public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Arisu Tachibana" <alicef@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.16 commit in: /
Date: Thu, 25 Sep 2025 12:02:17 +0000 (UTC)	[thread overview]
Message-ID: <1758801724.fb4386cb8d3a0e3944fcbd135b1a7c53cd28d3ad.alicef@gentoo> (raw)

commit:     fb4386cb8d3a0e3944fcbd135b1a7c53cd28d3ad
Author:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 25 12:02:04 2025 +0000
Commit:     Arisu Tachibana <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Sep 25 12:02:04 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=fb4386cb

Linux patch 6.16.9

Signed-off-by: Arisu Tachibana <alicef <AT> gentoo.org>

 0000_README             |    4 +
 1008_linux-6.16.9.patch | 6546 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 6550 insertions(+)

diff --git a/0000_README b/0000_README
index b72d6630..48b50ad0 100644
--- a/0000_README
+++ b/0000_README
@@ -75,6 +75,10 @@ Patch:  1007_linux-6.16.8.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.16.8
 
+Patch:  1008_linux-6.16.9.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.16.9
+
 Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.

diff --git a/1008_linux-6.16.9.patch b/1008_linux-6.16.9.patch
new file mode 100644
index 00000000..3a65fc5a
--- /dev/null
+++ b/1008_linux-6.16.9.patch
@@ -0,0 +1,6546 @@
+diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml
+index c6bc27709bf726..f59c0b37e8ebb2 100644
+--- a/Documentation/devicetree/bindings/serial/8250.yaml
++++ b/Documentation/devicetree/bindings/serial/8250.yaml
+@@ -48,6 +48,45 @@ allOf:
+       oneOf:
+         - required: [ clock-frequency ]
+         - required: [ clocks ]
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: nxp,lpc1850-uart
++    then:
++      properties:
++        clock-names:
++          items:
++            - const: uartclk
++            - const: reg
++    else:
++      properties:
++        clock-names:
++          items:
++            - const: core
++            - const: bus
++  - if:
++      properties:
++        compatible:
++          contains:
++            enum:
++              - spacemit,k1-uart
++              - nxp,lpc1850-uart
++    then:
++      required:
++        - clocks
++        - clock-names
++      properties:
++        clocks:
++          minItems: 2
++        clock-names:
++          minItems: 2
++    else:
++      properties:
++        clocks:
++          maxItems: 1
++        clock-names:
++          maxItems: 1
+ 
+ properties:
+   compatible:
+@@ -142,9 +181,22 @@ properties:
+ 
+   clock-names:
+     minItems: 1
+-    items:
+-      - const: core
+-      - const: bus
++    maxItems: 2
++    oneOf:
++      - items:
++          - const: core
++          - const: bus
++      - items:
++          - const: uartclk
++          - const: reg
++
++  dmas:
++    minItems: 1
++    maxItems: 4
++
++  dma-names:
++    minItems: 1
++    maxItems: 4
+ 
+   resets:
+     maxItems: 1
+@@ -233,25 +285,6 @@ required:
+   - reg
+   - interrupts
+ 
+-if:
+-  properties:
+-    compatible:
+-      contains:
+-        const: spacemit,k1-uart
+-then:
+-  required: [clock-names]
+-  properties:
+-    clocks:
+-      minItems: 2
+-    clock-names:
+-      minItems: 2
+-else:
+-  properties:
+-    clocks:
+-      maxItems: 1
+-    clock-names:
+-      maxItems: 1
+-
+ unevaluatedProperties: false
+ 
+ examples:
+diff --git a/Documentation/netlink/specs/conntrack.yaml b/Documentation/netlink/specs/conntrack.yaml
+index 840dc4504216bc..1865ddf01fb0f6 100644
+--- a/Documentation/netlink/specs/conntrack.yaml
++++ b/Documentation/netlink/specs/conntrack.yaml
+@@ -575,8 +575,8 @@ operations:
+             - nat-dst
+             - timeout
+             - mark
+-            - counter-orig
+-            - counter-reply
++            - counters-orig
++            - counters-reply
+             - use
+             - id
+             - nat-dst
+@@ -591,7 +591,6 @@ operations:
+         request:
+           value: 0x101
+           attributes:
+-            - nfgen-family
+             - mark
+             - filter
+             - status
+@@ -608,8 +607,8 @@ operations:
+             - nat-dst
+             - timeout
+             - mark
+-            - counter-orig
+-            - counter-reply
++            - counters-orig
++            - counters-reply
+             - use
+             - id
+             - nat-dst
+diff --git a/Documentation/netlink/specs/mptcp_pm.yaml b/Documentation/netlink/specs/mptcp_pm.yaml
+index ecfe5ee33de2d8..c77f32cfcae973 100644
+--- a/Documentation/netlink/specs/mptcp_pm.yaml
++++ b/Documentation/netlink/specs/mptcp_pm.yaml
+@@ -28,13 +28,13 @@ definitions:
+         traffic-patterns it can take a long time until the
+         MPTCP_EVENT_ESTABLISHED is sent.
+         Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6, sport,
+-        dport, server-side.
++        dport, server-side, [flags].
+      -
+       name: established
+       doc: >-
+         A MPTCP connection is established (can start new subflows).
+         Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6, sport,
+-        dport, server-side.
++        dport, server-side, [flags].
+      -
+       name: closed
+       doc: >-
+diff --git a/Makefile b/Makefile
+index 7594f35cbc2a5a..aef2cb6ea99d8b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 16
+-SUBLEVEL = 8
++SUBLEVEL = 9
+ EXTRAVERSION =
+ NAME = Baby Opossum Posse
+ 
+diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
+index 4b19f93379a153..eb13fcf095a1d4 100644
+--- a/arch/loongarch/Kconfig
++++ b/arch/loongarch/Kconfig
+@@ -301,6 +301,10 @@ config AS_HAS_LVZ_EXTENSION
+ config CC_HAS_ANNOTATE_TABLEJUMP
+ 	def_bool $(cc-option,-mannotate-tablejump)
+ 
++config RUSTC_HAS_ANNOTATE_TABLEJUMP
++	depends on RUST
++	def_bool $(rustc-option,-Cllvm-args=--loongarch-annotate-tablejump)
++
+ menu "Kernel type and options"
+ 
+ source "kernel/Kconfig.hz"
+@@ -566,10 +570,14 @@ config ARCH_STRICT_ALIGN
+ 	  -mstrict-align build parameter to prevent unaligned accesses.
+ 
+ 	  CPUs with h/w unaligned access support:
+-	  Loongson-2K2000/2K3000/3A5000/3C5000/3D5000.
++	  Loongson-2K2000/2K3000 and all of Loongson-3 series processors
++	  based on LoongArch.
+ 
+ 	  CPUs without h/w unaligned access support:
+-	  Loongson-2K500/2K1000.
++	  Loongson-2K0300/2K0500/2K1000.
++
++	  If you want to make sure whether to support unaligned memory access
++	  on your hardware, please read the bit 20 (UAL) of CPUCFG1 register.
+ 
+ 	  This option is enabled by default to make the kernel be able to run
+ 	  on all LoongArch systems. But you can disable it manually if you want
+diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
+index a3a9759414f40f..ae419e32f22e2f 100644
+--- a/arch/loongarch/Makefile
++++ b/arch/loongarch/Makefile
+@@ -102,16 +102,21 @@ KBUILD_CFLAGS			+= $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)
+ 
+ ifdef CONFIG_OBJTOOL
+ ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP
++KBUILD_CFLAGS			+= -mannotate-tablejump
++else
++KBUILD_CFLAGS			+= -fno-jump-tables # keep compatibility with older compilers
++endif
++ifdef CONFIG_RUSTC_HAS_ANNOTATE_TABLEJUMP
++KBUILD_RUSTFLAGS		+= -Cllvm-args=--loongarch-annotate-tablejump
++else
++KBUILD_RUSTFLAGS		+= -Zno-jump-tables # keep compatibility with older compilers
++endif
++ifdef CONFIG_LTO_CLANG
+ # The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled.
+ # Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to
+ # be passed via '-mllvm' to ld.lld.
+-KBUILD_CFLAGS			+= -mannotate-tablejump
+-ifdef CONFIG_LTO_CLANG
+ KBUILD_LDFLAGS			+= -mllvm --loongarch-annotate-tablejump
+ endif
+-else
+-KBUILD_CFLAGS			+= -fno-jump-tables # keep compatibility with older compilers
+-endif
+ endif
+ 
+ KBUILD_RUSTFLAGS		+= --target=loongarch64-unknown-none-softfloat -Ccode-model=small
+diff --git a/arch/loongarch/include/asm/acenv.h b/arch/loongarch/include/asm/acenv.h
+index 52f298f7293bab..483c955f2ae50d 100644
+--- a/arch/loongarch/include/asm/acenv.h
++++ b/arch/loongarch/include/asm/acenv.h
+@@ -10,9 +10,8 @@
+ #ifndef _ASM_LOONGARCH_ACENV_H
+ #define _ASM_LOONGARCH_ACENV_H
+ 
+-/*
+- * This header is required by ACPI core, but we have nothing to fill in
+- * right now. Will be updated later when needed.
+- */
++#ifdef CONFIG_ARCH_STRICT_ALIGN
++#define ACPI_MISALIGNMENT_NOT_SUPPORTED
++#endif /* CONFIG_ARCH_STRICT_ALIGN */
+ 
+ #endif /* _ASM_LOONGARCH_ACENV_H */
+diff --git a/arch/loongarch/include/asm/kvm_mmu.h b/arch/loongarch/include/asm/kvm_mmu.h
+index 099bafc6f797c9..e36cc7e8ed200a 100644
+--- a/arch/loongarch/include/asm/kvm_mmu.h
++++ b/arch/loongarch/include/asm/kvm_mmu.h
+@@ -16,6 +16,13 @@
+  */
+ #define KVM_MMU_CACHE_MIN_PAGES	(CONFIG_PGTABLE_LEVELS - 1)
+ 
++/*
++ * _PAGE_MODIFIED is a SW pte bit, it records page ever written on host
++ * kernel, on secondary MMU it records the page writeable attribute, in
++ * order for fast path handling.
++ */
++#define KVM_PAGE_WRITEABLE	_PAGE_MODIFIED
++
+ #define _KVM_FLUSH_PGTABLE	0x1
+ #define _KVM_HAS_PGMASK		0x2
+ #define kvm_pfn_pte(pfn, prot)	(((pfn) << PFN_PTE_SHIFT) | pgprot_val(prot))
+@@ -52,10 +59,10 @@ static inline void kvm_set_pte(kvm_pte_t *ptep, kvm_pte_t val)
+ 	WRITE_ONCE(*ptep, val);
+ }
+ 
+-static inline int kvm_pte_write(kvm_pte_t pte) { return pte & _PAGE_WRITE; }
+-static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & _PAGE_DIRTY; }
+ static inline int kvm_pte_young(kvm_pte_t pte) { return pte & _PAGE_ACCESSED; }
+ static inline int kvm_pte_huge(kvm_pte_t pte) { return pte & _PAGE_HUGE; }
++static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & __WRITEABLE; }
++static inline int kvm_pte_writeable(kvm_pte_t pte) { return pte & KVM_PAGE_WRITEABLE; }
+ 
+ static inline kvm_pte_t kvm_pte_mkyoung(kvm_pte_t pte)
+ {
+@@ -69,12 +76,12 @@ static inline kvm_pte_t kvm_pte_mkold(kvm_pte_t pte)
+ 
+ static inline kvm_pte_t kvm_pte_mkdirty(kvm_pte_t pte)
+ {
+-	return pte | _PAGE_DIRTY;
++	return pte | __WRITEABLE;
+ }
+ 
+ static inline kvm_pte_t kvm_pte_mkclean(kvm_pte_t pte)
+ {
+-	return pte & ~_PAGE_DIRTY;
++	return pte & ~__WRITEABLE;
+ }
+ 
+ static inline kvm_pte_t kvm_pte_mkhuge(kvm_pte_t pte)
+@@ -87,6 +94,11 @@ static inline kvm_pte_t kvm_pte_mksmall(kvm_pte_t pte)
+ 	return pte & ~_PAGE_HUGE;
+ }
+ 
++static inline kvm_pte_t kvm_pte_mkwriteable(kvm_pte_t pte)
++{
++	return pte | KVM_PAGE_WRITEABLE;
++}
++
+ static inline int kvm_need_flush(kvm_ptw_ctx *ctx)
+ {
+ 	return ctx->flag & _KVM_FLUSH_PGTABLE;
+diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
+index c0a5dc9aeae287..be309a71f20491 100644
+--- a/arch/loongarch/kernel/env.c
++++ b/arch/loongarch/kernel/env.c
+@@ -109,6 +109,8 @@ static int __init boardinfo_init(void)
+ 	struct kobject *loongson_kobj;
+ 
+ 	loongson_kobj = kobject_create_and_add("loongson", firmware_kobj);
++	if (!loongson_kobj)
++		return -ENOMEM;
+ 
+ 	return sysfs_create_file(loongson_kobj, &boardinfo_attr.attr);
+ }
+diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
+index 9a038d1070d73b..387dc4d3c4868f 100644
+--- a/arch/loongarch/kernel/stacktrace.c
++++ b/arch/loongarch/kernel/stacktrace.c
+@@ -51,12 +51,13 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
+ 	if (task == current) {
+ 		regs->regs[3] = (unsigned long)__builtin_frame_address(0);
+ 		regs->csr_era = (unsigned long)__builtin_return_address(0);
++		regs->regs[22] = 0;
+ 	} else {
+ 		regs->regs[3] = thread_saved_fp(task);
+ 		regs->csr_era = thread_saved_ra(task);
++		regs->regs[22] = task->thread.reg22;
+ 	}
+ 	regs->regs[1] = 0;
+-	regs->regs[22] = 0;
+ 
+ 	for (unwind_start(&state, task, regs);
+ 	     !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
+diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c
+index 7b888d9085a014..dee1a15d7f4c77 100644
+--- a/arch/loongarch/kernel/vdso.c
++++ b/arch/loongarch/kernel/vdso.c
+@@ -54,6 +54,9 @@ static int __init init_vdso(void)
+ 	vdso_info.code_mapping.pages =
+ 		kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL);
+ 
++	if (!vdso_info.code_mapping.pages)
++		return -ENOMEM;
++
+ 	pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso));
+ 	for (i = 0; i < vdso_info.size / PAGE_SIZE; i++)
+ 		vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i);
+diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
+index 0207cfe1dbd6c7..8e10393d276dc4 100644
+--- a/arch/loongarch/kvm/intc/eiointc.c
++++ b/arch/loongarch/kvm/intc/eiointc.c
+@@ -810,21 +810,26 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
+ 	struct loongarch_eiointc *s = dev->kvm->arch.eiointc;
+ 
+ 	data = (void __user *)attr->addr;
+-	spin_lock_irqsave(&s->lock, flags);
+ 	switch (type) {
+ 	case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
++	case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
+ 		if (copy_from_user(&val, data, 4))
+-			ret = -EFAULT;
+-		else {
+-			if (val >= EIOINTC_ROUTE_MAX_VCPUS)
+-				ret = -EINVAL;
+-			else
+-				s->num_cpu = val;
+-		}
++			return -EFAULT;
++		break;
++	default:
++		break;
++	}
++
++	spin_lock_irqsave(&s->lock, flags);
++	switch (type) {
++	case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
++		if (val >= EIOINTC_ROUTE_MAX_VCPUS)
++			ret = -EINVAL;
++		else
++			s->num_cpu = val;
+ 		break;
+ 	case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
+-		if (copy_from_user(&s->features, data, 4))
+-			ret = -EFAULT;
++		s->features = val;
+ 		if (!(s->features & BIT(EIOINTC_HAS_VIRT_EXTENSION)))
+ 			s->status |= BIT(EIOINTC_ENABLE);
+ 		break;
+@@ -846,19 +851,17 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
+ 
+ static int kvm_eiointc_regs_access(struct kvm_device *dev,
+ 					struct kvm_device_attr *attr,
+-					bool is_write)
++					bool is_write, int *data)
+ {
+ 	int addr, cpu, offset, ret = 0;
+ 	unsigned long flags;
+ 	void *p = NULL;
+-	void __user *data;
+ 	struct loongarch_eiointc *s;
+ 
+ 	s = dev->kvm->arch.eiointc;
+ 	addr = attr->attr;
+ 	cpu = addr >> 16;
+ 	addr &= 0xffff;
+-	data = (void __user *)attr->addr;
+ 	switch (addr) {
+ 	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
+ 		offset = (addr - EIOINTC_NODETYPE_START) / 4;
+@@ -897,13 +900,10 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
+ 	}
+ 
+ 	spin_lock_irqsave(&s->lock, flags);
+-	if (is_write) {
+-		if (copy_from_user(p, data, 4))
+-			ret = -EFAULT;
+-	} else {
+-		if (copy_to_user(data, p, 4))
+-			ret = -EFAULT;
+-	}
++	if (is_write)
++		memcpy(p, data, 4);
++	else
++		memcpy(data, p, 4);
+ 	spin_unlock_irqrestore(&s->lock, flags);
+ 
+ 	return ret;
+@@ -911,19 +911,17 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
+ 
+ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
+ 					struct kvm_device_attr *attr,
+-					bool is_write)
++					bool is_write, int *data)
+ {
+ 	int addr, ret = 0;
+ 	unsigned long flags;
+ 	void *p = NULL;
+-	void __user *data;
+ 	struct loongarch_eiointc *s;
+ 
+ 	s = dev->kvm->arch.eiointc;
+ 	addr = attr->attr;
+ 	addr &= 0xffff;
+ 
+-	data = (void __user *)attr->addr;
+ 	switch (addr) {
+ 	case KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU:
+ 		if (is_write)
+@@ -945,13 +943,10 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
+ 		return -EINVAL;
+ 	}
+ 	spin_lock_irqsave(&s->lock, flags);
+-	if (is_write) {
+-		if (copy_from_user(p, data, 4))
+-			ret = -EFAULT;
+-	} else {
+-		if (copy_to_user(data, p, 4))
+-			ret = -EFAULT;
+-	}
++	if (is_write)
++		memcpy(p, data, 4);
++	else
++		memcpy(data, p, 4);
+ 	spin_unlock_irqrestore(&s->lock, flags);
+ 
+ 	return ret;
+@@ -960,11 +955,27 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
+ static int kvm_eiointc_get_attr(struct kvm_device *dev,
+ 				struct kvm_device_attr *attr)
+ {
++	int ret, data;
++
+ 	switch (attr->group) {
+ 	case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
+-		return kvm_eiointc_regs_access(dev, attr, false);
++		ret = kvm_eiointc_regs_access(dev, attr, false, &data);
++		if (ret)
++			return ret;
++
++		if (copy_to_user((void __user *)attr->addr, &data, 4))
++			ret = -EFAULT;
++
++		return ret;
+ 	case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
+-		return kvm_eiointc_sw_status_access(dev, attr, false);
++		ret = kvm_eiointc_sw_status_access(dev, attr, false, &data);
++		if (ret)
++			return ret;
++
++		if (copy_to_user((void __user *)attr->addr, &data, 4))
++			ret = -EFAULT;
++
++		return ret;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -973,13 +984,21 @@ static int kvm_eiointc_get_attr(struct kvm_device *dev,
+ static int kvm_eiointc_set_attr(struct kvm_device *dev,
+ 				struct kvm_device_attr *attr)
+ {
++	int data;
++
+ 	switch (attr->group) {
+ 	case KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL:
+ 		return kvm_eiointc_ctrl_access(dev, attr);
+ 	case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
+-		return kvm_eiointc_regs_access(dev, attr, true);
++		if (copy_from_user(&data, (void __user *)attr->addr, 4))
++			return -EFAULT;
++
++		return kvm_eiointc_regs_access(dev, attr, true, &data);
+ 	case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
+-		return kvm_eiointc_sw_status_access(dev, attr, true);
++		if (copy_from_user(&data, (void __user *)attr->addr, 4))
++			return -EFAULT;
++
++		return kvm_eiointc_sw_status_access(dev, attr, true, &data);
+ 	default:
+ 		return -EINVAL;
+ 	}
+diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
+index ef5044796b7a6e..52f19dcf6b8814 100644
+--- a/arch/loongarch/kvm/intc/pch_pic.c
++++ b/arch/loongarch/kvm/intc/pch_pic.c
+@@ -348,6 +348,7 @@ static int kvm_pch_pic_regs_access(struct kvm_device *dev,
+ 				struct kvm_device_attr *attr,
+ 				bool is_write)
+ {
++	char buf[8];
+ 	int addr, offset, len = 8, ret = 0;
+ 	void __user *data;
+ 	void *p = NULL;
+@@ -397,17 +398,23 @@ static int kvm_pch_pic_regs_access(struct kvm_device *dev,
+ 		return -EINVAL;
+ 	}
+ 
+-	spin_lock(&s->lock);
+-	/* write or read value according to is_write */
+ 	if (is_write) {
+-		if (copy_from_user(p, data, len))
+-			ret = -EFAULT;
+-	} else {
+-		if (copy_to_user(data, p, len))
+-			ret = -EFAULT;
++		if (copy_from_user(buf, data, len))
++			return -EFAULT;
+ 	}
++
++	spin_lock(&s->lock);
++	if (is_write)
++		memcpy(p, buf, len);
++	else
++		memcpy(buf, p, len);
+ 	spin_unlock(&s->lock);
+ 
++	if (!is_write) {
++		if (copy_to_user(data, buf, len))
++			return -EFAULT;
++	}
++
+ 	return ret;
+ }
+ 
+diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c
+index ed956c5cf2cc04..7c8143e79c1279 100644
+--- a/arch/loongarch/kvm/mmu.c
++++ b/arch/loongarch/kvm/mmu.c
+@@ -569,7 +569,7 @@ static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool writ
+ 	/* Track access to pages marked old */
+ 	new = kvm_pte_mkyoung(*ptep);
+ 	if (write && !kvm_pte_dirty(new)) {
+-		if (!kvm_pte_write(new)) {
++		if (!kvm_pte_writeable(new)) {
+ 			ret = -EFAULT;
+ 			goto out;
+ 		}
+@@ -856,9 +856,9 @@ static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
+ 		prot_bits |= _CACHE_SUC;
+ 
+ 	if (writeable) {
+-		prot_bits |= _PAGE_WRITE;
++		prot_bits = kvm_pte_mkwriteable(prot_bits);
+ 		if (write)
+-			prot_bits |= __WRITEABLE;
++			prot_bits = kvm_pte_mkdirty(prot_bits);
+ 	}
+ 
+ 	/* Disable dirty logging on HugePages */
+@@ -904,7 +904,7 @@ static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
+ 	kvm_release_faultin_page(kvm, page, false, writeable);
+ 	spin_unlock(&kvm->mmu_lock);
+ 
+-	if (prot_bits & _PAGE_DIRTY)
++	if (kvm_pte_dirty(prot_bits))
+ 		mark_page_dirty_in_slot(kvm, memslot, gfn);
+ 
+ out:
+diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h
+index e5f57cfe1d4582..025c6dcbf89331 100644
+--- a/arch/s390/include/asm/pci_insn.h
++++ b/arch/s390/include/asm/pci_insn.h
+@@ -16,11 +16,11 @@
+ #define ZPCI_PCI_ST_FUNC_NOT_AVAIL		40
+ #define ZPCI_PCI_ST_ALREADY_IN_RQ_STATE		44
+ 
+-/* Load/Store return codes */
+-#define ZPCI_PCI_LS_OK				0
+-#define ZPCI_PCI_LS_ERR				1
+-#define ZPCI_PCI_LS_BUSY			2
+-#define ZPCI_PCI_LS_INVAL_HANDLE		3
++/* PCI instruction condition codes */
++#define ZPCI_CC_OK				0
++#define ZPCI_CC_ERR				1
++#define ZPCI_CC_BUSY				2
++#define ZPCI_CC_INVAL_HANDLE			3
+ 
+ /* Load/Store address space identifiers */
+ #define ZPCI_PCIAS_MEMIO_0			0
+diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
+index ad8d78fb1d9aaf..de7867ae220d0c 100644
+--- a/arch/um/drivers/virtio_uml.c
++++ b/arch/um/drivers/virtio_uml.c
+@@ -1250,10 +1250,12 @@ static int virtio_uml_probe(struct platform_device *pdev)
+ 	device_set_wakeup_capable(&vu_dev->vdev.dev, true);
+ 
+ 	rc = register_virtio_device(&vu_dev->vdev);
+-	if (rc)
++	if (rc) {
+ 		put_device(&vu_dev->vdev.dev);
++		return rc;
++	}
+ 	vu_dev->registered = 1;
+-	return rc;
++	return 0;
+ 
+ error_init:
+ 	os_close_file(vu_dev->sock);
+diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
+index 617886d1fb1e91..21f0e50fb1df95 100644
+--- a/arch/um/os-Linux/file.c
++++ b/arch/um/os-Linux/file.c
+@@ -535,7 +535,7 @@ ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
+ 	    cmsg->cmsg_type != SCM_RIGHTS)
+ 		return n;
+ 
+-	memcpy(fds, CMSG_DATA(cmsg), cmsg->cmsg_len);
++	memcpy(fds, CMSG_DATA(cmsg), cmsg->cmsg_len - CMSG_LEN(0));
+ 	return n;
+ }
+ 
+diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
+index 14d7e0719dd5ee..8d0dfd20ac2823 100644
+--- a/arch/x86/include/asm/sev.h
++++ b/arch/x86/include/asm/sev.h
+@@ -564,6 +564,24 @@ enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+ 
+ extern struct ghcb *boot_ghcb;
+ 
++static inline void sev_evict_cache(void *va, int npages)
++{
++	volatile u8 val __always_unused;
++	u8 *bytes = va;
++	int page_idx;
++
++	/*
++	 * For SEV guests, a read from the first/last cache-lines of a 4K page
++	 * using the guest key is sufficient to cause a flush of all cache-lines
++	 * associated with that 4K page without incurring all the overhead of a
++	 * full CLFLUSH sequence.
++	 */
++	for (page_idx = 0; page_idx < npages; page_idx++) {
++		val = bytes[page_idx * PAGE_SIZE];
++		val = bytes[page_idx * PAGE_SIZE + PAGE_SIZE - 1];
++	}
++}
++
+ #else	/* !CONFIG_AMD_MEM_ENCRYPT */
+ 
+ #define snp_vmpl 0
+@@ -607,6 +625,7 @@ static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_
+ static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
+ static inline void __init snp_secure_tsc_prepare(void) { }
+ static inline void __init snp_secure_tsc_init(void) { }
++static inline void sev_evict_cache(void *va, int npages) {}
+ 
+ #endif	/* CONFIG_AMD_MEM_ENCRYPT */
+ 
+@@ -621,24 +640,6 @@ int rmp_make_shared(u64 pfn, enum pg_level level);
+ void snp_leak_pages(u64 pfn, unsigned int npages);
+ void kdump_sev_callback(void);
+ void snp_fixup_e820_tables(void);
+-
+-static inline void sev_evict_cache(void *va, int npages)
+-{
+-	volatile u8 val __always_unused;
+-	u8 *bytes = va;
+-	int page_idx;
+-
+-	/*
+-	 * For SEV guests, a read from the first/last cache-lines of a 4K page
+-	 * using the guest key is sufficient to cause a flush of all cache-lines
+-	 * associated with that 4K page without incurring all the overhead of a
+-	 * full CLFLUSH sequence.
+-	 */
+-	for (page_idx = 0; page_idx < npages; page_idx++) {
+-		val = bytes[page_idx * PAGE_SIZE];
+-		val = bytes[page_idx * PAGE_SIZE + PAGE_SIZE - 1];
+-	}
+-}
+ #else
+ static inline bool snp_probe_rmptable_info(void) { return false; }
+ static inline int snp_rmptable_init(void) { return -ENOSYS; }
+@@ -654,7 +655,6 @@ static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV
+ static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
+ static inline void kdump_sev_callback(void) { }
+ static inline void snp_fixup_e820_tables(void) {}
+-static inline void sev_evict_cache(void *va, int npages) {}
+ #endif
+ 
+ #endif
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index be8c43049f4d39..268d62fa28b824 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -4204,8 +4204,7 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+ 	u64 cr8;
+ 
+-	if (nested_svm_virtualize_tpr(vcpu) ||
+-	    kvm_vcpu_apicv_active(vcpu))
++	if (nested_svm_virtualize_tpr(vcpu))
+ 		return;
+ 
+ 	cr8 = kvm_get_cr8(vcpu);
+diff --git a/crypto/af_alg.c b/crypto/af_alg.c
+index 0da7c1ac778a0e..ca6fdcc6c54aca 100644
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -970,6 +970,12 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
+ 	}
+ 
+ 	lock_sock(sk);
++	if (ctx->write) {
++		release_sock(sk);
++		return -EBUSY;
++	}
++	ctx->write = true;
++
+ 	if (ctx->init && !ctx->more) {
+ 		if (ctx->used) {
+ 			err = -EINVAL;
+@@ -1019,6 +1025,8 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
+ 			continue;
+ 		}
+ 
++		ctx->merge = 0;
++
+ 		if (!af_alg_writable(sk)) {
+ 			err = af_alg_wait_for_wmem(sk, msg->msg_flags);
+ 			if (err)
+@@ -1058,7 +1066,6 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
+ 			ctx->used += plen;
+ 			copied += plen;
+ 			size -= plen;
+-			ctx->merge = 0;
+ 		} else {
+ 			do {
+ 				struct page *pg;
+@@ -1104,6 +1111,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
+ 
+ unlock:
+ 	af_alg_data_wakeup(sk);
++	ctx->write = false;
+ 	release_sock(sk);
+ 
+ 	return copied ?: err;
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index 54c57103715f9b..0f7bcc86b6f724 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1794,6 +1794,7 @@ static int write_same_filled_page(struct zram *zram, unsigned long fill,
+ 				  u32 index)
+ {
+ 	zram_slot_lock(zram, index);
++	zram_free_page(zram, index);
+ 	zram_set_flag(zram, index, ZRAM_SAME);
+ 	zram_set_handle(zram, index, fill);
+ 	zram_slot_unlock(zram, index);
+@@ -1831,6 +1832,7 @@ static int write_incompressible_page(struct zram *zram, struct page *page,
+ 	kunmap_local(src);
+ 
+ 	zram_slot_lock(zram, index);
++	zram_free_page(zram, index);
+ 	zram_set_flag(zram, index, ZRAM_HUGE);
+ 	zram_set_handle(zram, index, handle);
+ 	zram_set_obj_size(zram, index, PAGE_SIZE);
+@@ -1854,11 +1856,6 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
+ 	unsigned long element;
+ 	bool same_filled;
+ 
+-	/* First, free memory allocated to this slot (if any) */
+-	zram_slot_lock(zram, index);
+-	zram_free_page(zram, index);
+-	zram_slot_unlock(zram, index);
+-
+ 	mem = kmap_local_page(page);
+ 	same_filled = page_same_filled(mem, &element);
+ 	kunmap_local(mem);
+@@ -1900,6 +1897,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
+ 	zcomp_stream_put(zstrm);
+ 
+ 	zram_slot_lock(zram, index);
++	zram_free_page(zram, index);
+ 	zram_set_handle(zram, index, handle);
+ 	zram_set_obj_size(zram, index, comp_len);
+ 	zram_slot_unlock(zram, index);
+diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
+index 354c981943b6f8..4221b1888b38da 100644
+--- a/drivers/clk/sunxi-ng/ccu_mp.c
++++ b/drivers/clk/sunxi-ng/ccu_mp.c
+@@ -185,7 +185,7 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
+ 	p &= (1 << cmp->p.width) - 1;
+ 
+ 	if (cmp->common.features & CCU_FEATURE_DUAL_DIV)
+-		rate = (parent_rate / p) / m;
++		rate = (parent_rate / (p + cmp->p.offset)) / m;
+ 	else
+ 		rate = (parent_rate >> p) / m;
+ 
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index e058ba02779296..9f5ccc1720cbc1 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -2430,7 +2430,7 @@ static void __sev_firmware_shutdown(struct sev_device *sev, bool panic)
+ {
+ 	int error;
+ 
+-	__sev_platform_shutdown_locked(NULL);
++	__sev_platform_shutdown_locked(&error);
+ 
+ 	if (sev_es_tmr) {
+ 		/*
+diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
+index c130f87147fa3f..815de752bcd384 100644
+--- a/drivers/dpll/dpll_netlink.c
++++ b/drivers/dpll/dpll_netlink.c
+@@ -173,8 +173,8 @@ static int
+ dpll_msg_add_clock_quality_level(struct sk_buff *msg, struct dpll_device *dpll,
+ 				 struct netlink_ext_ack *extack)
+ {
++	DECLARE_BITMAP(qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1) = { 0 };
+ 	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
+-	DECLARE_BITMAP(qls, DPLL_CLOCK_QUALITY_LEVEL_MAX) = { 0 };
+ 	enum dpll_clock_quality_level ql;
+ 	int ret;
+ 
+@@ -183,7 +183,7 @@ dpll_msg_add_clock_quality_level(struct sk_buff *msg, struct dpll_device *dpll,
+ 	ret = ops->clock_quality_level_get(dpll, dpll_priv(dpll), qls, extack);
+ 	if (ret)
+ 		return ret;
+-	for_each_set_bit(ql, qls, DPLL_CLOCK_QUALITY_LEVEL_MAX)
++	for_each_set_bit(ql, qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1)
+ 		if (nla_put_u32(msg, DPLL_A_CLOCK_QUALITY_LEVEL, ql))
+ 			return -EMSGSIZE;
+ 
+diff --git a/drivers/gpio/gpiolib-acpi-core.c b/drivers/gpio/gpiolib-acpi-core.c
+index 12b24a717e43f1..d11bcaf1ae8842 100644
+--- a/drivers/gpio/gpiolib-acpi-core.c
++++ b/drivers/gpio/gpiolib-acpi-core.c
+@@ -942,7 +942,7 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
+ {
+ 	struct acpi_device *adev = to_acpi_device_node(fwnode);
+ 	bool can_fallback = acpi_can_fallback_to_crs(adev, con_id);
+-	struct acpi_gpio_info info;
++	struct acpi_gpio_info info = {};
+ 	struct gpio_desc *desc;
+ 
+ 	desc = __acpi_find_gpio(fwnode, con_id, idx, can_fallback, &info);
+@@ -992,7 +992,7 @@ int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *con_id,
+ 	int ret;
+ 
+ 	for (i = 0, idx = 0; idx <= index; i++) {
+-		struct acpi_gpio_info info;
++		struct acpi_gpio_info info = {};
+ 		struct gpio_desc *desc;
+ 
+ 		/* Ignore -EPROBE_DEFER, it only matters if idx matches */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+index fe282b85573414..31010040a12f04 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -250,16 +250,24 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
+ 
+ void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool suspend_proc)
+ {
+-	if (adev->kfd.dev)
+-		kgd2kfd_suspend(adev->kfd.dev, suspend_proc);
++	if (adev->kfd.dev) {
++		if (adev->in_s0ix)
++			kgd2kfd_stop_sched_all_nodes(adev->kfd.dev);
++		else
++			kgd2kfd_suspend(adev->kfd.dev, suspend_proc);
++	}
+ }
+ 
+ int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool resume_proc)
+ {
+ 	int r = 0;
+ 
+-	if (adev->kfd.dev)
+-		r = kgd2kfd_resume(adev->kfd.dev, resume_proc);
++	if (adev->kfd.dev) {
++		if (adev->in_s0ix)
++			r = kgd2kfd_start_sched_all_nodes(adev->kfd.dev);
++		else
++			r = kgd2kfd_resume(adev->kfd.dev, resume_proc);
++	}
+ 
+ 	return r;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+index b7c3ec48340721..861697490ac2e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+@@ -426,7 +426,9 @@ void kgd2kfd_smi_event_throttle(struct kfd_dev *kfd, uint64_t throttle_bitmask);
+ int kgd2kfd_check_and_lock_kfd(void);
+ void kgd2kfd_unlock_kfd(void);
+ int kgd2kfd_start_sched(struct kfd_dev *kfd, uint32_t node_id);
++int kgd2kfd_start_sched_all_nodes(struct kfd_dev *kfd);
+ int kgd2kfd_stop_sched(struct kfd_dev *kfd, uint32_t node_id);
++int kgd2kfd_stop_sched_all_nodes(struct kfd_dev *kfd);
+ bool kgd2kfd_compute_active(struct kfd_dev *kfd, uint32_t node_id);
+ bool kgd2kfd_vmfault_fast_path(struct amdgpu_device *adev, struct amdgpu_iv_entry *entry,
+ 			       bool retry_fault);
+@@ -516,11 +518,21 @@ static inline int kgd2kfd_start_sched(struct kfd_dev *kfd, uint32_t node_id)
+ 	return 0;
+ }
+ 
++static inline int kgd2kfd_start_sched_all_nodes(struct kfd_dev *kfd)
++{
++	return 0;
++}
++
+ static inline int kgd2kfd_stop_sched(struct kfd_dev *kfd, uint32_t node_id)
+ {
+ 	return 0;
+ }
+ 
++static inline int kgd2kfd_stop_sched_all_nodes(struct kfd_dev *kfd)
++{
++	return 0;
++}
++
+ static inline bool kgd2kfd_compute_active(struct kfd_dev *kfd, uint32_t node_id)
+ {
+ 	return false;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index a57e8c5474bb00..a65591f70b15d8 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -5055,7 +5055,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
+ 	adev->in_suspend = true;
+ 
+ 	if (amdgpu_sriov_vf(adev)) {
+-		if (!adev->in_s0ix && !adev->in_runpm)
++		if (!adev->in_runpm)
+ 			amdgpu_amdkfd_suspend_process(adev);
+ 		amdgpu_virt_fini_data_exchange(adev);
+ 		r = amdgpu_virt_request_full_gpu(adev, false);
+@@ -5075,10 +5075,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
+ 
+ 	amdgpu_device_ip_suspend_phase1(adev);
+ 
+-	if (!adev->in_s0ix) {
+-		amdgpu_amdkfd_suspend(adev, !amdgpu_sriov_vf(adev) && !adev->in_runpm);
+-		amdgpu_userq_suspend(adev);
+-	}
++	amdgpu_amdkfd_suspend(adev, !amdgpu_sriov_vf(adev) && !adev->in_runpm);
++	amdgpu_userq_suspend(adev);
+ 
+ 	r = amdgpu_device_evict_resources(adev);
+ 	if (r)
+@@ -5141,15 +5139,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
+ 		goto exit;
+ 	}
+ 
+-	if (!adev->in_s0ix) {
+-		r = amdgpu_amdkfd_resume(adev, !amdgpu_sriov_vf(adev) && !adev->in_runpm);
+-		if (r)
+-			goto exit;
++	r = amdgpu_amdkfd_resume(adev, !amdgpu_sriov_vf(adev) && !adev->in_runpm);
++	if (r)
++		goto exit;
+ 
+-		r = amdgpu_userq_resume(adev);
+-		if (r)
+-			goto exit;
+-	}
++	r = amdgpu_userq_resume(adev);
++	if (r)
++		goto exit;
+ 
+ 	r = amdgpu_device_ip_late_init(adev);
+ 	if (r)
+@@ -5162,7 +5158,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
+ 		amdgpu_virt_init_data_exchange(adev);
+ 		amdgpu_virt_release_full_gpu(adev, true);
+ 
+-		if (!adev->in_s0ix && !r && !adev->in_runpm)
++		if (!r && !adev->in_runpm)
+ 			r = amdgpu_amdkfd_resume_process(adev);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+index 097bf675378273..f512879cb71c65 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+@@ -1501,6 +1501,25 @@ int kgd2kfd_start_sched(struct kfd_dev *kfd, uint32_t node_id)
+ 	return ret;
+ }
+ 
++int kgd2kfd_start_sched_all_nodes(struct kfd_dev *kfd)
++{
++	struct kfd_node *node;
++	int i, r;
++
++	if (!kfd->init_complete)
++		return 0;
++
++	for (i = 0; i < kfd->num_nodes; i++) {
++		node = kfd->nodes[i];
++		r = node->dqm->ops.unhalt(node->dqm);
++		if (r) {
++			dev_err(kfd_device, "Error in starting scheduler\n");
++			return r;
++		}
++	}
++	return 0;
++}
++
+ int kgd2kfd_stop_sched(struct kfd_dev *kfd, uint32_t node_id)
+ {
+ 	struct kfd_node *node;
+@@ -1518,6 +1537,23 @@ int kgd2kfd_stop_sched(struct kfd_dev *kfd, uint32_t node_id)
+ 	return node->dqm->ops.halt(node->dqm);
+ }
+ 
++int kgd2kfd_stop_sched_all_nodes(struct kfd_dev *kfd)
++{
++	struct kfd_node *node;
++	int i, r;
++
++	if (!kfd->init_complete)
++		return 0;
++
++	for (i = 0; i < kfd->num_nodes; i++) {
++		node = kfd->nodes[i];
++		r = node->dqm->ops.halt(node->dqm);
++		if (r)
++			return r;
++	}
++	return 0;
++}
++
+ bool kgd2kfd_compute_active(struct kfd_dev *kfd, uint32_t node_id)
+ {
+ 	struct kfd_node *node;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 312f6075e39d11..58ea351dd48b5d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -8689,7 +8689,16 @@ static int amdgpu_dm_encoder_init(struct drm_device *dev,
+ static void manage_dm_interrupts(struct amdgpu_device *adev,
+ 				 struct amdgpu_crtc *acrtc,
+ 				 struct dm_crtc_state *acrtc_state)
+-{
++{	/*
++	 * We cannot be sure that the frontend index maps to the same
++	 * backend index - some even map to more than one.
++	 * So we have to go through the CRTC to find the right IRQ.
++	 */
++	int irq_type = amdgpu_display_crtc_idx_to_irq_type(
++			adev,
++			acrtc->crtc_id);
++	struct drm_device *dev = adev_to_drm(adev);
++
+ 	struct drm_vblank_crtc_config config = {0};
+ 	struct dc_crtc_timing *timing;
+ 	int offdelay;
+@@ -8742,7 +8751,35 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
+ 
+ 		drm_crtc_vblank_on_config(&acrtc->base,
+ 					  &config);
++		/* Allow RX6xxx, RX7700, RX7800 GPUs to call amdgpu_irq_get.*/
++		switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
++		case IP_VERSION(3, 0, 0):
++		case IP_VERSION(3, 0, 2):
++		case IP_VERSION(3, 0, 3):
++		case IP_VERSION(3, 2, 0):
++			if (amdgpu_irq_get(adev, &adev->pageflip_irq, irq_type))
++				drm_err(dev, "DM_IRQ: Cannot get pageflip irq!\n");
++#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
++			if (amdgpu_irq_get(adev, &adev->vline0_irq, irq_type))
++				drm_err(dev, "DM_IRQ: Cannot get vline0 irq!\n");
++#endif
++		}
++
+ 	} else {
++		/* Allow RX6xxx, RX7700, RX7800 GPUs to call amdgpu_irq_put.*/
++		switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
++		case IP_VERSION(3, 0, 0):
++		case IP_VERSION(3, 0, 2):
++		case IP_VERSION(3, 0, 3):
++		case IP_VERSION(3, 2, 0):
++#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
++			if (amdgpu_irq_put(adev, &adev->vline0_irq, irq_type))
++				drm_err(dev, "DM_IRQ: Cannot put vline0 irq!\n");
++#endif
++			if (amdgpu_irq_put(adev, &adev->pageflip_irq, irq_type))
++				drm_err(dev, "DM_IRQ: Cannot put pageflip irq!\n");
++		}
++
+ 		drm_crtc_vblank_off(&acrtc->base);
+ 	}
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index 26b8e232f85825..2278a123db23f9 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -2185,7 +2185,7 @@ static int smu_resume(struct amdgpu_ip_block *ip_block)
+ 			return ret;
+ 	}
+ 
+-	if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
++	if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL && smu->od_enabled) {
+ 		ret = smu_od_edit_dpm_table(smu, PP_OD_COMMIT_DPM_TABLE, NULL, 0);
+ 		if (ret)
+ 			return ret;
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 8a9079c2ed5c22..8257132a8ee9d2 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -2678,7 +2678,7 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+ 		ret = devm_request_threaded_irq(dev, platform->pdata.intp_irq,
+ 						NULL, anx7625_intr_hpd_isr,
+ 						IRQF_TRIGGER_FALLING |
+-						IRQF_ONESHOT,
++						IRQF_ONESHOT | IRQF_NO_AUTOEN,
+ 						"anx7625-intp", platform);
+ 		if (ret) {
+ 			DRM_DEV_ERROR(dev, "fail to request irq\n");
+@@ -2747,8 +2747,10 @@ static int anx7625_i2c_probe(struct i2c_client *client)
+ 	}
+ 
+ 	/* Add work function */
+-	if (platform->pdata.intp_irq)
++	if (platform->pdata.intp_irq) {
++		enable_irq(platform->pdata.intp_irq);
+ 		queue_work(platform->workqueue, &platform->work);
++	}
+ 
+ 	if (platform->pdata.audio_en)
+ 		anx7625_register_audio(dev, platform);
+diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+index b431e7efd1f0d7..dbef0ca1a22a38 100644
+--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+@@ -1984,8 +1984,10 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
+ 	mhdp_state = to_cdns_mhdp_bridge_state(new_state);
+ 
+ 	mhdp_state->current_mode = drm_mode_duplicate(bridge->dev, mode);
+-	if (!mhdp_state->current_mode)
+-		return;
++	if (!mhdp_state->current_mode) {
++		ret = -EINVAL;
++		goto out;
++	}
+ 
+ 	drm_mode_set_name(mhdp_state->current_mode);
+ 
+diff --git a/drivers/gpu/drm/xe/abi/guc_actions_abi.h b/drivers/gpu/drm/xe/abi/guc_actions_abi.h
+index 448afb86e05c7d..4d9896e14649c0 100644
+--- a/drivers/gpu/drm/xe/abi/guc_actions_abi.h
++++ b/drivers/gpu/drm/xe/abi/guc_actions_abi.h
+@@ -117,6 +117,7 @@ enum xe_guc_action {
+ 	XE_GUC_ACTION_ENTER_S_STATE = 0x501,
+ 	XE_GUC_ACTION_EXIT_S_STATE = 0x502,
+ 	XE_GUC_ACTION_GLOBAL_SCHED_POLICY_CHANGE = 0x506,
++	XE_GUC_ACTION_UPDATE_SCHEDULING_POLICIES_KLV = 0x509,
+ 	XE_GUC_ACTION_SCHED_CONTEXT = 0x1000,
+ 	XE_GUC_ACTION_SCHED_CONTEXT_MODE_SET = 0x1001,
+ 	XE_GUC_ACTION_SCHED_CONTEXT_MODE_DONE = 0x1002,
+@@ -142,6 +143,7 @@ enum xe_guc_action {
+ 	XE_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
+ 	XE_GUC_ACTION_SET_DEVICE_ENGINE_ACTIVITY_BUFFER = 0x550C,
+ 	XE_GUC_ACTION_SET_FUNCTION_ENGINE_ACTIVITY_BUFFER = 0x550D,
++	XE_GUC_ACTION_OPT_IN_FEATURE_KLV = 0x550E,
+ 	XE_GUC_ACTION_NOTIFY_MEMORY_CAT_ERROR = 0x6000,
+ 	XE_GUC_ACTION_REPORT_PAGE_FAULT_REQ_DESC = 0x6002,
+ 	XE_GUC_ACTION_PAGE_FAULT_RES_DESC = 0x6003,
+@@ -240,4 +242,7 @@ enum xe_guc_g2g_type {
+ #define XE_G2G_DEREGISTER_TILE	REG_GENMASK(15, 12)
+ #define XE_G2G_DEREGISTER_TYPE	REG_GENMASK(11, 8)
+ 
++/* invalid type for XE_GUC_ACTION_NOTIFY_MEMORY_CAT_ERROR */
++#define XE_GUC_CAT_ERR_TYPE_INVALID 0xdeadbeef
++
+ #endif
+diff --git a/drivers/gpu/drm/xe/abi/guc_klvs_abi.h b/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
+index 7de8f827281fcd..89034bc97ec5a4 100644
+--- a/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
++++ b/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
+@@ -16,6 +16,8 @@
+  *  +===+=======+==============================================================+
+  *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
+  *  |   |       |   - `GuC Self Config KLVs`_                                  |
++ *  |   |       |   - `GuC Opt In Feature KLVs`_                               |
++ *  |   |       |   - `GuC Scheduling Policies KLVs`_                          |
+  *  |   |       |   - `GuC VGT Policy KLVs`_                                   |
+  *  |   |       |   - `GuC VF Configuration KLVs`_                             |
+  *  |   |       |                                                              |
+@@ -124,6 +126,44 @@ enum  {
+ 	GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
+ };
+ 
++/**
++ * DOC: GuC Opt In Feature KLVs
++ *
++ * `GuC KLV`_ keys available for use with OPT_IN_FEATURE_KLV
++ *
++ *  _`GUC_KLV_OPT_IN_FEATURE_EXT_CAT_ERR_TYPE` : 0x4001
++ *      Adds an extra dword to the XE_GUC_ACTION_NOTIFY_MEMORY_CAT_ERROR G2H
++ *      containing the type of the CAT error. On HW that does not support
++ *      reporting the CAT error type, the extra dword is set to 0xdeadbeef.
++ */
++
++#define GUC_KLV_OPT_IN_FEATURE_EXT_CAT_ERR_TYPE_KEY 0x4001
++#define GUC_KLV_OPT_IN_FEATURE_EXT_CAT_ERR_TYPE_LEN 0u
++
++/**
++ * DOC: GuC Scheduling Policies KLVs
++ *
++ * `GuC KLV`_ keys available for use with UPDATE_SCHEDULING_POLICIES_KLV.
++ *
++ * _`GUC_KLV_SCHEDULING_POLICIES_RENDER_COMPUTE_YIELD` : 0x1001
++ *      Some platforms do not allow concurrent execution of RCS and CCS
++ *      workloads from different address spaces. By default, the GuC prioritizes
++ *      RCS submissions over CCS ones, which can lead to CCS workloads being
++ *      significantly (or completely) starved of execution time. This KLV allows
++ *      the driver to specify a quantum (in ms) and a ratio (percentage value
++ *      between 0 and 100), and the GuC will prioritize the CCS for that
++ *      percentage of each quantum. For example, specifying 100ms and 30% will
++ *      make the GuC prioritize the CCS for 30ms of every 100ms.
++ *      Note that this does not necessarly mean that RCS and CCS engines will
++ *      only be active for their percentage of the quantum, as the restriction
++ *      only kicks in if both classes are fully busy with non-compatible address
++ *      spaces; i.e., if one engine is idle or running the same address space,
++ *      a pending job on the other engine will still be submitted to the HW no
++ *      matter what the ratio is
++ */
++#define GUC_KLV_SCHEDULING_POLICIES_RENDER_COMPUTE_YIELD_KEY	0x1001
++#define GUC_KLV_SCHEDULING_POLICIES_RENDER_COMPUTE_YIELD_LEN	2u
++
+ /**
+  * DOC: GuC VGT Policy KLVs
+  *
+diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
+index fee22358cc09be..e5116975961461 100644
+--- a/drivers/gpu/drm/xe/xe_exec_queue.c
++++ b/drivers/gpu/drm/xe/xe_exec_queue.c
+@@ -151,6 +151,16 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q)
+ 	return err;
+ }
+ 
++static void __xe_exec_queue_fini(struct xe_exec_queue *q)
++{
++	int i;
++
++	q->ops->fini(q);
++
++	for (i = 0; i < q->width; ++i)
++		xe_lrc_put(q->lrc[i]);
++}
++
+ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *vm,
+ 					   u32 logical_mask, u16 width,
+ 					   struct xe_hw_engine *hwe, u32 flags,
+@@ -181,11 +191,13 @@ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *v
+ 	if (xe_exec_queue_uses_pxp(q)) {
+ 		err = xe_pxp_exec_queue_add(xe->pxp, q);
+ 		if (err)
+-			goto err_post_alloc;
++			goto err_post_init;
+ 	}
+ 
+ 	return q;
+ 
++err_post_init:
++	__xe_exec_queue_fini(q);
+ err_post_alloc:
+ 	__xe_exec_queue_free(q);
+ 	return ERR_PTR(err);
+@@ -283,13 +295,11 @@ void xe_exec_queue_destroy(struct kref *ref)
+ 			xe_exec_queue_put(eq);
+ 	}
+ 
+-	q->ops->fini(q);
++	q->ops->destroy(q);
+ }
+ 
+ void xe_exec_queue_fini(struct xe_exec_queue *q)
+ {
+-	int i;
+-
+ 	/*
+ 	 * Before releasing our ref to lrc and xef, accumulate our run ticks
+ 	 * and wakeup any waiters.
+@@ -298,9 +308,7 @@ void xe_exec_queue_fini(struct xe_exec_queue *q)
+ 	if (q->xef && atomic_dec_and_test(&q->xef->exec_queue.pending_removal))
+ 		wake_up_var(&q->xef->exec_queue.pending_removal);
+ 
+-	for (i = 0; i < q->width; ++i)
+-		xe_lrc_put(q->lrc[i]);
+-
++	__xe_exec_queue_fini(q);
+ 	__xe_exec_queue_free(q);
+ }
+ 
+diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h
+index cc1cffb5c87f1d..1c9d03f2a3e5da 100644
+--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h
++++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h
+@@ -166,8 +166,14 @@ struct xe_exec_queue_ops {
+ 	int (*init)(struct xe_exec_queue *q);
+ 	/** @kill: Kill inflight submissions for backend */
+ 	void (*kill)(struct xe_exec_queue *q);
+-	/** @fini: Fini exec queue for submission backend */
++	/** @fini: Undoes the init() for submission backend */
+ 	void (*fini)(struct xe_exec_queue *q);
++	/**
++	 * @destroy: Destroy exec queue for submission backend. The backend
++	 * function must call xe_exec_queue_fini() (which will in turn call the
++	 * fini() backend function) to ensure the queue is properly cleaned up.
++	 */
++	void (*destroy)(struct xe_exec_queue *q);
+ 	/** @set_priority: Set priority for exec queue */
+ 	int (*set_priority)(struct xe_exec_queue *q,
+ 			    enum xe_exec_queue_priority priority);
+diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c
+index 788f56b066b6ad..f83d421ac9d3d2 100644
+--- a/drivers/gpu/drm/xe/xe_execlist.c
++++ b/drivers/gpu/drm/xe/xe_execlist.c
+@@ -385,10 +385,20 @@ static int execlist_exec_queue_init(struct xe_exec_queue *q)
+ 	return err;
+ }
+ 
+-static void execlist_exec_queue_fini_async(struct work_struct *w)
++static void execlist_exec_queue_fini(struct xe_exec_queue *q)
++{
++	struct xe_execlist_exec_queue *exl = q->execlist;
++
++	drm_sched_entity_fini(&exl->entity);
++	drm_sched_fini(&exl->sched);
++
++	kfree(exl);
++}
++
++static void execlist_exec_queue_destroy_async(struct work_struct *w)
+ {
+ 	struct xe_execlist_exec_queue *ee =
+-		container_of(w, struct xe_execlist_exec_queue, fini_async);
++		container_of(w, struct xe_execlist_exec_queue, destroy_async);
+ 	struct xe_exec_queue *q = ee->q;
+ 	struct xe_execlist_exec_queue *exl = q->execlist;
+ 	struct xe_device *xe = gt_to_xe(q->gt);
+@@ -401,10 +411,6 @@ static void execlist_exec_queue_fini_async(struct work_struct *w)
+ 		list_del(&exl->active_link);
+ 	spin_unlock_irqrestore(&exl->port->lock, flags);
+ 
+-	drm_sched_entity_fini(&exl->entity);
+-	drm_sched_fini(&exl->sched);
+-	kfree(exl);
+-
+ 	xe_exec_queue_fini(q);
+ }
+ 
+@@ -413,10 +419,10 @@ static void execlist_exec_queue_kill(struct xe_exec_queue *q)
+ 	/* NIY */
+ }
+ 
+-static void execlist_exec_queue_fini(struct xe_exec_queue *q)
++static void execlist_exec_queue_destroy(struct xe_exec_queue *q)
+ {
+-	INIT_WORK(&q->execlist->fini_async, execlist_exec_queue_fini_async);
+-	queue_work(system_unbound_wq, &q->execlist->fini_async);
++	INIT_WORK(&q->execlist->destroy_async, execlist_exec_queue_destroy_async);
++	queue_work(system_unbound_wq, &q->execlist->destroy_async);
+ }
+ 
+ static int execlist_exec_queue_set_priority(struct xe_exec_queue *q,
+@@ -467,6 +473,7 @@ static const struct xe_exec_queue_ops execlist_exec_queue_ops = {
+ 	.init = execlist_exec_queue_init,
+ 	.kill = execlist_exec_queue_kill,
+ 	.fini = execlist_exec_queue_fini,
++	.destroy = execlist_exec_queue_destroy,
+ 	.set_priority = execlist_exec_queue_set_priority,
+ 	.set_timeslice = execlist_exec_queue_set_timeslice,
+ 	.set_preempt_timeout = execlist_exec_queue_set_preempt_timeout,
+diff --git a/drivers/gpu/drm/xe/xe_execlist_types.h b/drivers/gpu/drm/xe/xe_execlist_types.h
+index 415140936f11da..92c4ba52db0cb1 100644
+--- a/drivers/gpu/drm/xe/xe_execlist_types.h
++++ b/drivers/gpu/drm/xe/xe_execlist_types.h
+@@ -42,7 +42,7 @@ struct xe_execlist_exec_queue {
+ 
+ 	bool has_run;
+ 
+-	struct work_struct fini_async;
++	struct work_struct destroy_async;
+ 
+ 	enum xe_exec_queue_priority active_priority;
+ 	struct list_head active_link;
+diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
+index e3517ce2e18c14..eaf7569a7c1d1e 100644
+--- a/drivers/gpu/drm/xe/xe_gt.c
++++ b/drivers/gpu/drm/xe/xe_gt.c
+@@ -41,6 +41,7 @@
+ #include "xe_gt_topology.h"
+ #include "xe_guc_exec_queue_types.h"
+ #include "xe_guc_pc.h"
++#include "xe_guc_submit.h"
+ #include "xe_hw_fence.h"
+ #include "xe_hw_engine_class_sysfs.h"
+ #include "xe_irq.h"
+@@ -97,7 +98,7 @@ void xe_gt_sanitize(struct xe_gt *gt)
+ 	 * FIXME: if xe_uc_sanitize is called here, on TGL driver will not
+ 	 * reload
+ 	 */
+-	gt->uc.guc.submission_state.enabled = false;
++	xe_guc_submit_disable(&gt->uc.guc);
+ }
+ 
+ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt)
+diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
+index 53a44702c04afd..c15dc600dcae7a 100644
+--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
++++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
+@@ -1600,7 +1600,6 @@ static u64 pf_estimate_fair_lmem(struct xe_gt *gt, unsigned int num_vfs)
+ 	u64 fair;
+ 
+ 	fair = div_u64(available, num_vfs);
+-	fair = rounddown_pow_of_two(fair);	/* XXX: ttm_vram_mgr & drm_buddy limitation */
+ 	fair = ALIGN_DOWN(fair, alignment);
+ #ifdef MAX_FAIR_LMEM
+ 	fair = min_t(u64, MAX_FAIR_LMEM, fair);
+diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c
+index bac5471a1a7806..b9d21fdaad48ba 100644
+--- a/drivers/gpu/drm/xe/xe_guc.c
++++ b/drivers/gpu/drm/xe/xe_guc.c
+@@ -29,6 +29,7 @@
+ #include "xe_guc_db_mgr.h"
+ #include "xe_guc_engine_activity.h"
+ #include "xe_guc_hwconfig.h"
++#include "xe_guc_klv_helpers.h"
+ #include "xe_guc_log.h"
+ #include "xe_guc_pc.h"
+ #include "xe_guc_relay.h"
+@@ -570,6 +571,57 @@ static int guc_g2g_start(struct xe_guc *guc)
+ 	return err;
+ }
+ 
++static int __guc_opt_in_features_enable(struct xe_guc *guc, u64 addr, u32 num_dwords)
++{
++	u32 action[] = {
++		XE_GUC_ACTION_OPT_IN_FEATURE_KLV,
++		lower_32_bits(addr),
++		upper_32_bits(addr),
++		num_dwords
++	};
++
++	return xe_guc_ct_send_block(&guc->ct, action, ARRAY_SIZE(action));
++}
++
++#define OPT_IN_MAX_DWORDS 16
++int xe_guc_opt_in_features_enable(struct xe_guc *guc)
++{
++	struct xe_device *xe = guc_to_xe(guc);
++	CLASS(xe_guc_buf, buf)(&guc->buf, OPT_IN_MAX_DWORDS);
++	u32 count = 0;
++	u32 *klvs;
++	int ret;
++
++	if (!xe_guc_buf_is_valid(buf))
++		return -ENOBUFS;
++
++	klvs = xe_guc_buf_cpu_ptr(buf);
++
++	/*
++	 * The extra CAT error type opt-in was added in GuC v70.17.0, which maps
++	 * to compatibility version v1.7.0.
++	 * Note that the GuC allows enabling this KLV even on platforms that do
++	 * not support the extra type; in such case the returned type variable
++	 * will be set to a known invalid value which we can check against.
++	 */
++	if (GUC_SUBMIT_VER(guc) >= MAKE_GUC_VER(1, 7, 0))
++		klvs[count++] = PREP_GUC_KLV_TAG(OPT_IN_FEATURE_EXT_CAT_ERR_TYPE);
++
++	if (count) {
++		xe_assert(xe, count <= OPT_IN_MAX_DWORDS);
++
++		ret = __guc_opt_in_features_enable(guc, xe_guc_buf_flush(buf), count);
++		if (ret < 0) {
++			xe_gt_err(guc_to_gt(guc),
++				  "failed to enable GuC opt-in features: %pe\n",
++				  ERR_PTR(ret));
++			return ret;
++		}
++	}
++
++	return 0;
++}
++
+ static void guc_fini_hw(void *arg)
+ {
+ 	struct xe_guc *guc = arg;
+@@ -763,15 +815,17 @@ int xe_guc_post_load_init(struct xe_guc *guc)
+ 
+ 	xe_guc_ads_populate_post_load(&guc->ads);
+ 
++	ret = xe_guc_opt_in_features_enable(guc);
++	if (ret)
++		return ret;
++
+ 	if (xe_guc_g2g_wanted(guc_to_xe(guc))) {
+ 		ret = guc_g2g_start(guc);
+ 		if (ret)
+ 			return ret;
+ 	}
+ 
+-	guc->submission_state.enabled = true;
+-
+-	return 0;
++	return xe_guc_submit_enable(guc);
+ }
+ 
+ int xe_guc_reset(struct xe_guc *guc)
+@@ -1465,7 +1519,7 @@ void xe_guc_sanitize(struct xe_guc *guc)
+ {
+ 	xe_uc_fw_sanitize(&guc->fw);
+ 	xe_guc_ct_disable(&guc->ct);
+-	guc->submission_state.enabled = false;
++	xe_guc_submit_disable(guc);
+ }
+ 
+ int xe_guc_reset_prepare(struct xe_guc *guc)
+diff --git a/drivers/gpu/drm/xe/xe_guc.h b/drivers/gpu/drm/xe/xe_guc.h
+index 58338be4455856..4a66575f017d2d 100644
+--- a/drivers/gpu/drm/xe/xe_guc.h
++++ b/drivers/gpu/drm/xe/xe_guc.h
+@@ -33,6 +33,7 @@ int xe_guc_reset(struct xe_guc *guc);
+ int xe_guc_upload(struct xe_guc *guc);
+ int xe_guc_min_load_for_hwconfig(struct xe_guc *guc);
+ int xe_guc_enable_communication(struct xe_guc *guc);
++int xe_guc_opt_in_features_enable(struct xe_guc *guc);
+ int xe_guc_suspend(struct xe_guc *guc);
+ void xe_guc_notify(struct xe_guc *guc);
+ int xe_guc_auth_huc(struct xe_guc *guc, u32 rsa_addr);
+diff --git a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
+index a3f421e2adc03b..c30c0e3ccbbb93 100644
+--- a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
++++ b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
+@@ -35,8 +35,8 @@ struct xe_guc_exec_queue {
+ 	struct xe_sched_msg static_msgs[MAX_STATIC_MSG_TYPE];
+ 	/** @lr_tdr: long running TDR worker */
+ 	struct work_struct lr_tdr;
+-	/** @fini_async: do final fini async from this worker */
+-	struct work_struct fini_async;
++	/** @destroy_async: do final destroy async from this worker */
++	struct work_struct destroy_async;
+ 	/** @resume_time: time of last resume */
+ 	u64 resume_time;
+ 	/** @state: GuC specific state for this xe_exec_queue */
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
+index ef3e9e1588f7c6..18ddbb7b98a15b 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -32,6 +32,7 @@
+ #include "xe_guc_ct.h"
+ #include "xe_guc_exec_queue_types.h"
+ #include "xe_guc_id_mgr.h"
++#include "xe_guc_klv_helpers.h"
+ #include "xe_guc_submit_types.h"
+ #include "xe_hw_engine.h"
+ #include "xe_hw_fence.h"
+@@ -316,6 +317,71 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids)
+ 	return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc);
+ }
+ 
++/*
++ * Given that we want to guarantee enough RCS throughput to avoid missing
++ * frames, we set the yield policy to 20% of each 80ms interval.
++ */
++#define RC_YIELD_DURATION	80	/* in ms */
++#define RC_YIELD_RATIO		20	/* in percent */
++static u32 *emit_render_compute_yield_klv(u32 *emit)
++{
++	*emit++ = PREP_GUC_KLV_TAG(SCHEDULING_POLICIES_RENDER_COMPUTE_YIELD);
++	*emit++ = RC_YIELD_DURATION;
++	*emit++ = RC_YIELD_RATIO;
++
++	return emit;
++}
++
++#define SCHEDULING_POLICY_MAX_DWORDS 16
++static int guc_init_global_schedule_policy(struct xe_guc *guc)
++{
++	u32 data[SCHEDULING_POLICY_MAX_DWORDS];
++	u32 *emit = data;
++	u32 count = 0;
++	int ret;
++
++	if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 1, 0))
++		return 0;
++
++	*emit++ = XE_GUC_ACTION_UPDATE_SCHEDULING_POLICIES_KLV;
++
++	if (CCS_MASK(guc_to_gt(guc)))
++		emit = emit_render_compute_yield_klv(emit);
++
++	count = emit - data;
++	if (count > 1) {
++		xe_assert(guc_to_xe(guc), count <= SCHEDULING_POLICY_MAX_DWORDS);
++
++		ret = xe_guc_ct_send_block(&guc->ct, data, count);
++		if (ret < 0) {
++			xe_gt_err(guc_to_gt(guc),
++				  "failed to enable GuC sheduling policies: %pe\n",
++				  ERR_PTR(ret));
++			return ret;
++		}
++	}
++
++	return 0;
++}
++
++int xe_guc_submit_enable(struct xe_guc *guc)
++{
++	int ret;
++
++	ret = guc_init_global_schedule_policy(guc);
++	if (ret)
++		return ret;
++
++	guc->submission_state.enabled = true;
++
++	return 0;
++}
++
++void xe_guc_submit_disable(struct xe_guc *guc)
++{
++	guc->submission_state.enabled = false;
++}
++
+ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa_count)
+ {
+ 	int i;
+@@ -1269,48 +1335,57 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
+ 	return DRM_GPU_SCHED_STAT_NOMINAL;
+ }
+ 
+-static void __guc_exec_queue_fini_async(struct work_struct *w)
++static void guc_exec_queue_fini(struct xe_exec_queue *q)
++{
++	struct xe_guc_exec_queue *ge = q->guc;
++	struct xe_guc *guc = exec_queue_to_guc(q);
++
++	release_guc_id(guc, q);
++	xe_sched_entity_fini(&ge->entity);
++	xe_sched_fini(&ge->sched);
++
++	/*
++	 * RCU free due sched being exported via DRM scheduler fences
++	 * (timeline name).
++	 */
++	kfree_rcu(ge, rcu);
++}
++
++static void __guc_exec_queue_destroy_async(struct work_struct *w)
+ {
+ 	struct xe_guc_exec_queue *ge =
+-		container_of(w, struct xe_guc_exec_queue, fini_async);
++		container_of(w, struct xe_guc_exec_queue, destroy_async);
+ 	struct xe_exec_queue *q = ge->q;
+ 	struct xe_guc *guc = exec_queue_to_guc(q);
+ 
+ 	xe_pm_runtime_get(guc_to_xe(guc));
+ 	trace_xe_exec_queue_destroy(q);
+ 
+-	release_guc_id(guc, q);
+ 	if (xe_exec_queue_is_lr(q))
+ 		cancel_work_sync(&ge->lr_tdr);
+ 	/* Confirm no work left behind accessing device structures */
+ 	cancel_delayed_work_sync(&ge->sched.base.work_tdr);
+-	xe_sched_entity_fini(&ge->entity);
+-	xe_sched_fini(&ge->sched);
+ 
+-	/*
+-	 * RCU free due sched being exported via DRM scheduler fences
+-	 * (timeline name).
+-	 */
+-	kfree_rcu(ge, rcu);
+ 	xe_exec_queue_fini(q);
++
+ 	xe_pm_runtime_put(guc_to_xe(guc));
+ }
+ 
+-static void guc_exec_queue_fini_async(struct xe_exec_queue *q)
++static void guc_exec_queue_destroy_async(struct xe_exec_queue *q)
+ {
+ 	struct xe_guc *guc = exec_queue_to_guc(q);
+ 	struct xe_device *xe = guc_to_xe(guc);
+ 
+-	INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async);
++	INIT_WORK(&q->guc->destroy_async, __guc_exec_queue_destroy_async);
+ 
+ 	/* We must block on kernel engines so slabs are empty on driver unload */
+ 	if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q))
+-		__guc_exec_queue_fini_async(&q->guc->fini_async);
++		__guc_exec_queue_destroy_async(&q->guc->destroy_async);
+ 	else
+-		queue_work(xe->destroy_wq, &q->guc->fini_async);
++		queue_work(xe->destroy_wq, &q->guc->destroy_async);
+ }
+ 
+-static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q)
++static void __guc_exec_queue_destroy(struct xe_guc *guc, struct xe_exec_queue *q)
+ {
+ 	/*
+ 	 * Might be done from within the GPU scheduler, need to do async as we
+@@ -1319,7 +1394,7 @@ static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q)
+ 	 * this we and don't really care when everything is fini'd, just that it
+ 	 * is.
+ 	 */
+-	guc_exec_queue_fini_async(q);
++	guc_exec_queue_destroy_async(q);
+ }
+ 
+ static void __guc_exec_queue_process_msg_cleanup(struct xe_sched_msg *msg)
+@@ -1333,7 +1408,7 @@ static void __guc_exec_queue_process_msg_cleanup(struct xe_sched_msg *msg)
+ 	if (exec_queue_registered(q))
+ 		disable_scheduling_deregister(guc, q);
+ 	else
+-		__guc_exec_queue_fini(guc, q);
++		__guc_exec_queue_destroy(guc, q);
+ }
+ 
+ static bool guc_exec_queue_allowed_to_change_state(struct xe_exec_queue *q)
+@@ -1566,14 +1641,14 @@ static bool guc_exec_queue_try_add_msg(struct xe_exec_queue *q,
+ #define STATIC_MSG_CLEANUP	0
+ #define STATIC_MSG_SUSPEND	1
+ #define STATIC_MSG_RESUME	2
+-static void guc_exec_queue_fini(struct xe_exec_queue *q)
++static void guc_exec_queue_destroy(struct xe_exec_queue *q)
+ {
+ 	struct xe_sched_msg *msg = q->guc->static_msgs + STATIC_MSG_CLEANUP;
+ 
+ 	if (!(q->flags & EXEC_QUEUE_FLAG_PERMANENT) && !exec_queue_wedged(q))
+ 		guc_exec_queue_add_msg(q, msg, CLEANUP);
+ 	else
+-		__guc_exec_queue_fini(exec_queue_to_guc(q), q);
++		__guc_exec_queue_destroy(exec_queue_to_guc(q), q);
+ }
+ 
+ static int guc_exec_queue_set_priority(struct xe_exec_queue *q,
+@@ -1703,6 +1778,7 @@ static const struct xe_exec_queue_ops guc_exec_queue_ops = {
+ 	.init = guc_exec_queue_init,
+ 	.kill = guc_exec_queue_kill,
+ 	.fini = guc_exec_queue_fini,
++	.destroy = guc_exec_queue_destroy,
+ 	.set_priority = guc_exec_queue_set_priority,
+ 	.set_timeslice = guc_exec_queue_set_timeslice,
+ 	.set_preempt_timeout = guc_exec_queue_set_preempt_timeout,
+@@ -1724,7 +1800,7 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q)
+ 		if (exec_queue_extra_ref(q) || xe_exec_queue_is_lr(q))
+ 			xe_exec_queue_put(q);
+ 		else if (exec_queue_destroyed(q))
+-			__guc_exec_queue_fini(guc, q);
++			__guc_exec_queue_destroy(guc, q);
+ 	}
+ 	if (q->guc->suspend_pending) {
+ 		set_exec_queue_suspended(q);
+@@ -1981,7 +2057,7 @@ static void handle_deregister_done(struct xe_guc *guc, struct xe_exec_queue *q)
+ 	if (exec_queue_extra_ref(q) || xe_exec_queue_is_lr(q))
+ 		xe_exec_queue_put(q);
+ 	else
+-		__guc_exec_queue_fini(guc, q);
++		__guc_exec_queue_destroy(guc, q);
+ }
+ 
+ int xe_guc_deregister_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
+@@ -2078,12 +2154,16 @@ int xe_guc_exec_queue_memory_cat_error_handler(struct xe_guc *guc, u32 *msg,
+ 	struct xe_gt *gt = guc_to_gt(guc);
+ 	struct xe_exec_queue *q;
+ 	u32 guc_id;
++	u32 type = XE_GUC_CAT_ERR_TYPE_INVALID;
+ 
+-	if (unlikely(len < 1))
++	if (unlikely(!len || len > 2))
+ 		return -EPROTO;
+ 
+ 	guc_id = msg[0];
+ 
++	if (len == 2)
++		type = msg[1];
++
+ 	if (guc_id == GUC_ID_UNKNOWN) {
+ 		/*
+ 		 * GuC uses GUC_ID_UNKNOWN if it can not map the CAT fault to any PF/VF
+@@ -2097,8 +2177,19 @@ int xe_guc_exec_queue_memory_cat_error_handler(struct xe_guc *guc, u32 *msg,
+ 	if (unlikely(!q))
+ 		return -EPROTO;
+ 
+-	xe_gt_dbg(gt, "Engine memory cat error: engine_class=%s, logical_mask: 0x%x, guc_id=%d",
+-		  xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id);
++	/*
++	 * The type is HW-defined and changes based on platform, so we don't
++	 * decode it in the kernel and only check if it is valid.
++	 * See bspec 54047 and 72187 for details.
++	 */
++	if (type != XE_GUC_CAT_ERR_TYPE_INVALID)
++		xe_gt_dbg(gt,
++			  "Engine memory CAT error [%u]: class=%s, logical_mask: 0x%x, guc_id=%d",
++			  type, xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id);
++	else
++		xe_gt_dbg(gt,
++			  "Engine memory CAT error: class=%s, logical_mask: 0x%x, guc_id=%d",
++			  xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id);
+ 
+ 	trace_xe_exec_queue_memory_cat_error(q);
+ 
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.h b/drivers/gpu/drm/xe/xe_guc_submit.h
+index 9b71a986c6ca69..0d126b807c1041 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.h
++++ b/drivers/gpu/drm/xe/xe_guc_submit.h
+@@ -13,6 +13,8 @@ struct xe_exec_queue;
+ struct xe_guc;
+ 
+ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids);
++int xe_guc_submit_enable(struct xe_guc *guc);
++void xe_guc_submit_disable(struct xe_guc *guc);
+ 
+ int xe_guc_submit_reset_prepare(struct xe_guc *guc);
+ void xe_guc_submit_reset_wait(struct xe_guc *guc);
+diff --git a/drivers/gpu/drm/xe/xe_tile_sysfs.c b/drivers/gpu/drm/xe/xe_tile_sysfs.c
+index b804234a655160..9e1236a9ec6734 100644
+--- a/drivers/gpu/drm/xe/xe_tile_sysfs.c
++++ b/drivers/gpu/drm/xe/xe_tile_sysfs.c
+@@ -44,16 +44,18 @@ int xe_tile_sysfs_init(struct xe_tile *tile)
+ 	kt->tile = tile;
+ 
+ 	err = kobject_add(&kt->base, &dev->kobj, "tile%d", tile->id);
+-	if (err) {
+-		kobject_put(&kt->base);
+-		return err;
+-	}
++	if (err)
++		goto err_object;
+ 
+ 	tile->sysfs = &kt->base;
+ 
+ 	err = xe_vram_freq_sysfs_init(tile);
+ 	if (err)
+-		return err;
++		goto err_object;
+ 
+ 	return devm_add_action_or_reset(xe->drm.dev, tile_sysfs_fini, tile);
++
++err_object:
++	kobject_put(&kt->base);
++	return err;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_uc.c b/drivers/gpu/drm/xe/xe_uc.c
+index 3a8751a8b92dde..5c45b0f072a4c2 100644
+--- a/drivers/gpu/drm/xe/xe_uc.c
++++ b/drivers/gpu/drm/xe/xe_uc.c
+@@ -165,6 +165,10 @@ static int vf_uc_init_hw(struct xe_uc *uc)
+ 
+ 	uc->guc.submission_state.enabled = true;
+ 
++	err = xe_guc_opt_in_features_enable(&uc->guc);
++	if (err)
++		return err;
++
+ 	err = xe_gt_record_default_lrcs(uc_to_gt(uc));
+ 	if (err)
+ 		return err;
+diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
+index 84052b98002d14..92ce7374a79ce9 100644
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -240,8 +240,8 @@ int xe_vm_add_compute_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q)
+ 
+ 	pfence = xe_preempt_fence_create(q, q->lr.context,
+ 					 ++q->lr.seqno);
+-	if (!pfence) {
+-		err = -ENOMEM;
++	if (IS_ERR(pfence)) {
++		err = PTR_ERR(pfence);
+ 		goto out_fini;
+ 	}
+ 
+diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
+index ccbab3a4811adf..a1086b6d1f11f8 100644
+--- a/drivers/iommu/amd/amd_iommu_types.h
++++ b/drivers/iommu/amd/amd_iommu_types.h
+@@ -551,6 +551,7 @@ struct gcr3_tbl_info {
+ };
+ 
+ struct amd_io_pgtable {
++	seqcount_t		seqcount;	/* Protects root/mode update */
+ 	struct io_pgtable	pgtbl;
+ 	int			mode;
+ 	u64			*root;
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 7add9bcf45dc8b..eef55aa4143c1f 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -1450,12 +1450,12 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
+ 				    PCI_FUNC(e->devid));
+ 
+ 			devid = e->devid;
+-			for (dev_i = devid_start; dev_i <= devid; ++dev_i) {
+-				if (alias)
++			if (alias) {
++				for (dev_i = devid_start; dev_i <= devid; ++dev_i)
+ 					pci_seg->alias_table[dev_i] = devid_to;
++				set_dev_entry_from_acpi(iommu, devid_to, flags, ext_flags);
+ 			}
+ 			set_dev_entry_from_acpi_range(iommu, devid_start, devid, flags, ext_flags);
+-			set_dev_entry_from_acpi(iommu, devid_to, flags, ext_flags);
+ 			break;
+ 		case IVHD_DEV_SPECIAL: {
+ 			u8 handle, type;
+@@ -3048,7 +3048,8 @@ static int __init early_amd_iommu_init(void)
+ 
+ 	if (!boot_cpu_has(X86_FEATURE_CX16)) {
+ 		pr_err("Failed to initialize. The CMPXCHG16B feature is required.\n");
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto out;
+ 	}
+ 
+ 	/*
+diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
+index 4d308c07113495..5c6fdf38636a0c 100644
+--- a/drivers/iommu/amd/io_pgtable.c
++++ b/drivers/iommu/amd/io_pgtable.c
+@@ -17,6 +17,7 @@
+ #include <linux/slab.h>
+ #include <linux/types.h>
+ #include <linux/dma-mapping.h>
++#include <linux/seqlock.h>
+ 
+ #include <asm/barrier.h>
+ 
+@@ -130,8 +131,11 @@ static bool increase_address_space(struct amd_io_pgtable *pgtable,
+ 
+ 	*pte = PM_LEVEL_PDE(pgtable->mode, iommu_virt_to_phys(pgtable->root));
+ 
++	write_seqcount_begin(&pgtable->seqcount);
+ 	pgtable->root  = pte;
+ 	pgtable->mode += 1;
++	write_seqcount_end(&pgtable->seqcount);
++
+ 	amd_iommu_update_and_flush_device_table(domain);
+ 
+ 	pte = NULL;
+@@ -153,6 +157,7 @@ static u64 *alloc_pte(struct amd_io_pgtable *pgtable,
+ {
+ 	unsigned long last_addr = address + (page_size - 1);
+ 	struct io_pgtable_cfg *cfg = &pgtable->pgtbl.cfg;
++	unsigned int seqcount;
+ 	int level, end_lvl;
+ 	u64 *pte, *page;
+ 
+@@ -170,8 +175,14 @@ static u64 *alloc_pte(struct amd_io_pgtable *pgtable,
+ 	}
+ 
+ 
+-	level   = pgtable->mode - 1;
+-	pte     = &pgtable->root[PM_LEVEL_INDEX(level, address)];
++	do {
++		seqcount = read_seqcount_begin(&pgtable->seqcount);
++
++		level   = pgtable->mode - 1;
++		pte     = &pgtable->root[PM_LEVEL_INDEX(level, address)];
++	} while (read_seqcount_retry(&pgtable->seqcount, seqcount));
++
++
+ 	address = PAGE_SIZE_ALIGN(address, page_size);
+ 	end_lvl = PAGE_SIZE_LEVEL(page_size);
+ 
+@@ -249,6 +260,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
+ 		      unsigned long *page_size)
+ {
+ 	int level;
++	unsigned int seqcount;
+ 	u64 *pte;
+ 
+ 	*page_size = 0;
+@@ -256,8 +268,12 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
+ 	if (address > PM_LEVEL_SIZE(pgtable->mode))
+ 		return NULL;
+ 
+-	level	   =  pgtable->mode - 1;
+-	pte	   = &pgtable->root[PM_LEVEL_INDEX(level, address)];
++	do {
++		seqcount = read_seqcount_begin(&pgtable->seqcount);
++		level	   =  pgtable->mode - 1;
++		pte	   = &pgtable->root[PM_LEVEL_INDEX(level, address)];
++	} while (read_seqcount_retry(&pgtable->seqcount, seqcount));
++
+ 	*page_size =  PTE_LEVEL_PAGE_SIZE(level);
+ 
+ 	while (level > 0) {
+@@ -541,6 +557,7 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo
+ 	if (!pgtable->root)
+ 		return NULL;
+ 	pgtable->mode = PAGE_MODE_3_LEVEL;
++	seqcount_init(&pgtable->seqcount);
+ 
+ 	cfg->pgsize_bitmap  = amd_iommu_pgsize_bitmap;
+ 	cfg->ias            = IOMMU_IN_ADDR_BIT_SIZE;
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 34dd175a331dc7..3dd4d73fcb5dc6 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -1592,6 +1592,10 @@ static void switch_to_super_page(struct dmar_domain *domain,
+ 	unsigned long lvl_pages = lvl_to_nr_pages(level);
+ 	struct dma_pte *pte = NULL;
+ 
++	if (WARN_ON(!IS_ALIGNED(start_pfn, lvl_pages) ||
++		    !IS_ALIGNED(end_pfn + 1, lvl_pages)))
++		return;
++
+ 	while (start_pfn <= end_pfn) {
+ 		if (!pte)
+ 			pte = pfn_to_dma_pte(domain, start_pfn, &level,
+@@ -1667,7 +1671,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
+ 				unsigned long pages_to_remove;
+ 
+ 				pteval |= DMA_PTE_LARGE_PAGE;
+-				pages_to_remove = min_t(unsigned long, nr_pages,
++				pages_to_remove = min_t(unsigned long,
++							round_down(nr_pages, lvl_pages),
+ 							nr_pte_to_next_page(pte) * lvl_pages);
+ 				end_pfn = iov_pfn + pages_to_remove - 1;
+ 				switch_to_super_page(domain, iov_pfn, end_pfn, largepage_lvl);
+diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
+index 433b59f435302b..cc9ec636a7a21e 100644
+--- a/drivers/iommu/s390-iommu.c
++++ b/drivers/iommu/s390-iommu.c
+@@ -611,6 +611,23 @@ static u64 get_iota_region_flag(struct s390_domain *domain)
+ 	}
+ }
+ 
++static bool reg_ioat_propagate_error(int cc, u8 status)
++{
++	/*
++	 * If the device is in the error state the reset routine
++	 * will register the IOAT of the newly set domain on re-enable
++	 */
++	if (cc == ZPCI_CC_ERR && status == ZPCI_PCI_ST_FUNC_NOT_AVAIL)
++		return false;
++	/*
++	 * If the device was removed treat registration as success
++	 * and let the subsequent error event trigger tear down.
++	 */
++	if (cc == ZPCI_CC_INVAL_HANDLE)
++		return false;
++	return cc != ZPCI_CC_OK;
++}
++
+ static int s390_iommu_domain_reg_ioat(struct zpci_dev *zdev,
+ 				      struct iommu_domain *domain, u8 *status)
+ {
+@@ -695,7 +712,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 
+ 	/* If we fail now DMA remains blocked via blocking domain */
+ 	cc = s390_iommu_domain_reg_ioat(zdev, domain, &status);
+-	if (cc && status != ZPCI_PCI_ST_FUNC_NOT_AVAIL)
++	if (reg_ioat_propagate_error(cc, status))
+ 		return -EIO;
+ 	zdev->dma_table = s390_domain->dma_table;
+ 	zdev_s390_domain_update(zdev, domain);
+@@ -1031,7 +1048,8 @@ struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev)
+ 
+ 	lockdep_assert_held(&zdev->dom_lock);
+ 
+-	if (zdev->s390_domain->type == IOMMU_DOMAIN_BLOCKED)
++	if (zdev->s390_domain->type == IOMMU_DOMAIN_BLOCKED ||
++	    zdev->s390_domain->type == IOMMU_DOMAIN_IDENTITY)
+ 		return NULL;
+ 
+ 	s390_domain = to_s390_domain(zdev->s390_domain);
+@@ -1122,12 +1140,7 @@ static int s390_attach_dev_identity(struct iommu_domain *domain,
+ 
+ 	/* If we fail now DMA remains blocked via blocking domain */
+ 	cc = s390_iommu_domain_reg_ioat(zdev, domain, &status);
+-
+-	/*
+-	 * If the device is undergoing error recovery the reset code
+-	 * will re-establish the new domain.
+-	 */
+-	if (cc && status != ZPCI_PCI_ST_FUNC_NOT_AVAIL)
++	if (reg_ioat_propagate_error(cc, status))
+ 		return -EIO;
+ 
+ 	zdev_s390_domain_update(zdev, domain);
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 9835f2fe26e99f..1e09b4860a4543 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3810,8 +3810,10 @@ static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits)
+ 	struct raid_set *rs = ti->private;
+ 	unsigned int chunk_size_bytes = to_bytes(rs->md.chunk_sectors);
+ 
+-	limits->io_min = chunk_size_bytes;
+-	limits->io_opt = chunk_size_bytes * mddev_data_stripes(rs);
++	if (chunk_size_bytes) {
++		limits->io_min = chunk_size_bytes;
++		limits->io_opt = chunk_size_bytes * mddev_data_stripes(rs);
++	}
+ }
+ 
+ static void raid_presuspend(struct dm_target *ti)
+diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
+index 5bbbdf8fc1bdef..2313dbaf642422 100644
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -456,11 +456,15 @@ static void stripe_io_hints(struct dm_target *ti,
+ 			    struct queue_limits *limits)
+ {
+ 	struct stripe_c *sc = ti->private;
+-	unsigned int chunk_size = sc->chunk_size << SECTOR_SHIFT;
++	unsigned int io_min, io_opt;
+ 
+ 	limits->chunk_sectors = sc->chunk_size;
+-	limits->io_min = chunk_size;
+-	limits->io_opt = chunk_size * sc->stripes;
++
++	if (!check_shl_overflow(sc->chunk_size, SECTOR_SHIFT, &io_min) &&
++	    !check_mul_overflow(io_min, sc->stripes, &io_opt)) {
++		limits->io_min = io_min;
++		limits->io_opt = io_opt;
++	}
+ }
+ 
+ static struct target_type stripe_target = {
+diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
+index 101f36de7b63bd..8165fa4d0d937a 100644
+--- a/drivers/mmc/host/mvsdio.c
++++ b/drivers/mmc/host/mvsdio.c
+@@ -292,7 +292,7 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+ 		host->pio_ptr = NULL;
+ 		host->pio_size = 0;
+ 	} else {
+-		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
++		dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+ 			     mmc_get_dma_dir(data));
+ 	}
+ 
+diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
+index 3a1de477e9af8d..b0f91cc9e40e43 100644
+--- a/drivers/mmc/host/sdhci-pci-gli.c
++++ b/drivers/mmc/host/sdhci-pci-gli.c
+@@ -283,6 +283,8 @@
+ #define   PCIE_GLI_9767_UHS2_CTL2_ZC_VALUE	  0xb
+ #define   PCIE_GLI_9767_UHS2_CTL2_ZC_CTL	  BIT(6)
+ #define   PCIE_GLI_9767_UHS2_CTL2_ZC_CTL_VALUE	  0x1
++#define   PCIE_GLI_9767_UHS2_CTL2_FORCE_PHY_RESETN	BIT(13)
++#define   PCIE_GLI_9767_UHS2_CTL2_FORCE_RESETN_VALUE	BIT(14)
+ 
+ #define GLI_MAX_TUNING_LOOP 40
+ 
+@@ -1179,6 +1181,65 @@ static void gl9767_set_low_power_negotiation(struct pci_dev *pdev, bool enable)
+ 	gl9767_vhs_read(pdev);
+ }
+ 
++static void sdhci_gl9767_uhs2_phy_reset(struct sdhci_host *host, bool assert)
++{
++	struct sdhci_pci_slot *slot = sdhci_priv(host);
++	struct pci_dev *pdev = slot->chip->pdev;
++	u32 value, set, clr;
++
++	if (assert) {
++		/* Assert reset, set RESETN and clean RESETN_VALUE */
++		set = PCIE_GLI_9767_UHS2_CTL2_FORCE_PHY_RESETN;
++		clr = PCIE_GLI_9767_UHS2_CTL2_FORCE_RESETN_VALUE;
++	} else {
++		/* De-assert reset, clean RESETN and set RESETN_VALUE */
++		set = PCIE_GLI_9767_UHS2_CTL2_FORCE_RESETN_VALUE;
++		clr = PCIE_GLI_9767_UHS2_CTL2_FORCE_PHY_RESETN;
++	}
++
++	gl9767_vhs_write(pdev);
++	pci_read_config_dword(pdev, PCIE_GLI_9767_UHS2_CTL2, &value);
++	value |= set;
++	pci_write_config_dword(pdev, PCIE_GLI_9767_UHS2_CTL2, value);
++	value &= ~clr;
++	pci_write_config_dword(pdev, PCIE_GLI_9767_UHS2_CTL2, value);
++	gl9767_vhs_read(pdev);
++}
++
++static void __gl9767_uhs2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd)
++{
++	u8 pwr = 0;
++
++	if (mode != MMC_POWER_OFF) {
++		pwr = sdhci_get_vdd_value(vdd);
++		if (!pwr)
++			WARN(1, "%s: Invalid vdd %#x\n",
++			     mmc_hostname(host->mmc), vdd);
++		pwr |= SDHCI_VDD2_POWER_180;
++	}
++
++	if (host->pwr == pwr)
++		return;
++
++	host->pwr = pwr;
++
++	if (pwr == 0) {
++		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
++	} else {
++		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
++
++		pwr |= SDHCI_POWER_ON;
++		sdhci_writeb(host, pwr & 0xf, SDHCI_POWER_CONTROL);
++		usleep_range(5000, 6250);
++
++		/* Assert reset */
++		sdhci_gl9767_uhs2_phy_reset(host, true);
++		pwr |= SDHCI_VDD2_POWER_ON;
++		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
++		usleep_range(5000, 6250);
++	}
++}
++
+ static void sdhci_gl9767_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+ 	struct sdhci_pci_slot *slot = sdhci_priv(host);
+@@ -1205,6 +1266,11 @@ static void sdhci_gl9767_set_clock(struct sdhci_host *host, unsigned int clock)
+ 	}
+ 
+ 	sdhci_enable_clk(host, clk);
++
++	if (mmc_card_uhs2(host->mmc))
++		/* De-assert reset */
++		sdhci_gl9767_uhs2_phy_reset(host, false);
++
+ 	gl9767_set_low_power_negotiation(pdev, true);
+ }
+ 
+@@ -1476,7 +1542,7 @@ static void sdhci_gl9767_set_power(struct sdhci_host *host, unsigned char mode,
+ 		gl9767_vhs_read(pdev);
+ 
+ 		sdhci_gli_overcurrent_event_enable(host, false);
+-		sdhci_uhs2_set_power(host, mode, vdd);
++		__gl9767_uhs2_set_power(host, mode, vdd);
+ 		sdhci_gli_overcurrent_event_enable(host, true);
+ 	} else {
+ 		gl9767_vhs_write(pdev);
+diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c
+index 0efeb9d0c3765a..c459a08d01da52 100644
+--- a/drivers/mmc/host/sdhci-uhs2.c
++++ b/drivers/mmc/host/sdhci-uhs2.c
+@@ -295,7 +295,8 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 	else
+ 		sdhci_uhs2_set_power(host, ios->power_mode, ios->vdd);
+ 
+-	sdhci_set_clock(host, host->clock);
++	host->ops->set_clock(host, ios->clock);
++	host->clock = ios->clock;
+ }
+ 
+ static int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index e116f2db34d52b..be701eb25fec42 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -2367,23 +2367,6 @@ void sdhci_set_ios_common(struct mmc_host *mmc, struct mmc_ios *ios)
+ 		(ios->power_mode == MMC_POWER_UP) &&
+ 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
+ 		sdhci_enable_preset_value(host, false);
+-
+-	if (!ios->clock || ios->clock != host->clock) {
+-		host->ops->set_clock(host, ios->clock);
+-		host->clock = ios->clock;
+-
+-		if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK &&
+-		    host->clock) {
+-			host->timeout_clk = mmc->actual_clock ?
+-						mmc->actual_clock / 1000 :
+-						host->clock / 1000;
+-			mmc->max_busy_timeout =
+-				host->ops->get_max_timeout_count ?
+-				host->ops->get_max_timeout_count(host) :
+-				1 << 27;
+-			mmc->max_busy_timeout /= host->timeout_clk;
+-		}
+-	}
+ }
+ EXPORT_SYMBOL_GPL(sdhci_set_ios_common);
+ 
+@@ -2410,6 +2393,23 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 
+ 	sdhci_set_ios_common(mmc, ios);
+ 
++	if (!ios->clock || ios->clock != host->clock) {
++		host->ops->set_clock(host, ios->clock);
++		host->clock = ios->clock;
++
++		if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK &&
++		    host->clock) {
++			host->timeout_clk = mmc->actual_clock ?
++						mmc->actual_clock / 1000 :
++						host->clock / 1000;
++			mmc->max_busy_timeout =
++				host->ops->get_max_timeout_count ?
++				host->ops->get_max_timeout_count(host) :
++				1 << 27;
++			mmc->max_busy_timeout /= host->timeout_clk;
++		}
++	}
++
+ 	if (host->ops->set_power)
+ 		host->ops->set_power(host, ios->power_mode, ios->vdd);
+ 	else
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index c4d53e8e7c152d..e23195dd747769 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2115,6 +2115,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+ 		memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len);
+ 	} else if (bond->params.fail_over_mac == BOND_FOM_FOLLOW &&
+ 		   BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
++		   bond_has_slaves(bond) &&
+ 		   memcmp(slave_dev->dev_addr, bond_dev->dev_addr, bond_dev->addr_len) == 0) {
+ 		/* Set slave to random address to avoid duplicate mac
+ 		 * address in later fail over.
+@@ -3338,7 +3339,6 @@ static void bond_ns_send_all(struct bonding *bond, struct slave *slave)
+ 		/* Find out through which dev should the packet go */
+ 		memset(&fl6, 0, sizeof(struct flowi6));
+ 		fl6.daddr = targets[i];
+-		fl6.flowi6_oif = bond->dev->ifindex;
+ 
+ 		dst = ip6_route_output(dev_net(bond->dev), NULL, &fl6);
+ 		if (dst->error) {
+diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
+index a9040c42d2ff97..6e97a5a7daaf9c 100644
+--- a/drivers/net/ethernet/broadcom/cnic.c
++++ b/drivers/net/ethernet/broadcom/cnic.c
+@@ -4230,8 +4230,7 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
+ 
+ 	cnic_bnx2x_delete_wait(dev, 0);
+ 
+-	cancel_delayed_work(&cp->delete_task);
+-	flush_workqueue(cnic_wq);
++	cancel_delayed_work_sync(&cp->delete_task);
+ 
+ 	if (atomic_read(&cp->iscsi_conn) != 0)
+ 		netdev_warn(dev->netdev, "%d iSCSI connections not destroyed\n",
+diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c
+index de8a6ce86ad7e2..12105ffb5dac6d 100644
+--- a/drivers/net/ethernet/cavium/liquidio/request_manager.c
++++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c
+@@ -126,7 +126,7 @@ int octeon_init_instr_queue(struct octeon_device *oct,
+ 	oct->io_qmask.iq |= BIT_ULL(iq_no);
+ 
+ 	/* Set the 32B/64B mode for each input queue */
+-	oct->io_qmask.iq64B |= ((conf->instr_type == 64) << iq_no);
++	oct->io_qmask.iq64B |= ((u64)(conf->instr_type == 64) << iq_no);
+ 	iq->iqcmd_64B = (conf->instr_type == 64);
+ 
+ 	oct->fn_list.setup_iq_regs(oct, iq_no);
+diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+index 4643a338061820..b1e1ad9e4b48e6 100644
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+@@ -2736,7 +2736,7 @@ static int dpaa2_switch_setup_dpbp(struct ethsw_core *ethsw)
+ 		dev_err(dev, "dpsw_ctrl_if_set_pools() failed\n");
+ 		goto err_get_attr;
+ 	}
+-	ethsw->bpid = dpbp_attrs.id;
++	ethsw->bpid = dpbp_attrs.bpid;
+ 
+ 	return 0;
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+index c006f716a3bdbe..ca7517a68a2c32 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+@@ -947,9 +947,6 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
+ 		if (!eop_desc)
+ 			break;
+ 
+-		/* prevent any other reads prior to eop_desc */
+-		smp_rmb();
+-
+ 		i40e_trace(clean_tx_irq, tx_ring, tx_desc, tx_buf);
+ 		/* we have caught up to head, no work left to do */
+ 		if (tx_head == tx_desc)
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index c50cf3ad190e9a..4766597ac55509 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -865,10 +865,6 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ 	__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page,
+ 				   rx_buf->page_offset, size);
+ 	sinfo->xdp_frags_size += size;
+-	/* remember frag count before XDP prog execution; bpf_xdp_adjust_tail()
+-	 * can pop off frags but driver has to handle it on its own
+-	 */
+-	rx_ring->nr_frags = sinfo->nr_frags;
+ 
+ 	if (page_is_pfmemalloc(rx_buf->page))
+ 		xdp_buff_set_frag_pfmemalloc(xdp);
+@@ -939,20 +935,20 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
+ /**
+  * ice_get_pgcnts - grab page_count() for gathered fragments
+  * @rx_ring: Rx descriptor ring to store the page counts on
++ * @ntc: the next to clean element (not included in this frame!)
+  *
+  * This function is intended to be called right before running XDP
+  * program so that the page recycling mechanism will be able to take
+  * a correct decision regarding underlying pages; this is done in such
+  * way as XDP program can change the refcount of page
+  */
+-static void ice_get_pgcnts(struct ice_rx_ring *rx_ring)
++static void ice_get_pgcnts(struct ice_rx_ring *rx_ring, unsigned int ntc)
+ {
+-	u32 nr_frags = rx_ring->nr_frags + 1;
+ 	u32 idx = rx_ring->first_desc;
+ 	struct ice_rx_buf *rx_buf;
+ 	u32 cnt = rx_ring->count;
+ 
+-	for (int i = 0; i < nr_frags; i++) {
++	while (idx != ntc) {
+ 		rx_buf = &rx_ring->rx_buf[idx];
+ 		rx_buf->pgcnt = page_count(rx_buf->page);
+ 
+@@ -1125,62 +1121,51 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf)
+ }
+ 
+ /**
+- * ice_put_rx_mbuf - ice_put_rx_buf() caller, for all frame frags
++ * ice_put_rx_mbuf - ice_put_rx_buf() caller, for all buffers in frame
+  * @rx_ring: Rx ring with all the auxiliary data
+  * @xdp: XDP buffer carrying linear + frags part
+- * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage
+- * @ntc: a current next_to_clean value to be stored at rx_ring
++ * @ntc: the next to clean element (not included in this frame!)
+  * @verdict: return code from XDP program execution
+  *
+- * Walk through gathered fragments and satisfy internal page
+- * recycle mechanism; we take here an action related to verdict
+- * returned by XDP program;
++ * Called after XDP program is completed, or on error with verdict set to
++ * ICE_XDP_CONSUMED.
++ *
++ * Walk through buffers from first_desc to the end of the frame, releasing
++ * buffers and satisfying internal page recycle mechanism. The action depends
++ * on verdict from XDP program.
+  */
+ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+-			    u32 *xdp_xmit, u32 ntc, u32 verdict)
++			    u32 ntc, u32 verdict)
+ {
+-	u32 nr_frags = rx_ring->nr_frags + 1;
+ 	u32 idx = rx_ring->first_desc;
+ 	u32 cnt = rx_ring->count;
+-	u32 post_xdp_frags = 1;
+ 	struct ice_rx_buf *buf;
+-	int i;
++	u32 xdp_frags = 0;
++	int i = 0;
+ 
+ 	if (unlikely(xdp_buff_has_frags(xdp)))
+-		post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags;
++		xdp_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
+ 
+-	for (i = 0; i < post_xdp_frags; i++) {
++	while (idx != ntc) {
+ 		buf = &rx_ring->rx_buf[idx];
++		if (++idx == cnt)
++			idx = 0;
+ 
+-		if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) {
++		/* An XDP program could release fragments from the end of the
++		 * buffer. For these, we need to keep the pagecnt_bias as-is.
++		 * To do this, only adjust pagecnt_bias for fragments up to
++		 * the total remaining after the XDP program has run.
++		 */
++		if (verdict != ICE_XDP_CONSUMED)
+ 			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+-			*xdp_xmit |= verdict;
+-		} else if (verdict & ICE_XDP_CONSUMED) {
++		else if (i++ <= xdp_frags)
+ 			buf->pagecnt_bias++;
+-		} else if (verdict == ICE_XDP_PASS) {
+-			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+-		}
+ 
+ 		ice_put_rx_buf(rx_ring, buf);
+-
+-		if (++idx == cnt)
+-			idx = 0;
+-	}
+-	/* handle buffers that represented frags released by XDP prog;
+-	 * for these we keep pagecnt_bias as-is; refcount from struct page
+-	 * has been decremented within XDP prog and we do not have to increase
+-	 * the biased refcnt
+-	 */
+-	for (; i < nr_frags; i++) {
+-		buf = &rx_ring->rx_buf[idx];
+-		ice_put_rx_buf(rx_ring, buf);
+-		if (++idx == cnt)
+-			idx = 0;
+ 	}
+ 
+ 	xdp->data = NULL;
+ 	rx_ring->first_desc = ntc;
+-	rx_ring->nr_frags = 0;
+ }
+ 
+ /**
+@@ -1260,6 +1245,10 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ 		/* retrieve a buffer from the ring */
+ 		rx_buf = ice_get_rx_buf(rx_ring, size, ntc);
+ 
++		/* Increment ntc before calls to ice_put_rx_mbuf() */
++		if (++ntc == cnt)
++			ntc = 0;
++
+ 		if (!xdp->data) {
+ 			void *hard_start;
+ 
+@@ -1268,24 +1257,23 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ 			xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
+ 			xdp_buff_clear_frags_flag(xdp);
+ 		} else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
+-			ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED);
++			ice_put_rx_mbuf(rx_ring, xdp, ntc, ICE_XDP_CONSUMED);
+ 			break;
+ 		}
+-		if (++ntc == cnt)
+-			ntc = 0;
+ 
+ 		/* skip if it is NOP desc */
+ 		if (ice_is_non_eop(rx_ring, rx_desc))
+ 			continue;
+ 
+-		ice_get_pgcnts(rx_ring);
++		ice_get_pgcnts(rx_ring, ntc);
+ 		xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc);
+ 		if (xdp_verdict == ICE_XDP_PASS)
+ 			goto construct_skb;
+ 		total_rx_bytes += xdp_get_buff_len(xdp);
+ 		total_rx_pkts++;
+ 
+-		ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
++		ice_put_rx_mbuf(rx_ring, xdp, ntc, xdp_verdict);
++		xdp_xmit |= xdp_verdict & (ICE_XDP_TX | ICE_XDP_REDIR);
+ 
+ 		continue;
+ construct_skb:
+@@ -1298,7 +1286,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ 			rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+ 			xdp_verdict = ICE_XDP_CONSUMED;
+ 		}
+-		ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
++		ice_put_rx_mbuf(rx_ring, xdp, ntc, xdp_verdict);
+ 
+ 		if (!skb)
+ 			break;
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index a4b1e95146327d..07155e615f75ab 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -358,7 +358,6 @@ struct ice_rx_ring {
+ 	struct ice_tx_ring *xdp_ring;
+ 	struct ice_rx_ring *next;	/* pointer to next ring in q_vector */
+ 	struct xsk_buff_pool *xsk_pool;
+-	u32 nr_frags;
+ 	u16 max_frame;
+ 	u16 rx_buf_len;
+ 	dma_addr_t dma;			/* physical address of ring */
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 859a15e4ccbab5..1bbe7f72757c06 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -343,6 +343,7 @@ struct igc_adapter {
+ 	/* LEDs */
+ 	struct mutex led_mutex;
+ 	struct igc_led_classdev *leds;
++	bool leds_available;
+ };
+ 
+ void igc_up(struct igc_adapter *adapter);
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 1b4465d6b2b726..5b8f9b51214897 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -7301,8 +7301,14 @@ static int igc_probe(struct pci_dev *pdev,
+ 
+ 	if (IS_ENABLED(CONFIG_IGC_LEDS)) {
+ 		err = igc_led_setup(adapter);
+-		if (err)
+-			goto err_register;
++		if (err) {
++			netdev_warn_once(netdev,
++					 "LED init failed (%d); continuing without LED support\n",
++					 err);
++			adapter->leds_available = false;
++		} else {
++			adapter->leds_available = true;
++		}
+ 	}
+ 
+ 	return 0;
+@@ -7358,7 +7364,7 @@ static void igc_remove(struct pci_dev *pdev)
+ 	cancel_work_sync(&adapter->watchdog_task);
+ 	hrtimer_cancel(&adapter->hrtimer);
+ 
+-	if (IS_ENABLED(CONFIG_IGC_LEDS))
++	if (IS_ENABLED(CONFIG_IGC_LEDS) && adapter->leds_available)
+ 		igc_led_free(adapter);
+ 
+ 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+index cba860f0e1f154..d5c421451f3191 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -6801,6 +6801,13 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
+ 		break;
+ 	}
+ 
++	/* Make sure the SWFW semaphore is in a valid state */
++	if (hw->mac.ops.init_swfw_sync)
++		hw->mac.ops.init_swfw_sync(hw);
++
++	if (hw->mac.type == ixgbe_mac_e610)
++		mutex_init(&hw->aci.lock);
++
+ #ifdef IXGBE_FCOE
+ 	/* FCoE support exists, always init the FCoE lock */
+ 	spin_lock_init(&adapter->fcoe.lock);
+@@ -11474,10 +11481,6 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	if (err)
+ 		goto err_sw_init;
+ 
+-	/* Make sure the SWFW semaphore is in a valid state */
+-	if (hw->mac.ops.init_swfw_sync)
+-		hw->mac.ops.init_swfw_sync(hw);
+-
+ 	if (ixgbe_check_fw_error(adapter))
+ 		return ixgbe_recovery_probe(adapter);
+ 
+@@ -11681,8 +11684,6 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	ether_addr_copy(hw->mac.addr, hw->mac.perm_addr);
+ 	ixgbe_mac_set_default_filter(adapter);
+ 
+-	if (hw->mac.type == ixgbe_mac_e610)
+-		mutex_init(&hw->aci.lock);
+ 	timer_setup(&adapter->service_timer, ixgbe_service_timer, 0);
+ 
+ 	if (ixgbe_removed(hw->hw_addr)) {
+@@ -11838,9 +11839,9 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	devl_unlock(adapter->devlink);
+ 	ixgbe_release_hw_control(adapter);
+ 	ixgbe_clear_interrupt_scheme(adapter);
++err_sw_init:
+ 	if (hw->mac.type == ixgbe_mac_e610)
+ 		mutex_destroy(&adapter->hw.aci.lock);
+-err_sw_init:
+ 	ixgbe_disable_sriov(adapter);
+ 	adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
+ 	iounmap(adapter->io_addr);
+@@ -11891,10 +11892,8 @@ static void ixgbe_remove(struct pci_dev *pdev)
+ 	set_bit(__IXGBE_REMOVING, &adapter->state);
+ 	cancel_work_sync(&adapter->service_task);
+ 
+-	if (adapter->hw.mac.type == ixgbe_mac_e610) {
++	if (adapter->hw.mac.type == ixgbe_mac_e610)
+ 		ixgbe_disable_link_status_events(adapter);
+-		mutex_destroy(&adapter->hw.aci.lock);
+-	}
+ 
+ 	if (adapter->mii_bus)
+ 		mdiobus_unregister(adapter->mii_bus);
+@@ -11954,6 +11953,9 @@ static void ixgbe_remove(struct pci_dev *pdev)
+ 	disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);
+ 	free_netdev(netdev);
+ 
++	if (adapter->hw.mac.type == ixgbe_mac_e610)
++		mutex_destroy(&adapter->hw.aci.lock);
++
+ 	if (disable_dev)
+ 		pci_disable_device(pdev);
+ }
+diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+index 24499bb36c0057..bcea3fc26a8c7d 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+@@ -1124,11 +1124,24 @@ static int octep_set_features(struct net_device *dev, netdev_features_t features
+ 	return err;
+ }
+ 
++static bool octep_is_vf_valid(struct octep_device *oct, int vf)
++{
++	if (vf >= CFG_GET_ACTIVE_VFS(oct->conf)) {
++		netdev_err(oct->netdev, "Invalid VF ID %d\n", vf);
++		return false;
++	}
++
++	return true;
++}
++
+ static int octep_get_vf_config(struct net_device *dev, int vf,
+ 			       struct ifla_vf_info *ivi)
+ {
+ 	struct octep_device *oct = netdev_priv(dev);
+ 
++	if (!octep_is_vf_valid(oct, vf))
++		return -EINVAL;
++
+ 	ivi->vf = vf;
+ 	ether_addr_copy(ivi->mac, oct->vf_info[vf].mac_addr);
+ 	ivi->spoofchk = true;
+@@ -1143,6 +1156,9 @@ static int octep_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
+ 	struct octep_device *oct = netdev_priv(dev);
+ 	int err;
+ 
++	if (!octep_is_vf_valid(oct, vf))
++		return -EINVAL;
++
+ 	if (!is_valid_ether_addr(mac)) {
+ 		dev_err(&oct->pdev->dev, "Invalid  MAC Address %pM\n", mac);
+ 		return -EADDRNOTAVAIL;
+diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
+index ebecdd29f3bd05..0867fab61b1905 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
+@@ -196,6 +196,7 @@ static void octep_pfvf_get_mac_addr(struct octep_device *oct,  u32 vf_id,
+ 			vf_id);
+ 		return;
+ 	}
++	ether_addr_copy(oct->vf_info[vf_id].mac_addr, rsp->s_set_mac.mac_addr);
+ 	rsp->s_set_mac.type = OCTEP_PFVF_MBOX_TYPE_RSP_ACK;
+ }
+ 
+@@ -205,6 +206,8 @@ static void octep_pfvf_dev_remove(struct octep_device *oct,  u32 vf_id,
+ {
+ 	int err;
+ 
++	/* Reset VF-specific information maintained by the PF */
++	memset(&oct->vf_info[vf_id], 0, sizeof(struct octep_pfvf_info));
+ 	err = octep_ctrl_net_dev_remove(oct, vf_id);
+ 	if (err) {
+ 		rsp->s.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
+index 63130ba37e9df1..69b435ed8fbbe9 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
+@@ -491,7 +491,7 @@ void otx2_ptp_destroy(struct otx2_nic *pfvf)
+ 	if (!ptp)
+ 		return;
+ 
+-	cancel_delayed_work(&pfvf->ptp->synctstamp_work);
++	cancel_delayed_work_sync(&pfvf->ptp->synctstamp_work);
+ 
+ 	ptp_clock_unregister(ptp->ptp_clock);
+ 	kfree(ptp);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+index 9560fcba643f50..ac65e319148029 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+@@ -92,6 +92,7 @@ enum {
+ 	MLX5E_ACCEL_FS_ESP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
+ 	MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL,
+ 	MLX5E_ACCEL_FS_POL_FT_LEVEL,
++	MLX5E_ACCEL_FS_POL_MISS_FT_LEVEL,
+ 	MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
+ #endif
+ };
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+index ffcd0cdeb77544..23703f28386ad9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+@@ -185,6 +185,7 @@ struct mlx5e_ipsec_rx_create_attr {
+ 	u32 family;
+ 	int prio;
+ 	int pol_level;
++	int pol_miss_level;
+ 	int sa_level;
+ 	int status_level;
+ 	enum mlx5_flow_namespace_type chains_ns;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+index 98b6a3a623f995..65dc3529283b69 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+@@ -747,6 +747,7 @@ static void ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec,
+ 	attr->family = family;
+ 	attr->prio = MLX5E_NIC_PRIO;
+ 	attr->pol_level = MLX5E_ACCEL_FS_POL_FT_LEVEL;
++	attr->pol_miss_level = MLX5E_ACCEL_FS_POL_MISS_FT_LEVEL;
+ 	attr->sa_level = MLX5E_ACCEL_FS_ESP_FT_LEVEL;
+ 	attr->status_level = MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL;
+ 	attr->chains_ns = MLX5_FLOW_NAMESPACE_KERNEL;
+@@ -833,7 +834,7 @@ static int ipsec_rx_chains_create_miss(struct mlx5e_ipsec *ipsec,
+ 
+ 	ft_attr.max_fte = 1;
+ 	ft_attr.autogroup.max_num_groups = 1;
+-	ft_attr.level = attr->pol_level;
++	ft_attr.level = attr->pol_miss_level;
+ 	ft_attr.prio = attr->prio;
+ 
+ 	ft = mlx5_create_auto_grouped_flow_table(attr->ns, &ft_attr);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index e39c51cfc8e6c2..f0142d32b648f5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -136,8 +136,6 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ 	if (up) {
+ 		netdev_info(priv->netdev, "Link up\n");
+ 		netif_carrier_on(priv->netdev);
+-		mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
+-						NULL, NULL, NULL);
+ 	} else {
+ 		netdev_info(priv->netdev, "Link down\n");
+ 		netif_carrier_off(priv->netdev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+index 63a7a788fb0db5..cd0242eb008c29 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+@@ -1506,12 +1506,21 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
+ static int
+ mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
+ {
+-	struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
+ 	struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
++	struct net_device *netdev;
++	struct mlx5e_priv *priv;
++	int err;
++
++	netdev = mlx5_uplink_netdev_get(dev);
++	if (!netdev)
++		return 0;
+ 
++	priv = netdev_priv(netdev);
+ 	rpriv->netdev = priv->netdev;
+-	return mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
+-					   rpriv);
++	err = mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
++					  rpriv);
++	mlx5_uplink_netdev_put(dev, netdev);
++	return err;
+ }
+ 
+ static void
+@@ -1638,8 +1647,16 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
+ {
+ 	struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
+ 	struct net_device *netdev = rpriv->netdev;
+-	struct mlx5e_priv *priv = netdev_priv(netdev);
+-	void *ppriv = priv->ppriv;
++	struct mlx5e_priv *priv;
++	void *ppriv;
++
++	if (!netdev) {
++		ppriv = rpriv;
++		goto free_ppriv;
++	}
++
++	priv = netdev_priv(netdev);
++	ppriv = priv->ppriv;
+ 
+ 	if (rep->vport == MLX5_VPORT_UPLINK) {
+ 		mlx5e_vport_uplink_rep_unload(rpriv);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+index ad9f6fca9b6a20..c6476e943e98d4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+@@ -743,6 +743,7 @@ static u32 mlx5_esw_qos_lag_link_speed_get_locked(struct mlx5_core_dev *mdev)
+ 		speed = lksettings.base.speed;
+ 
+ out:
++	mlx5_uplink_netdev_put(mdev, slave);
+ 	return speed;
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 29ce09af59aef0..3b57ef6b3de383 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -114,9 +114,9 @@
+ #define ETHTOOL_NUM_PRIOS 11
+ #define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
+ /* Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}}, IPsec policy,
+- * {IPsec RoCE MPV,Alias table},IPsec RoCE policy
++ * IPsec policy miss, {IPsec RoCE MPV,Alias table},IPsec RoCE policy
+  */
+-#define KERNEL_NIC_PRIO_NUM_LEVELS 10
++#define KERNEL_NIC_PRIO_NUM_LEVELS 11
+ #define KERNEL_NIC_NUM_PRIOS 1
+ /* One more level for tc, and one more for promisc */
+ #define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 2)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
+index 37d5f445598c7b..a7486e6d0d5eff 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
+@@ -52,7 +52,20 @@ static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
+ 
+ static inline struct net_device *mlx5_uplink_netdev_get(struct mlx5_core_dev *mdev)
+ {
+-	return mdev->mlx5e_res.uplink_netdev;
++	struct mlx5e_resources *mlx5e_res = &mdev->mlx5e_res;
++	struct net_device *netdev;
++
++	mutex_lock(&mlx5e_res->uplink_netdev_lock);
++	netdev = mlx5e_res->uplink_netdev;
++	netdev_hold(netdev, &mlx5e_res->tracker, GFP_KERNEL);
++	mutex_unlock(&mlx5e_res->uplink_netdev_lock);
++	return netdev;
++}
++
++static inline void mlx5_uplink_netdev_put(struct mlx5_core_dev *mdev,
++					  struct net_device *netdev)
++{
++	netdev_put(netdev, &mdev->mlx5e_res.tracker);
+ }
+ 
+ struct mlx5_sd;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
+index 2d7adf7444ba29..aa9f2b0a77d36f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
+@@ -1170,7 +1170,11 @@ const struct mlx5_link_info *mlx5_port_ptys2info(struct mlx5_core_dev *mdev,
+ 	mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
+ 					  force_legacy);
+ 	i = find_first_bit(&temp, max_size);
+-	if (i < max_size)
++
++	/* mlx5e_link_info has holes. Check speed
++	 * is not zero as indication of one.
++	 */
++	if (i < max_size && table[i].speed)
+ 		return &table[i];
+ 
+ 	return NULL;
+diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
+index 56d5464222d97a..cdbf82affa7bea 100644
+--- a/drivers/net/ethernet/natsemi/ns83820.c
++++ b/drivers/net/ethernet/natsemi/ns83820.c
+@@ -820,7 +820,7 @@ static void rx_irq(struct net_device *ndev)
+ 	struct ns83820 *dev = PRIV(ndev);
+ 	struct rx_info *info = &dev->rx_info;
+ 	unsigned next_rx;
+-	int rx_rc, len;
++	int len;
+ 	u32 cmdsts;
+ 	__le32 *desc;
+ 	unsigned long flags;
+@@ -881,8 +881,10 @@ static void rx_irq(struct net_device *ndev)
+ 		if (likely(CMDSTS_OK & cmdsts)) {
+ #endif
+ 			skb_put(skb, len);
+-			if (unlikely(!skb))
++			if (unlikely(!skb)) {
++				ndev->stats.rx_dropped++;
+ 				goto netdev_mangle_me_harder_failed;
++			}
+ 			if (cmdsts & CMDSTS_DEST_MULTI)
+ 				ndev->stats.multicast++;
+ 			ndev->stats.rx_packets++;
+@@ -901,15 +903,12 @@ static void rx_irq(struct net_device *ndev)
+ 				__vlan_hwaccel_put_tag(skb, htons(ETH_P_IPV6), tag);
+ 			}
+ #endif
+-			rx_rc = netif_rx(skb);
+-			if (NET_RX_DROP == rx_rc) {
+-netdev_mangle_me_harder_failed:
+-				ndev->stats.rx_dropped++;
+-			}
++			netif_rx(skb);
+ 		} else {
+ 			dev_kfree_skb_irq(skb);
+ 		}
+ 
++netdev_mangle_me_harder_failed:
+ 		nr++;
+ 		next_rx = info->next_rx;
+ 		desc = info->descs + (DESC_SIZE * next_rx);
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 9c3d3dd2f84753..1f0cea3cae92f5 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -4462,10 +4462,11 @@ static enum dbg_status qed_protection_override_dump(struct qed_hwfn *p_hwfn,
+ 		goto out;
+ 	}
+ 
+-	/* Add override window info to buffer */
++	/* Add override window info to buffer, preventing buffer overflow */
+ 	override_window_dwords =
+-		qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
+-		PROTECTION_OVERRIDE_ELEMENT_DWORDS;
++		min(qed_rd(p_hwfn, p_ptt, GRC_REG_NUMBER_VALID_OVERRIDE_WINDOW) *
++		PROTECTION_OVERRIDE_ELEMENT_DWORDS,
++		PROTECTION_OVERRIDE_DEPTH_DWORDS);
+ 	if (override_window_dwords) {
+ 		addr = BYTES_TO_DWORDS(GRC_REG_PROTECTION_OVERRIDE_WINDOW);
+ 		offset += qed_grc_dump_addr_range(p_hwfn,
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index 8e6ce16ab5b88f..c9e2dca3083123 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -1731,7 +1731,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
+ 
+ void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid)
+ {
+-	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++	if (test_bit(MT76_MCU_RESET, &dev->phy.state) || !wcid->sta)
+ 		return;
+ 
+ 	spin_lock_bh(&dev->sta_poll_lock);
+diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
+index 131388886acbfa..cfabd5aebb5400 100644
+--- a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
++++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c
+@@ -41,10 +41,10 @@ static const struct wilc_cfg_word g_cfg_word[] = {
+ };
+ 
+ static const struct wilc_cfg_str g_cfg_str[] = {
+-	{WID_FIRMWARE_VERSION, NULL},
+-	{WID_MAC_ADDR, NULL},
+-	{WID_ASSOC_RES_INFO, NULL},
+-	{WID_NIL, NULL}
++	{WID_FIRMWARE_VERSION, 0, NULL},
++	{WID_MAC_ADDR, 0, NULL},
++	{WID_ASSOC_RES_INFO, 0, NULL},
++	{WID_NIL, 0, NULL}
+ };
+ 
+ #define WILC_RESP_MSG_TYPE_CONFIG_REPLY		'R'
+@@ -147,44 +147,58 @@ static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
+ 
+ 		switch (FIELD_GET(WILC_WID_TYPE, wid)) {
+ 		case WID_CHAR:
++			len = 3;
++			if (len + 2  > size)
++				return;
++
+ 			while (cfg->b[i].id != WID_NIL && cfg->b[i].id != wid)
+ 				i++;
+ 
+ 			if (cfg->b[i].id == wid)
+ 				cfg->b[i].val = info[4];
+ 
+-			len = 3;
+ 			break;
+ 
+ 		case WID_SHORT:
++			len = 4;
++			if (len + 2  > size)
++				return;
++
+ 			while (cfg->hw[i].id != WID_NIL && cfg->hw[i].id != wid)
+ 				i++;
+ 
+ 			if (cfg->hw[i].id == wid)
+ 				cfg->hw[i].val = get_unaligned_le16(&info[4]);
+ 
+-			len = 4;
+ 			break;
+ 
+ 		case WID_INT:
++			len = 6;
++			if (len + 2  > size)
++				return;
++
+ 			while (cfg->w[i].id != WID_NIL && cfg->w[i].id != wid)
+ 				i++;
+ 
+ 			if (cfg->w[i].id == wid)
+ 				cfg->w[i].val = get_unaligned_le32(&info[4]);
+ 
+-			len = 6;
+ 			break;
+ 
+ 		case WID_STR:
++			len = 2 + get_unaligned_le16(&info[2]);
++
+ 			while (cfg->s[i].id != WID_NIL && cfg->s[i].id != wid)
+ 				i++;
+ 
+-			if (cfg->s[i].id == wid)
++			if (cfg->s[i].id == wid) {
++				if (len > cfg->s[i].len || (len + 2  > size))
++					return;
++
+ 				memcpy(cfg->s[i].str, &info[2],
+-				       get_unaligned_le16(&info[2]) + 2);
++				       len);
++			}
+ 
+-			len = 2 + get_unaligned_le16(&info[2]);
+ 			break;
+ 
+ 		default:
+@@ -384,12 +398,15 @@ int wilc_wlan_cfg_init(struct wilc *wl)
+ 	/* store the string cfg parameters */
+ 	wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
+ 	wl->cfg.s[i].str = str_vals->firmware_version;
++	wl->cfg.s[i].len = sizeof(str_vals->firmware_version);
+ 	i++;
+ 	wl->cfg.s[i].id = WID_MAC_ADDR;
+ 	wl->cfg.s[i].str = str_vals->mac_address;
++	wl->cfg.s[i].len = sizeof(str_vals->mac_address);
+ 	i++;
+ 	wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
+ 	wl->cfg.s[i].str = str_vals->assoc_rsp;
++	wl->cfg.s[i].len = sizeof(str_vals->assoc_rsp);
+ 	i++;
+ 	wl->cfg.s[i].id = WID_NIL;
+ 	wl->cfg.s[i].str = NULL;
+diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
+index 7038b74f8e8ff6..5ae74bced7d748 100644
+--- a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
++++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.h
+@@ -24,12 +24,13 @@ struct wilc_cfg_word {
+ 
+ struct wilc_cfg_str {
+ 	u16 id;
++	u16 len;
+ 	u8 *str;
+ };
+ 
+ struct wilc_cfg_str_vals {
+-	u8 mac_address[7];
+-	u8 firmware_version[129];
++	u8 mac_address[8];
++	u8 firmware_version[130];
+ 	u8 assoc_rsp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
+ };
+ 
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 895fb163d48e6a..5395623d2ba6aa 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -903,6 +903,15 @@ static void nvme_set_ref_tag(struct nvme_ns *ns, struct nvme_command *cmnd,
+ 	u32 upper, lower;
+ 	u64 ref48;
+ 
++	/* only type1 and type 2 PI formats have a reftag */
++	switch (ns->head->pi_type) {
++	case NVME_NS_DPS_PI_TYPE1:
++	case NVME_NS_DPS_PI_TYPE2:
++		break;
++	default:
++		return;
++	}
++
+ 	/* both rw and write zeroes share the same reftag format */
+ 	switch (ns->head->guard_type) {
+ 	case NVME_NVM_NS_16B_GUARD:
+@@ -942,13 +951,7 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,
+ 
+ 	if (nvme_ns_has_pi(ns->head)) {
+ 		cmnd->write_zeroes.control |= cpu_to_le16(NVME_RW_PRINFO_PRACT);
+-
+-		switch (ns->head->pi_type) {
+-		case NVME_NS_DPS_PI_TYPE1:
+-		case NVME_NS_DPS_PI_TYPE2:
+-			nvme_set_ref_tag(ns, cmnd, req);
+-			break;
+-		}
++		nvme_set_ref_tag(ns, cmnd, req);
+ 	}
+ 
+ 	return BLK_STS_OK;
+@@ -1039,6 +1042,7 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
+ 			if (WARN_ON_ONCE(!nvme_ns_has_pi(ns->head)))
+ 				return BLK_STS_NOTSUPP;
+ 			control |= NVME_RW_PRINFO_PRACT;
++			nvme_set_ref_tag(ns, cmnd, req);
+ 		}
+ 
+ 		if (bio_integrity_flagged(req->bio, BIP_CHECK_GUARD))
+diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
+index 441cdf83f5a449..d6f24c7d156227 100644
+--- a/drivers/pcmcia/omap_cf.c
++++ b/drivers/pcmcia/omap_cf.c
+@@ -304,7 +304,13 @@ static void __exit omap_cf_remove(struct platform_device *pdev)
+ 	kfree(cf);
+ }
+ 
+-static struct platform_driver omap_cf_driver = {
++/*
++ * omap_cf_remove() lives in .exit.text. For drivers registered via
++ * platform_driver_probe() this is ok because they cannot get unbound at
++ * runtime. So mark the driver struct with __refdata to prevent modpost
++ * triggering a section mismatch warning.
++ */
++static struct platform_driver omap_cf_driver __refdata = {
+ 	.driver = {
+ 		.name	= driver_name,
+ 	},
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index e6726be5890e7f..ce177c37994140 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -147,7 +147,12 @@ static struct quirk_entry quirk_asus_ignore_fan = {
+ };
+ 
+ static struct quirk_entry quirk_asus_zenbook_duo_kbd = {
+-	.ignore_key_wlan = true,
++	.key_wlan_event = ASUS_WMI_KEY_IGNORE,
++};
++
++static struct quirk_entry quirk_asus_z13 = {
++	.key_wlan_event = ASUS_WMI_KEY_ARMOURY,
++	.tablet_switch_mode = asus_wmi_kbd_dock_devid,
+ };
+ 
+ static int dmi_matched(const struct dmi_system_id *dmi)
+@@ -539,6 +544,15 @@ static const struct dmi_system_id asus_quirks[] = {
+ 		},
+ 		.driver_data = &quirk_asus_zenbook_duo_kbd,
+ 	},
++	{
++		.callback = dmi_matched,
++		.ident = "ASUS ROG Z13",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow Z13"),
++		},
++		.driver_data = &quirk_asus_z13,
++	},
+ 	{},
+ };
+ 
+@@ -636,6 +650,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ 	{ KE_IGNORE, 0xCF, },	/* AC mode */
+ 	{ KE_KEY, 0xFA, { KEY_PROG2 } },           /* Lid flip action */
+ 	{ KE_KEY, 0xBD, { KEY_PROG2 } },           /* Lid flip action on ROG xflow laptops */
++	{ KE_KEY, ASUS_WMI_KEY_ARMOURY, { KEY_PROG3 } },
+ 	{ KE_END, 0},
+ };
+ 
+@@ -655,9 +670,11 @@ static void asus_nb_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code,
+ 		if (atkbd_reports_vol_keys)
+ 			*code = ASUS_WMI_KEY_IGNORE;
+ 		break;
+-	case 0x5F: /* Wireless console Disable */
+-		if (quirks->ignore_key_wlan)
+-			*code = ASUS_WMI_KEY_IGNORE;
++	case 0x5D: /* Wireless console Toggle */
++	case 0x5E: /* Wireless console Enable / Keyboard Attach, Detach */
++	case 0x5F: /* Wireless console Disable / Special Key */
++		if (quirks->key_wlan_event)
++			*code = quirks->key_wlan_event;
+ 		break;
+ 	}
+ }
+diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
+index 018dfde4025e79..5cd4392b964eb8 100644
+--- a/drivers/platform/x86/asus-wmi.h
++++ b/drivers/platform/x86/asus-wmi.h
+@@ -18,6 +18,7 @@
+ #include <linux/i8042.h>
+ 
+ #define ASUS_WMI_KEY_IGNORE (-1)
++#define ASUS_WMI_KEY_ARMOURY	0xffff01
+ #define ASUS_WMI_BRN_DOWN	0x2e
+ #define ASUS_WMI_BRN_UP		0x2f
+ 
+@@ -40,7 +41,7 @@ struct quirk_entry {
+ 	bool wmi_force_als_set;
+ 	bool wmi_ignore_fan;
+ 	bool filter_i8042_e1_extended_codes;
+-	bool ignore_key_wlan;
++	int key_wlan_event;
+ 	enum asus_wmi_tablet_switch_mode tablet_switch_mode;
+ 	int wapf;
+ 	/*
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 93dcebbe114175..ad2d9ecf32a5ae 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1919,8 +1919,8 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+ 	bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
+ 
+ 	cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
+-	if ((cache.flags & 0xff) == 0xff)
+-		cache.flags = -1; /* read error */
++	if (di->chip == BQ27000 && (cache.flags & 0xff) == 0xff)
++		cache.flags = -ENODEV; /* bq27000 hdq read error */
+ 	if (cache.flags >= 0) {
+ 		cache.capacity = bq27xxx_battery_read_soc(di);
+ 
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 8c597fa605233a..41e4b3d4f2b581 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1843,7 +1843,6 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans,
+ 
+ int btrfs_fill_inode(struct btrfs_inode *inode, u32 *rdev)
+ {
+-	struct btrfs_fs_info *fs_info = inode->root->fs_info;
+ 	struct btrfs_delayed_node *delayed_node;
+ 	struct btrfs_inode_item *inode_item;
+ 	struct inode *vfs_inode = &inode->vfs_inode;
+@@ -1864,8 +1863,6 @@ int btrfs_fill_inode(struct btrfs_inode *inode, u32 *rdev)
+ 	i_uid_write(vfs_inode, btrfs_stack_inode_uid(inode_item));
+ 	i_gid_write(vfs_inode, btrfs_stack_inode_gid(inode_item));
+ 	btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item));
+-	btrfs_inode_set_file_extent_range(inode, 0,
+-			round_up(i_size_read(vfs_inode), fs_info->sectorsize));
+ 	vfs_inode->i_mode = btrfs_stack_inode_mode(inode_item);
+ 	set_nlink(vfs_inode, btrfs_stack_inode_nlink(inode_item));
+ 	inode_set_bytes(vfs_inode, btrfs_stack_inode_nbytes(inode_item));
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index e266a229484852..eb73025d4e4abb 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3881,10 +3881,6 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path
+ 	bool filled = false;
+ 	int first_xattr_slot;
+ 
+-	ret = btrfs_init_file_extent_tree(inode);
+-	if (ret)
+-		goto out;
+-
+ 	ret = btrfs_fill_inode(inode, &rdev);
+ 	if (!ret)
+ 		filled = true;
+@@ -3916,8 +3912,6 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path
+ 	i_uid_write(vfs_inode, btrfs_inode_uid(leaf, inode_item));
+ 	i_gid_write(vfs_inode, btrfs_inode_gid(leaf, inode_item));
+ 	btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
+-	btrfs_inode_set_file_extent_range(inode, 0,
+-			round_up(i_size_read(vfs_inode), fs_info->sectorsize));
+ 
+ 	inode_set_atime(vfs_inode, btrfs_timespec_sec(leaf, &inode_item->atime),
+ 			btrfs_timespec_nsec(leaf, &inode_item->atime));
+@@ -3948,6 +3942,11 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path
+ 	btrfs_update_inode_mapping_flags(inode);
+ 
+ cache_index:
++	ret = btrfs_init_file_extent_tree(inode);
++	if (ret)
++		goto out;
++	btrfs_inode_set_file_extent_range(inode, 0,
++			round_up(i_size_read(vfs_inode), fs_info->sectorsize));
+ 	/*
+ 	 * If we were modified in the current generation and evicted from memory
+ 	 * and then re-read we need to do a full sync since we don't have any
+diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
+index 8f4703b488b71d..b59d01b976ff1d 100644
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -1756,10 +1756,10 @@ static int check_inode_ref(struct extent_buffer *leaf,
+ 	while (ptr < end) {
+ 		u16 namelen;
+ 
+-		if (unlikely(ptr + sizeof(iref) > end)) {
++		if (unlikely(ptr + sizeof(*iref) > end)) {
+ 			inode_ref_err(leaf, slot,
+ 			"inode ref overflow, ptr %lu end %lu inode_ref_size %zu",
+-				ptr, end, sizeof(iref));
++				ptr, end, sizeof(*iref));
+ 			return -EUCLEAN;
+ 		}
+ 
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 56d30ec0f52fca..5466a93a28f58f 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -1933,7 +1933,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
+ 
+ 	search_key.objectid = log_key.objectid;
+ 	search_key.type = BTRFS_INODE_EXTREF_KEY;
+-	search_key.offset = key->objectid;
++	search_key.offset = btrfs_extref_hash(key->objectid, name.name, name.len);
+ 	ret = backref_in_log(root->log_root, &search_key, key->objectid, &name);
+ 	if (ret < 0) {
+ 		goto out;
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index d7a1193332d941..60937127a0bc63 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -2577,9 +2577,9 @@ void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info)
+ 			spin_lock(&space_info->lock);
+ 			space_info->total_bytes -= bg->length;
+ 			space_info->disk_total -= bg->length * factor;
++			space_info->disk_total -= bg->zone_unusable;
+ 			/* There is no allocation ever happened. */
+ 			ASSERT(bg->used == 0);
+-			ASSERT(bg->zone_unusable == 0);
+ 			/* No super block in a block group on the zoned setup. */
+ 			ASSERT(bg->bytes_super == 0);
+ 			spin_unlock(&space_info->lock);
+diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c
+index 14868a3dd592ca..bc52afbfc5c739 100644
+--- a/fs/nilfs2/sysfs.c
++++ b/fs/nilfs2/sysfs.c
+@@ -1075,7 +1075,7 @@ void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs)
+  ************************************************************************/
+ 
+ static ssize_t nilfs_feature_revision_show(struct kobject *kobj,
+-					    struct attribute *attr, char *buf)
++					    struct kobj_attribute *attr, char *buf)
+ {
+ 	return sysfs_emit(buf, "%d.%d\n",
+ 			NILFS_CURRENT_REV, NILFS_MINOR_REV);
+@@ -1087,7 +1087,7 @@ static const char features_readme_str[] =
+ 	"(1) revision\n\tshow current revision of NILFS file system driver.\n";
+ 
+ static ssize_t nilfs_feature_README_show(struct kobject *kobj,
+-					 struct attribute *attr,
++					 struct kobj_attribute *attr,
+ 					 char *buf)
+ {
+ 	return sysfs_emit(buf, features_readme_str);
+diff --git a/fs/nilfs2/sysfs.h b/fs/nilfs2/sysfs.h
+index 78a87a016928b7..d370cd5cce3f5d 100644
+--- a/fs/nilfs2/sysfs.h
++++ b/fs/nilfs2/sysfs.h
+@@ -50,16 +50,16 @@ struct nilfs_sysfs_dev_subgroups {
+ 	struct completion sg_segments_kobj_unregister;
+ };
+ 
+-#define NILFS_COMMON_ATTR_STRUCT(name) \
++#define NILFS_KOBJ_ATTR_STRUCT(name) \
+ struct nilfs_##name##_attr { \
+ 	struct attribute attr; \
+-	ssize_t (*show)(struct kobject *, struct attribute *, \
++	ssize_t (*show)(struct kobject *, struct kobj_attribute *, \
+ 			char *); \
+-	ssize_t (*store)(struct kobject *, struct attribute *, \
++	ssize_t (*store)(struct kobject *, struct kobj_attribute *, \
+ 			 const char *, size_t); \
+ }
+ 
+-NILFS_COMMON_ATTR_STRUCT(feature);
++NILFS_KOBJ_ATTR_STRUCT(feature);
+ 
+ #define NILFS_DEV_ATTR_STRUCT(name) \
+ struct nilfs_##name##_attr { \
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index 045227ed4efc96..0dcea9acca5442 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -297,8 +297,8 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
+ 
+ extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
+ 
+-extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
+-				const char *path);
++void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
++					   struct dentry *dentry);
+ 
+ extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
+ 				const char *path);
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index 11d442e8b3d622..0f0d2dae6283ad 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -1984,7 +1984,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
+ 	}
+ 
+ 	netfs_wait_for_outstanding_io(inode);
+-	cifs_close_deferred_file_under_dentry(tcon, full_path);
++	cifs_close_deferred_file_under_dentry(tcon, dentry);
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+ 	if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+ 				le64_to_cpu(tcon->fsUnixInfo.Capability))) {
+@@ -2003,8 +2003,21 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
+ 		goto psx_del_no_retry;
+ 	}
+ 
+-	if (sillyrename || (server->vals->protocol_id > SMB10_PROT_ID &&
+-			    d_is_positive(dentry) && d_count(dentry) > 2))
++	/* For SMB2+, if the file is open, we always perform a silly rename.
++	 *
++	 * We check for d_count() right after calling
++	 * cifs_close_deferred_file_under_dentry() to make sure that the
++	 * dentry's refcount gets dropped in case the file had any deferred
++	 * close.
++	 */
++	if (!sillyrename && server->vals->protocol_id > SMB10_PROT_ID) {
++		spin_lock(&dentry->d_lock);
++		if (d_count(dentry) > 1)
++			sillyrename = true;
++		spin_unlock(&dentry->d_lock);
++	}
++
++	if (sillyrename)
+ 		rc = -EBUSY;
+ 	else
+ 		rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);
+@@ -2538,10 +2551,10 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
+ 		goto cifs_rename_exit;
+ 	}
+ 
+-	cifs_close_deferred_file_under_dentry(tcon, from_name);
++	cifs_close_deferred_file_under_dentry(tcon, source_dentry);
+ 	if (d_inode(target_dentry) != NULL) {
+ 		netfs_wait_for_outstanding_io(d_inode(target_dentry));
+-		cifs_close_deferred_file_under_dentry(tcon, to_name);
++		cifs_close_deferred_file_under_dentry(tcon, target_dentry);
+ 	}
+ 
+ 	rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
+diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
+index da23cc12a52caa..dda6dece802ad2 100644
+--- a/fs/smb/client/misc.c
++++ b/fs/smb/client/misc.c
+@@ -832,33 +832,28 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
+ 		kfree(tmp_list);
+ 	}
+ }
+-void
+-cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
++
++void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
++					   struct dentry *dentry)
+ {
+-	struct cifsFileInfo *cfile;
+ 	struct file_list *tmp_list, *tmp_next_list;
+-	void *page;
+-	const char *full_path;
++	struct cifsFileInfo *cfile;
+ 	LIST_HEAD(file_head);
+ 
+-	page = alloc_dentry_path();
+ 	spin_lock(&tcon->open_file_lock);
+ 	list_for_each_entry(cfile, &tcon->openFileList, tlist) {
+-		full_path = build_path_from_dentry(cfile->dentry, page);
+-		if (strstr(full_path, path)) {
+-			if (delayed_work_pending(&cfile->deferred)) {
+-				if (cancel_delayed_work(&cfile->deferred)) {
+-					spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+-					cifs_del_deferred_close(cfile);
+-					spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
+-
+-					tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
+-					if (tmp_list == NULL)
+-						break;
+-					tmp_list->cfile = cfile;
+-					list_add_tail(&tmp_list->list, &file_head);
+-				}
+-			}
++		if ((cfile->dentry == dentry) &&
++		    delayed_work_pending(&cfile->deferred) &&
++		    cancel_delayed_work(&cfile->deferred)) {
++			spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
++			cifs_del_deferred_close(cfile);
++			spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
++
++			tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
++			if (tmp_list == NULL)
++				break;
++			tmp_list->cfile = cfile;
++			list_add_tail(&tmp_list->list, &file_head);
+ 		}
+ 	}
+ 	spin_unlock(&tcon->open_file_lock);
+@@ -868,7 +863,6 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
+ 		list_del(&tmp_list->list);
+ 		kfree(tmp_list);
+ 	}
+-	free_dentry_path(page);
+ }
+ 
+ /*
+diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
+index b9bb531717a651..6dd2a1c66df3db 100644
+--- a/fs/smb/client/smbdirect.c
++++ b/fs/smb/client/smbdirect.c
+@@ -13,23 +13,23 @@
+ #include "cifsproto.h"
+ #include "smb2proto.h"
+ 
+-static struct smbd_response *get_receive_buffer(
++static struct smbdirect_recv_io *get_receive_buffer(
+ 		struct smbd_connection *info);
+ static void put_receive_buffer(
+ 		struct smbd_connection *info,
+-		struct smbd_response *response);
++		struct smbdirect_recv_io *response);
+ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf);
+ static void destroy_receive_buffers(struct smbd_connection *info);
+ 
+ static void enqueue_reassembly(
+ 		struct smbd_connection *info,
+-		struct smbd_response *response, int data_length);
+-static struct smbd_response *_get_first_reassembly(
++		struct smbdirect_recv_io *response, int data_length);
++static struct smbdirect_recv_io *_get_first_reassembly(
+ 		struct smbd_connection *info);
+ 
+ static int smbd_post_recv(
+ 		struct smbd_connection *info,
+-		struct smbd_response *response);
++		struct smbdirect_recv_io *response);
+ 
+ static int smbd_post_send_empty(struct smbd_connection *info);
+ 
+@@ -260,7 +260,7 @@ static inline void *smbd_request_payload(struct smbd_request *request)
+ 	return (void *)request->packet;
+ }
+ 
+-static inline void *smbd_response_payload(struct smbd_response *response)
++static inline void *smbdirect_recv_io_payload(struct smbdirect_recv_io *response)
+ {
+ 	return (void *)response->packet;
+ }
+@@ -315,12 +315,13 @@ static void dump_smbdirect_negotiate_resp(struct smbdirect_negotiate_resp *resp)
+  * return value: true if negotiation is a success, false if failed
+  */
+ static bool process_negotiation_response(
+-		struct smbd_response *response, int packet_length)
++		struct smbdirect_recv_io *response, int packet_length)
+ {
+-	struct smbd_connection *info = response->info;
+-	struct smbdirect_socket *sc = &info->socket;
++	struct smbdirect_socket *sc = response->socket;
++	struct smbd_connection *info =
++		container_of(sc, struct smbd_connection, socket);
+ 	struct smbdirect_socket_parameters *sp = &sc->parameters;
+-	struct smbdirect_negotiate_resp *packet = smbd_response_payload(response);
++	struct smbdirect_negotiate_resp *packet = smbdirect_recv_io_payload(response);
+ 
+ 	if (packet_length < sizeof(struct smbdirect_negotiate_resp)) {
+ 		log_rdma_event(ERR,
+@@ -383,6 +384,7 @@ static bool process_negotiation_response(
+ 			info->max_frmr_depth * PAGE_SIZE);
+ 	info->max_frmr_depth = sp->max_read_write_size / PAGE_SIZE;
+ 
++	sc->recv_io.expected = SMBDIRECT_EXPECT_DATA_TRANSFER;
+ 	return true;
+ }
+ 
+@@ -390,7 +392,7 @@ static void smbd_post_send_credits(struct work_struct *work)
+ {
+ 	int ret = 0;
+ 	int rc;
+-	struct smbd_response *response;
++	struct smbdirect_recv_io *response;
+ 	struct smbd_connection *info =
+ 		container_of(work, struct smbd_connection,
+ 			post_send_credits_work);
+@@ -408,7 +410,6 @@ static void smbd_post_send_credits(struct work_struct *work)
+ 			if (!response)
+ 				break;
+ 
+-			response->type = SMBD_TRANSFER_DATA;
+ 			response->first_segment = false;
+ 			rc = smbd_post_recv(info, response);
+ 			if (rc) {
+@@ -442,13 +443,18 @@ static void smbd_post_send_credits(struct work_struct *work)
+ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+ 	struct smbdirect_data_transfer *data_transfer;
+-	struct smbd_response *response =
+-		container_of(wc->wr_cqe, struct smbd_response, cqe);
+-	struct smbd_connection *info = response->info;
+-	int data_length = 0;
++	struct smbdirect_recv_io *response =
++		container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe);
++	struct smbdirect_socket *sc = response->socket;
++	struct smbdirect_socket_parameters *sp = &sc->parameters;
++	struct smbd_connection *info =
++		container_of(sc, struct smbd_connection, socket);
++	u32 data_offset = 0;
++	u32 data_length = 0;
++	u32 remaining_data_length = 0;
+ 
+ 	log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n",
+-		      response, response->type, wc->status, wc->opcode,
++		      response, sc->recv_io.expected, wc->status, wc->opcode,
+ 		      wc->byte_len, wc->pkey_index);
+ 
+ 	if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
+@@ -463,10 +469,10 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ 		response->sge.length,
+ 		DMA_FROM_DEVICE);
+ 
+-	switch (response->type) {
++	switch (sc->recv_io.expected) {
+ 	/* SMBD negotiation response */
+-	case SMBD_NEGOTIATE_RESP:
+-		dump_smbdirect_negotiate_resp(smbd_response_payload(response));
++	case SMBDIRECT_EXPECT_NEGOTIATE_REP:
++		dump_smbdirect_negotiate_resp(smbdirect_recv_io_payload(response));
+ 		info->full_packet_received = true;
+ 		info->negotiate_done =
+ 			process_negotiation_response(response, wc->byte_len);
+@@ -475,9 +481,24 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ 		return;
+ 
+ 	/* SMBD data transfer packet */
+-	case SMBD_TRANSFER_DATA:
+-		data_transfer = smbd_response_payload(response);
++	case SMBDIRECT_EXPECT_DATA_TRANSFER:
++		data_transfer = smbdirect_recv_io_payload(response);
++
++		if (wc->byte_len <
++		    offsetof(struct smbdirect_data_transfer, padding))
++			goto error;
++
++		remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length);
++		data_offset = le32_to_cpu(data_transfer->data_offset);
+ 		data_length = le32_to_cpu(data_transfer->data_length);
++		if (wc->byte_len < data_offset ||
++		    (u64)wc->byte_len < (u64)data_offset + data_length)
++			goto error;
++
++		if (remaining_data_length > sp->max_fragmented_recv_size ||
++		    data_length > sp->max_fragmented_recv_size ||
++		    (u64)remaining_data_length + (u64)data_length > (u64)sp->max_fragmented_recv_size)
++			goto error;
+ 
+ 		if (data_length) {
+ 			if (info->full_packet_received)
+@@ -526,13 +547,17 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ 			put_receive_buffer(info, response);
+ 
+ 		return;
++
++	case SMBDIRECT_EXPECT_NEGOTIATE_REQ:
++		/* Only server... */
++		break;
+ 	}
+ 
+ 	/*
+ 	 * This is an internal error!
+ 	 */
+-	log_rdma_recv(ERR, "unexpected response type=%d\n", response->type);
+-	WARN_ON_ONCE(response->type != SMBD_TRANSFER_DATA);
++	log_rdma_recv(ERR, "unexpected response type=%d\n", sc->recv_io.expected);
++	WARN_ON_ONCE(sc->recv_io.expected != SMBDIRECT_EXPECT_DATA_TRANSFER);
+ error:
+ 	put_receive_buffer(info, response);
+ 	smbd_disconnect_rdma_connection(info);
+@@ -1029,7 +1054,7 @@ static int smbd_post_send_full_iter(struct smbd_connection *info,
+  * The interaction is controlled by send/receive credit system
+  */
+ static int smbd_post_recv(
+-		struct smbd_connection *info, struct smbd_response *response)
++		struct smbd_connection *info, struct smbdirect_recv_io *response)
+ {
+ 	struct smbdirect_socket *sc = &info->socket;
+ 	struct smbdirect_socket_parameters *sp = &sc->parameters;
+@@ -1067,16 +1092,19 @@ static int smbd_post_recv(
+ /* Perform SMBD negotiate according to [MS-SMBD] 3.1.5.2 */
+ static int smbd_negotiate(struct smbd_connection *info)
+ {
++	struct smbdirect_socket *sc = &info->socket;
+ 	int rc;
+-	struct smbd_response *response = get_receive_buffer(info);
++	struct smbdirect_recv_io *response = get_receive_buffer(info);
+ 
+-	response->type = SMBD_NEGOTIATE_RESP;
++	sc->recv_io.expected = SMBDIRECT_EXPECT_NEGOTIATE_REP;
+ 	rc = smbd_post_recv(info, response);
+ 	log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=0x%llx iov.length=%u iov.lkey=0x%x\n",
+ 		       rc, response->sge.addr,
+ 		       response->sge.length, response->sge.lkey);
+-	if (rc)
++	if (rc) {
++		put_receive_buffer(info, response);
+ 		return rc;
++	}
+ 
+ 	init_completion(&info->negotiate_completion);
+ 	info->negotiate_done = false;
+@@ -1113,7 +1141,7 @@ static int smbd_negotiate(struct smbd_connection *info)
+  */
+ static void enqueue_reassembly(
+ 	struct smbd_connection *info,
+-	struct smbd_response *response,
++	struct smbdirect_recv_io *response,
+ 	int data_length)
+ {
+ 	spin_lock(&info->reassembly_queue_lock);
+@@ -1137,14 +1165,14 @@ static void enqueue_reassembly(
+  * Caller is responsible for locking
+  * return value: the first entry if any, NULL if queue is empty
+  */
+-static struct smbd_response *_get_first_reassembly(struct smbd_connection *info)
++static struct smbdirect_recv_io *_get_first_reassembly(struct smbd_connection *info)
+ {
+-	struct smbd_response *ret = NULL;
++	struct smbdirect_recv_io *ret = NULL;
+ 
+ 	if (!list_empty(&info->reassembly_queue)) {
+ 		ret = list_first_entry(
+ 			&info->reassembly_queue,
+-			struct smbd_response, list);
++			struct smbdirect_recv_io, list);
+ 	}
+ 	return ret;
+ }
+@@ -1155,16 +1183,16 @@ static struct smbd_response *_get_first_reassembly(struct smbd_connection *info)
+  * pre-allocated in advance.
+  * return value: the receive buffer, NULL if none is available
+  */
+-static struct smbd_response *get_receive_buffer(struct smbd_connection *info)
++static struct smbdirect_recv_io *get_receive_buffer(struct smbd_connection *info)
+ {
+-	struct smbd_response *ret = NULL;
++	struct smbdirect_recv_io *ret = NULL;
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&info->receive_queue_lock, flags);
+ 	if (!list_empty(&info->receive_queue)) {
+ 		ret = list_first_entry(
+ 			&info->receive_queue,
+-			struct smbd_response, list);
++			struct smbdirect_recv_io, list);
+ 		list_del(&ret->list);
+ 		info->count_receive_queue--;
+ 		info->count_get_receive_buffer++;
+@@ -1181,7 +1209,7 @@ static struct smbd_response *get_receive_buffer(struct smbd_connection *info)
+  * receive buffer is returned.
+  */
+ static void put_receive_buffer(
+-	struct smbd_connection *info, struct smbd_response *response)
++	struct smbd_connection *info, struct smbdirect_recv_io *response)
+ {
+ 	struct smbdirect_socket *sc = &info->socket;
+ 	unsigned long flags;
+@@ -1206,8 +1234,9 @@ static void put_receive_buffer(
+ /* Preallocate all receive buffer on transport establishment */
+ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
+ {
++	struct smbdirect_socket *sc = &info->socket;
++	struct smbdirect_recv_io *response;
+ 	int i;
+-	struct smbd_response *response;
+ 
+ 	INIT_LIST_HEAD(&info->reassembly_queue);
+ 	spin_lock_init(&info->reassembly_queue_lock);
+@@ -1225,7 +1254,7 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
+ 		if (!response)
+ 			goto allocate_failed;
+ 
+-		response->info = info;
++		response->socket = sc;
+ 		response->sge.length = 0;
+ 		list_add_tail(&response->list, &info->receive_queue);
+ 		info->count_receive_queue++;
+@@ -1237,7 +1266,7 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
+ 	while (!list_empty(&info->receive_queue)) {
+ 		response = list_first_entry(
+ 				&info->receive_queue,
+-				struct smbd_response, list);
++				struct smbdirect_recv_io, list);
+ 		list_del(&response->list);
+ 		info->count_receive_queue--;
+ 
+@@ -1248,7 +1277,7 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf)
+ 
+ static void destroy_receive_buffers(struct smbd_connection *info)
+ {
+-	struct smbd_response *response;
++	struct smbdirect_recv_io *response;
+ 
+ 	while ((response = get_receive_buffer(info)))
+ 		mempool_free(response, info->response_mempool);
+@@ -1289,7 +1318,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
+ 	struct smbd_connection *info = server->smbd_conn;
+ 	struct smbdirect_socket *sc;
+ 	struct smbdirect_socket_parameters *sp;
+-	struct smbd_response *response;
++	struct smbdirect_recv_io *response;
+ 	unsigned long flags;
+ 
+ 	if (!info) {
+@@ -1308,13 +1337,16 @@ void smbd_destroy(struct TCP_Server_Info *server)
+ 			sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
+ 	}
+ 
++	log_rdma_event(INFO, "cancelling post_send_credits_work\n");
++	disable_work_sync(&info->post_send_credits_work);
++
+ 	log_rdma_event(INFO, "destroying qp\n");
+ 	ib_drain_qp(sc->ib.qp);
+ 	rdma_destroy_qp(sc->rdma.cm_id);
+ 	sc->ib.qp = NULL;
+ 
+ 	log_rdma_event(INFO, "cancelling idle timer\n");
+-	cancel_delayed_work_sync(&info->idle_timer_work);
++	disable_delayed_work_sync(&info->idle_timer_work);
+ 
+ 	/* It's not possible for upper layer to get to reassembly */
+ 	log_rdma_event(INFO, "drain the reassembly queue\n");
+@@ -1446,17 +1478,17 @@ static int allocate_caches_and_workqueue(struct smbd_connection *info)
+ 	if (!info->request_mempool)
+ 		goto out1;
+ 
+-	scnprintf(name, MAX_NAME_LEN, "smbd_response_%p", info);
++	scnprintf(name, MAX_NAME_LEN, "smbdirect_recv_io_%p", info);
+ 
+ 	struct kmem_cache_args response_args = {
+-		.align		= __alignof__(struct smbd_response),
+-		.useroffset	= (offsetof(struct smbd_response, packet) +
++		.align		= __alignof__(struct smbdirect_recv_io),
++		.useroffset	= (offsetof(struct smbdirect_recv_io, packet) +
+ 				   sizeof(struct smbdirect_data_transfer)),
+ 		.usersize	= sp->max_recv_size - sizeof(struct smbdirect_data_transfer),
+ 	};
+ 	info->response_cache =
+ 		kmem_cache_create(name,
+-				  sizeof(struct smbd_response) + sp->max_recv_size,
++				  sizeof(struct smbdirect_recv_io) + sp->max_recv_size,
+ 				  &response_args, SLAB_HWCACHE_ALIGN);
+ 	if (!info->response_cache)
+ 		goto out2;
+@@ -1686,7 +1718,7 @@ static struct smbd_connection *_smbd_get_connection(
+ 	return NULL;
+ 
+ negotiation_failed:
+-	cancel_delayed_work_sync(&info->idle_timer_work);
++	disable_delayed_work_sync(&info->idle_timer_work);
+ 	destroy_caches_and_workqueue(info);
+ 	sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
+ 	rdma_disconnect(sc->rdma.cm_id);
+@@ -1747,7 +1779,7 @@ struct smbd_connection *smbd_get_connection(
+ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
+ {
+ 	struct smbdirect_socket *sc = &info->socket;
+-	struct smbd_response *response;
++	struct smbdirect_recv_io *response;
+ 	struct smbdirect_data_transfer *data_transfer;
+ 	size_t size = iov_iter_count(&msg->msg_iter);
+ 	int to_copy, to_read, data_read, offset;
+@@ -1783,7 +1815,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
+ 		offset = info->first_entry_offset;
+ 		while (data_read < size) {
+ 			response = _get_first_reassembly(info);
+-			data_transfer = smbd_response_payload(response);
++			data_transfer = smbdirect_recv_io_payload(response);
+ 			data_length = le32_to_cpu(data_transfer->data_length);
+ 			remaining_data_length =
+ 				le32_to_cpu(
+@@ -2045,7 +2077,7 @@ static void destroy_mr_list(struct smbd_connection *info)
+ 	struct smbdirect_socket *sc = &info->socket;
+ 	struct smbd_mr *mr, *tmp;
+ 
+-	cancel_work_sync(&info->mr_recovery_work);
++	disable_work_sync(&info->mr_recovery_work);
+ 	list_for_each_entry_safe(mr, tmp, &info->mr_list, list) {
+ 		if (mr->state == MR_INVALIDATED)
+ 			ib_dma_unmap_sg(sc->ib.dev, mr->sgt.sgl,
+diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h
+index ea04ce8a9763a6..d60e445da22563 100644
+--- a/fs/smb/client/smbdirect.h
++++ b/fs/smb/client/smbdirect.h
+@@ -157,11 +157,6 @@ struct smbd_connection {
+ 	unsigned int count_send_empty;
+ };
+ 
+-enum smbd_message_type {
+-	SMBD_NEGOTIATE_RESP,
+-	SMBD_TRANSFER_DATA,
+-};
+-
+ /* Maximum number of SGEs used by smbdirect.c in any send work request */
+ #define SMBDIRECT_MAX_SEND_SGE	6
+ 
+@@ -181,24 +176,6 @@ struct smbd_request {
+ /* Maximum number of SGEs used by smbdirect.c in any receive work request */
+ #define SMBDIRECT_MAX_RECV_SGE	1
+ 
+-/* The context for a SMBD response */
+-struct smbd_response {
+-	struct smbd_connection *info;
+-	struct ib_cqe cqe;
+-	struct ib_sge sge;
+-
+-	enum smbd_message_type type;
+-
+-	/* Link to receive queue or reassembly queue */
+-	struct list_head list;
+-
+-	/* Indicate if this is the 1st packet of a payload */
+-	bool first_segment;
+-
+-	/* SMBD packet header and payload follows this structure */
+-	u8 packet[];
+-};
+-
+ /* Create a SMBDirect session */
+ struct smbd_connection *smbd_get_connection(
+ 	struct TCP_Server_Info *server, struct sockaddr *dstaddr);
+diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h
+index e5b15cc44a7ba5..a7ad31c471a7b6 100644
+--- a/fs/smb/common/smbdirect/smbdirect_socket.h
++++ b/fs/smb/common/smbdirect/smbdirect_socket.h
+@@ -38,6 +38,35 @@ struct smbdirect_socket {
+ 	} ib;
+ 
+ 	struct smbdirect_socket_parameters parameters;
++
++	/*
++	 * The state for posted receive buffers
++	 */
++	struct {
++		/*
++		 * The type of PDU we are expecting
++		 */
++		enum {
++			SMBDIRECT_EXPECT_NEGOTIATE_REQ = 1,
++			SMBDIRECT_EXPECT_NEGOTIATE_REP = 2,
++			SMBDIRECT_EXPECT_DATA_TRANSFER = 3,
++		} expected;
++	} recv_io;
++};
++
++struct smbdirect_recv_io {
++	struct smbdirect_socket *socket;
++	struct ib_cqe cqe;
++	struct ib_sge sge;
++
++	/* Link to free or reassembly list */
++	struct list_head list;
++
++	/* Indicate if this is the 1st packet of a payload */
++	bool first_segment;
++
++	/* SMBD packet header and payload follows this structure */
++	u8 packet[];
+ };
+ 
+ #endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */
+diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
+index 5466aa8c39b1cd..6550bd9f002c27 100644
+--- a/fs/smb/server/transport_rdma.c
++++ b/fs/smb/server/transport_rdma.c
+@@ -554,7 +554,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ 	case SMB_DIRECT_MSG_DATA_TRANSFER: {
+ 		struct smb_direct_data_transfer *data_transfer =
+ 			(struct smb_direct_data_transfer *)recvmsg->packet;
+-		unsigned int data_length;
++		u32 remaining_data_length, data_offset, data_length;
+ 		int avail_recvmsg_count, receive_credits;
+ 
+ 		if (wc->byte_len <
+@@ -564,15 +564,25 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
+ 			return;
+ 		}
+ 
++		remaining_data_length = le32_to_cpu(data_transfer->remaining_data_length);
+ 		data_length = le32_to_cpu(data_transfer->data_length);
+-		if (data_length) {
+-			if (wc->byte_len < sizeof(struct smb_direct_data_transfer) +
+-			    (u64)data_length) {
+-				put_recvmsg(t, recvmsg);
+-				smb_direct_disconnect_rdma_connection(t);
+-				return;
+-			}
++		data_offset = le32_to_cpu(data_transfer->data_offset);
++		if (wc->byte_len < data_offset ||
++		    wc->byte_len < (u64)data_offset + data_length) {
++			put_recvmsg(t, recvmsg);
++			smb_direct_disconnect_rdma_connection(t);
++			return;
++		}
++		if (remaining_data_length > t->max_fragmented_recv_size ||
++		    data_length > t->max_fragmented_recv_size ||
++		    (u64)remaining_data_length + (u64)data_length >
++		    (u64)t->max_fragmented_recv_size) {
++			put_recvmsg(t, recvmsg);
++			smb_direct_disconnect_rdma_connection(t);
++			return;
++		}
+ 
++		if (data_length) {
+ 			if (t->full_packet_received)
+ 				recvmsg->first_segment = true;
+ 
+@@ -1209,78 +1219,130 @@ static int smb_direct_writev(struct ksmbd_transport *t,
+ 			     bool need_invalidate, unsigned int remote_key)
+ {
+ 	struct smb_direct_transport *st = smb_trans_direct_transfort(t);
+-	int remaining_data_length;
+-	int start, i, j;
+-	int max_iov_size = st->max_send_size -
++	size_t remaining_data_length;
++	size_t iov_idx;
++	size_t iov_ofs;
++	size_t max_iov_size = st->max_send_size -
+ 			sizeof(struct smb_direct_data_transfer);
+ 	int ret;
+-	struct kvec vec;
+ 	struct smb_direct_send_ctx send_ctx;
++	int error = 0;
+ 
+ 	if (st->status != SMB_DIRECT_CS_CONNECTED)
+ 		return -ENOTCONN;
+ 
+ 	//FIXME: skip RFC1002 header..
++	if (WARN_ON_ONCE(niovs <= 1 || iov[0].iov_len != 4))
++		return -EINVAL;
+ 	buflen -= 4;
++	iov_idx = 1;
++	iov_ofs = 0;
+ 
+ 	remaining_data_length = buflen;
+ 	ksmbd_debug(RDMA, "Sending smb (RDMA): smb_len=%u\n", buflen);
+ 
+ 	smb_direct_send_ctx_init(st, &send_ctx, need_invalidate, remote_key);
+-	start = i = 1;
+-	buflen = 0;
+-	while (true) {
+-		buflen += iov[i].iov_len;
+-		if (buflen > max_iov_size) {
+-			if (i > start) {
+-				remaining_data_length -=
+-					(buflen - iov[i].iov_len);
+-				ret = smb_direct_post_send_data(st, &send_ctx,
+-								&iov[start], i - start,
+-								remaining_data_length);
+-				if (ret)
++	while (remaining_data_length) {
++		struct kvec vecs[SMB_DIRECT_MAX_SEND_SGES - 1]; /* minus smbdirect hdr */
++		size_t possible_bytes = max_iov_size;
++		size_t possible_vecs;
++		size_t bytes = 0;
++		size_t nvecs = 0;
++
++		/*
++		 * For the last message remaining_data_length should be
++		 * have been 0 already!
++		 */
++		if (WARN_ON_ONCE(iov_idx >= niovs)) {
++			error = -EINVAL;
++			goto done;
++		}
++
++		/*
++		 * We have 2 factors which limit the arguments we pass
++		 * to smb_direct_post_send_data():
++		 *
++		 * 1. The number of supported sges for the send,
++		 *    while one is reserved for the smbdirect header.
++		 *    And we currently need one SGE per page.
++		 * 2. The number of negotiated payload bytes per send.
++		 */
++		possible_vecs = min_t(size_t, ARRAY_SIZE(vecs), niovs - iov_idx);
++
++		while (iov_idx < niovs && possible_vecs && possible_bytes) {
++			struct kvec *v = &vecs[nvecs];
++			int page_count;
++
++			v->iov_base = ((u8 *)iov[iov_idx].iov_base) + iov_ofs;
++			v->iov_len = min_t(size_t,
++					   iov[iov_idx].iov_len - iov_ofs,
++					   possible_bytes);
++			page_count = get_buf_page_count(v->iov_base, v->iov_len);
++			if (page_count > possible_vecs) {
++				/*
++				 * If the number of pages in the buffer
++				 * is to much (because we currently require
++				 * one SGE per page), we need to limit the
++				 * length.
++				 *
++				 * We know possible_vecs is at least 1,
++				 * so we always keep the first page.
++				 *
++				 * We need to calculate the number extra
++				 * pages (epages) we can also keep.
++				 *
++				 * We calculate the number of bytes in the
++				 * first page (fplen), this should never be
++				 * larger than v->iov_len because page_count is
++				 * at least 2, but adding a limitation feels
++				 * better.
++				 *
++				 * Then we calculate the number of bytes (elen)
++				 * we can keep for the extra pages.
++				 */
++				size_t epages = possible_vecs - 1;
++				size_t fpofs = offset_in_page(v->iov_base);
++				size_t fplen = min_t(size_t, PAGE_SIZE - fpofs, v->iov_len);
++				size_t elen = min_t(size_t, v->iov_len - fplen, epages*PAGE_SIZE);
++
++				v->iov_len = fplen + elen;
++				page_count = get_buf_page_count(v->iov_base, v->iov_len);
++				if (WARN_ON_ONCE(page_count > possible_vecs)) {
++					/*
++					 * Something went wrong in the above
++					 * logic...
++					 */
++					error = -EINVAL;
+ 					goto done;
+-			} else {
+-				/* iov[start] is too big, break it */
+-				int nvec  = (buflen + max_iov_size - 1) /
+-						max_iov_size;
+-
+-				for (j = 0; j < nvec; j++) {
+-					vec.iov_base =
+-						(char *)iov[start].iov_base +
+-						j * max_iov_size;
+-					vec.iov_len =
+-						min_t(int, max_iov_size,
+-						      buflen - max_iov_size * j);
+-					remaining_data_length -= vec.iov_len;
+-					ret = smb_direct_post_send_data(st, &send_ctx, &vec, 1,
+-									remaining_data_length);
+-					if (ret)
+-						goto done;
+ 				}
+-				i++;
+-				if (i == niovs)
+-					break;
+ 			}
+-			start = i;
+-			buflen = 0;
+-		} else {
+-			i++;
+-			if (i == niovs) {
+-				/* send out all remaining vecs */
+-				remaining_data_length -= buflen;
+-				ret = smb_direct_post_send_data(st, &send_ctx,
+-								&iov[start], i - start,
+-								remaining_data_length);
+-				if (ret)
+-					goto done;
+-				break;
++			possible_vecs -= page_count;
++			nvecs += 1;
++			possible_bytes -= v->iov_len;
++			bytes += v->iov_len;
++
++			iov_ofs += v->iov_len;
++			if (iov_ofs >= iov[iov_idx].iov_len) {
++				iov_idx += 1;
++				iov_ofs = 0;
+ 			}
+ 		}
++
++		remaining_data_length -= bytes;
++
++		ret = smb_direct_post_send_data(st, &send_ctx,
++						vecs, nvecs,
++						remaining_data_length);
++		if (unlikely(ret)) {
++			error = ret;
++			goto done;
++		}
+ 	}
+ 
+ done:
+ 	ret = smb_direct_flush_send_list(st, &send_ctx, true);
++	if (unlikely(!ret && error))
++		ret = error;
+ 
+ 	/*
+ 	 * As an optimization, we don't wait for individual I/O to finish
+@@ -1744,6 +1806,11 @@ static int smb_direct_init_params(struct smb_direct_transport *t,
+ 		return -EINVAL;
+ 	}
+ 
++	if (device->attrs.max_send_sge < SMB_DIRECT_MAX_SEND_SGES) {
++		pr_err("warning: device max_send_sge = %d too small\n",
++		       device->attrs.max_send_sge);
++		return -EINVAL;
++	}
+ 	if (device->attrs.max_recv_sge < SMB_DIRECT_MAX_RECV_SGES) {
+ 		pr_err("warning: device max_recv_sge = %d too small\n",
+ 		       device->attrs.max_recv_sge);
+@@ -1767,7 +1834,7 @@ static int smb_direct_init_params(struct smb_direct_transport *t,
+ 
+ 	cap->max_send_wr = max_send_wrs;
+ 	cap->max_recv_wr = t->recv_credit_max;
+-	cap->max_send_sge = max_sge_per_wr;
++	cap->max_send_sge = SMB_DIRECT_MAX_SEND_SGES;
+ 	cap->max_recv_sge = SMB_DIRECT_MAX_RECV_SGES;
+ 	cap->max_inline_data = 0;
+ 	cap->max_rdma_ctxs = t->max_rw_credits;
+diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
+index f7b3b93f3a49a7..0c70f3a5557505 100644
+--- a/include/crypto/if_alg.h
++++ b/include/crypto/if_alg.h
+@@ -135,6 +135,7 @@ struct af_alg_async_req {
+  *			SG?
+  * @enc:		Cryptographic operation to be performed when
+  *			recvmsg is invoked.
++ * @write:		True if we are in the middle of a write.
+  * @init:		True if metadata has been sent.
+  * @len:		Length of memory allocated for this data structure.
+  * @inflight:		Non-zero when AIO requests are in flight.
+@@ -151,10 +152,11 @@ struct af_alg_ctx {
+ 	size_t used;
+ 	atomic_t rcvused;
+ 
+-	bool more;
+-	bool merge;
+-	bool enc;
+-	bool init;
++	u32		more:1,
++			merge:1,
++			enc:1,
++			write:1,
++			init:1;
+ 
+ 	unsigned int len;
+ 
+diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
+index a7efcec2e3d081..215ff20affa33f 100644
+--- a/include/linux/io_uring_types.h
++++ b/include/linux/io_uring_types.h
+@@ -418,9 +418,6 @@ struct io_ring_ctx {
+ 	struct list_head		defer_list;
+ 	unsigned			nr_drained;
+ 
+-	struct io_alloc_cache		msg_cache;
+-	spinlock_t			msg_lock;
+-
+ #ifdef CONFIG_NET_RX_BUSY_POLL
+ 	struct list_head	napi_list;	/* track busy poll napi_id */
+ 	spinlock_t		napi_lock;	/* napi_list lock */
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index e6ba8f4f4bd1f4..27850ebb651b30 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -662,6 +662,7 @@ struct mlx5e_resources {
+ 		bool			   tisn_valid;
+ 	} hw_objs;
+ 	struct net_device *uplink_netdev;
++	netdevice_tracker tracker;
+ 	struct mutex uplink_netdev_lock;
+ 	struct mlx5_crypto_dek_priv *dek_priv;
+ };
+diff --git a/include/linux/swap.h b/include/linux/swap.h
+index bc0e1c275fc047..8b56b2bbaa4f07 100644
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -384,6 +384,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
+ void mark_page_accessed(struct page *);
+ void folio_mark_accessed(struct folio *);
+ 
++static inline bool folio_may_be_lru_cached(struct folio *folio)
++{
++	/*
++	 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
++	 * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
++	 * will be sensible, but nobody has implemented and tested that yet.
++	 */
++	return !folio_test_large(folio);
++}
++
+ extern atomic_t lru_disable_count;
+ 
+ static inline bool lru_cache_disabled(void)
+diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
+index 4160731dcb6e3a..1fc2fb03ce3f9a 100644
+--- a/include/net/dst_metadata.h
++++ b/include/net/dst_metadata.h
+@@ -3,6 +3,7 @@
+ #define __NET_DST_METADATA_H 1
+ 
+ #include <linux/skbuff.h>
++#include <net/ip.h>
+ #include <net/ip_tunnels.h>
+ #include <net/macsec.h>
+ #include <net/dst.h>
+@@ -220,9 +221,15 @@ static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
+ 						 int md_size)
+ {
+ 	const struct iphdr *iph = ip_hdr(skb);
++	struct metadata_dst *tun_dst;
++
++	tun_dst = __ip_tun_set_dst(iph->saddr, iph->daddr, iph->tos, iph->ttl,
++				   0, flags, tunnel_id, md_size);
+ 
+-	return __ip_tun_set_dst(iph->saddr, iph->daddr, iph->tos, iph->ttl,
+-				0, flags, tunnel_id, md_size);
++	if (tun_dst && (iph->frag_off & htons(IP_DF)))
++		__set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT,
++			  tun_dst->u.tun_info.key.tun_flags);
++	return tun_dst;
+ }
+ 
+ static inline struct metadata_dst *__ipv6_tun_set_dst(const struct in6_addr *saddr,
+diff --git a/include/net/sock.h b/include/net/sock.h
+index a348ae145eda43..6e9f4c126672d0 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2061,6 +2061,9 @@ static inline void sk_set_socket(struct sock *sk, struct socket *sock)
+ 	if (sock) {
+ 		WRITE_ONCE(sk->sk_uid, SOCK_INODE(sock)->i_uid);
+ 		WRITE_ONCE(sk->sk_ino, SOCK_INODE(sock)->i_ino);
++	} else {
++		/* Note: sk_uid is unchanged. */
++		WRITE_ONCE(sk->sk_ino, 0);
+ 	}
+ }
+ 
+@@ -2082,8 +2085,6 @@ static inline void sock_orphan(struct sock *sk)
+ 	sock_set_flag(sk, SOCK_DEAD);
+ 	sk_set_socket(sk, NULL);
+ 	sk->sk_wq  = NULL;
+-	/* Note: sk_uid is unchanged. */
+-	WRITE_ONCE(sk->sk_ino, 0);
+ 	write_unlock_bh(&sk->sk_callback_lock);
+ }
+ 
+diff --git a/include/sound/sdca.h b/include/sound/sdca.h
+index 5a5d6de78d7283..9c6a351c9d474f 100644
+--- a/include/sound/sdca.h
++++ b/include/sound/sdca.h
+@@ -46,6 +46,7 @@ struct sdca_device_data {
+ 
+ enum sdca_quirk {
+ 	SDCA_QUIRKS_RT712_VB,
++	SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
+ };
+ 
+ #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
+diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h
+index 67d015df8893cc..5fd5b4cf75ca1e 100644
+--- a/include/uapi/linux/mptcp.h
++++ b/include/uapi/linux/mptcp.h
+@@ -31,6 +31,8 @@
+ #define MPTCP_INFO_FLAG_FALLBACK		_BITUL(0)
+ #define MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED	_BITUL(1)
+ 
++#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0		_BITUL(0)
++
+ #define MPTCP_PM_ADDR_FLAG_SIGNAL                      (1 << 0)
+ #define MPTCP_PM_ADDR_FLAG_SUBFLOW                     (1 << 1)
+ #define MPTCP_PM_ADDR_FLAG_BACKUP                      (1 << 2)
+diff --git a/include/uapi/linux/mptcp_pm.h b/include/uapi/linux/mptcp_pm.h
+index 6ac84b2f636ca2..7359d34da446b9 100644
+--- a/include/uapi/linux/mptcp_pm.h
++++ b/include/uapi/linux/mptcp_pm.h
+@@ -16,10 +16,10 @@
+  *   good time to allocate memory and send ADD_ADDR if needed. Depending on the
+  *   traffic-patterns it can take a long time until the MPTCP_EVENT_ESTABLISHED
+  *   is sent. Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6,
+- *   sport, dport, server-side.
++ *   sport, dport, server-side, [flags].
+  * @MPTCP_EVENT_ESTABLISHED: A MPTCP connection is established (can start new
+  *   subflows). Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6,
+- *   sport, dport, server-side.
++ *   sport, dport, server-side, [flags].
+  * @MPTCP_EVENT_CLOSED: A MPTCP connection has stopped. Attribute: token.
+  * @MPTCP_EVENT_ANNOUNCED: A new address has been announced by the peer.
+  *   Attributes: token, rem_id, family, daddr4 | daddr6 [, dport].
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index 17dfaa0395c46b..1d03b2fc4b2594 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -352,16 +352,16 @@ static void create_worker_cb(struct callback_head *cb)
+ 	struct io_wq *wq;
+ 
+ 	struct io_wq_acct *acct;
+-	bool do_create = false;
++	bool activated_free_worker, do_create = false;
+ 
+ 	worker = container_of(cb, struct io_worker, create_work);
+ 	wq = worker->wq;
+ 	acct = worker->acct;
+ 
+ 	rcu_read_lock();
+-	do_create = !io_acct_activate_free_worker(acct);
++	activated_free_worker = io_acct_activate_free_worker(acct);
+ 	rcu_read_unlock();
+-	if (!do_create)
++	if (activated_free_worker)
+ 		goto no_need_create;
+ 
+ 	raw_spin_lock(&acct->workers_lock);
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 5111ec040c5342..eaa5410e5a70a1 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -290,7 +290,6 @@ static void io_free_alloc_caches(struct io_ring_ctx *ctx)
+ 	io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
+ 	io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free);
+ 	io_alloc_cache_free(&ctx->cmd_cache, io_cmd_cache_free);
+-	io_alloc_cache_free(&ctx->msg_cache, kfree);
+ 	io_futex_cache_free(ctx);
+ 	io_rsrc_cache_free(ctx);
+ }
+@@ -337,9 +336,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
+ 	ret |= io_alloc_cache_init(&ctx->cmd_cache, IO_ALLOC_CACHE_MAX,
+ 			    sizeof(struct io_async_cmd),
+ 			    sizeof(struct io_async_cmd));
+-	spin_lock_init(&ctx->msg_lock);
+-	ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX,
+-			    sizeof(struct io_kiocb), 0);
+ 	ret |= io_futex_cache_init(ctx);
+ 	ret |= io_rsrc_cache_init(ctx);
+ 	if (ret)
+@@ -1371,8 +1367,10 @@ static void io_req_task_cancel(struct io_kiocb *req, io_tw_token_t tw)
+ 
+ void io_req_task_submit(struct io_kiocb *req, io_tw_token_t tw)
+ {
+-	io_tw_lock(req->ctx, tw);
+-	if (unlikely(io_should_terminate_tw()))
++	struct io_ring_ctx *ctx = req->ctx;
++
++	io_tw_lock(ctx, tw);
++	if (unlikely(io_should_terminate_tw(ctx)))
+ 		io_req_defer_failed(req, -EFAULT);
+ 	else if (req->flags & REQ_F_FORCE_ASYNC)
+ 		io_queue_iowq(req);
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 66c1ca73f55ee5..336689752d9fe1 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -470,9 +470,9 @@ static inline bool io_allowed_run_tw(struct io_ring_ctx *ctx)
+  * 2) PF_KTHREAD is set, in which case the invoker of the task_work is
+  *    our fallback task_work.
+  */
+-static inline bool io_should_terminate_tw(void)
++static inline bool io_should_terminate_tw(struct io_ring_ctx *ctx)
+ {
+-	return current->flags & (PF_KTHREAD | PF_EXITING);
++	return (current->flags & (PF_KTHREAD | PF_EXITING)) || percpu_ref_is_dying(&ctx->refs);
+ }
+ 
+ static inline void io_req_queue_tw_complete(struct io_kiocb *req, s32 res)
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 4c2578f2efcb0e..5e5b94236d7204 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -11,7 +11,6 @@
+ #include "io_uring.h"
+ #include "rsrc.h"
+ #include "filetable.h"
+-#include "alloc_cache.h"
+ #include "msg_ring.h"
+ 
+ /* All valid masks for MSG_RING */
+@@ -76,13 +75,7 @@ static void io_msg_tw_complete(struct io_kiocb *req, io_tw_token_t tw)
+ 	struct io_ring_ctx *ctx = req->ctx;
+ 
+ 	io_add_aux_cqe(ctx, req->cqe.user_data, req->cqe.res, req->cqe.flags);
+-	if (spin_trylock(&ctx->msg_lock)) {
+-		if (io_alloc_cache_put(&ctx->msg_cache, req))
+-			req = NULL;
+-		spin_unlock(&ctx->msg_lock);
+-	}
+-	if (req)
+-		kfree_rcu(req, rcu_head);
++	kfree_rcu(req, rcu_head);
+ 	percpu_ref_put(&ctx->refs);
+ }
+ 
+@@ -104,26 +97,13 @@ static int io_msg_remote_post(struct io_ring_ctx *ctx, struct io_kiocb *req,
+ 	return 0;
+ }
+ 
+-static struct io_kiocb *io_msg_get_kiocb(struct io_ring_ctx *ctx)
+-{
+-	struct io_kiocb *req = NULL;
+-
+-	if (spin_trylock(&ctx->msg_lock)) {
+-		req = io_alloc_cache_get(&ctx->msg_cache);
+-		spin_unlock(&ctx->msg_lock);
+-		if (req)
+-			return req;
+-	}
+-	return kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
+-}
+-
+ static int io_msg_data_remote(struct io_ring_ctx *target_ctx,
+ 			      struct io_msg *msg)
+ {
+ 	struct io_kiocb *target;
+ 	u32 flags = 0;
+ 
+-	target = io_msg_get_kiocb(target_ctx);
++	target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO)  ;
+ 	if (unlikely(!target))
+ 		return -ENOMEM;
+ 
+diff --git a/io_uring/notif.c b/io_uring/notif.c
+index 9a6f6e92d74242..ea9c0116cec2df 100644
+--- a/io_uring/notif.c
++++ b/io_uring/notif.c
+@@ -85,7 +85,7 @@ static int io_link_skb(struct sk_buff *skb, struct ubuf_info *uarg)
+ 		return -EEXIST;
+ 
+ 	prev_nd = container_of(prev_uarg, struct io_notif_data, uarg);
+-	prev_notif = cmd_to_io_kiocb(nd);
++	prev_notif = cmd_to_io_kiocb(prev_nd);
+ 
+ 	/* make sure all noifications can be finished in the same task_work */
+ 	if (unlikely(notif->ctx != prev_notif->ctx ||
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index 20e9b46a4adfd5..1b79c268725d47 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -224,7 +224,7 @@ static int io_poll_check_events(struct io_kiocb *req, io_tw_token_t tw)
+ {
+ 	int v;
+ 
+-	if (unlikely(io_should_terminate_tw()))
++	if (unlikely(io_should_terminate_tw(req->ctx)))
+ 		return -ECANCELED;
+ 
+ 	do {
+diff --git a/io_uring/timeout.c b/io_uring/timeout.c
+index 7f13bfa9f2b617..17e3aab0af3676 100644
+--- a/io_uring/timeout.c
++++ b/io_uring/timeout.c
+@@ -324,7 +324,7 @@ static void io_req_task_link_timeout(struct io_kiocb *req, io_tw_token_t tw)
+ 	int ret;
+ 
+ 	if (prev) {
+-		if (!io_should_terminate_tw()) {
++		if (!io_should_terminate_tw(req->ctx)) {
+ 			struct io_cancel_data cd = {
+ 				.ctx		= req->ctx,
+ 				.data		= prev->cqe.user_data,
+diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
+index 929cad6ee32628..b2b4f62c90ce80 100644
+--- a/io_uring/uring_cmd.c
++++ b/io_uring/uring_cmd.c
+@@ -123,7 +123,7 @@ static void io_uring_cmd_work(struct io_kiocb *req, io_tw_token_t tw)
+ 	struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
+ 	unsigned int flags = IO_URING_F_COMPLETE_DEFER;
+ 
+-	if (io_should_terminate_tw())
++	if (io_should_terminate_tw(req->ctx))
+ 		flags |= IO_URING_F_TASK_DEAD;
+ 
+ 	/* task_work executor checks the deffered list completion */
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index a723b7dc6e4e28..20f76b21765016 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -126,8 +126,31 @@ DEFINE_PERCPU_RWSEM(cgroup_threadgroup_rwsem);
+  * of concurrent destructions.  Use a separate workqueue so that cgroup
+  * destruction work items don't end up filling up max_active of system_wq
+  * which may lead to deadlock.
++ *
++ * A cgroup destruction should enqueue work sequentially to:
++ * cgroup_offline_wq: use for css offline work
++ * cgroup_release_wq: use for css release work
++ * cgroup_free_wq: use for free work
++ *
++ * Rationale for using separate workqueues:
++ * The cgroup root free work may depend on completion of other css offline
++ * operations. If all tasks were enqueued to a single workqueue, this could
++ * create a deadlock scenario where:
++ * - Free work waits for other css offline work to complete.
++ * - But other css offline work is queued after free work in the same queue.
++ *
++ * Example deadlock scenario with single workqueue (cgroup_destroy_wq):
++ * 1. umount net_prio
++ * 2. net_prio root destruction enqueues work to cgroup_destroy_wq (CPUx)
++ * 3. perf_event CSS A offline enqueues work to same cgroup_destroy_wq (CPUx)
++ * 4. net_prio cgroup_destroy_root->cgroup_lock_and_drain_offline.
++ * 5. net_prio root destruction blocks waiting for perf_event CSS A offline,
++ *    which can never complete as it's behind in the same queue and
++ *    workqueue's max_active is 1.
+  */
+-static struct workqueue_struct *cgroup_destroy_wq;
++static struct workqueue_struct *cgroup_offline_wq;
++static struct workqueue_struct *cgroup_release_wq;
++static struct workqueue_struct *cgroup_free_wq;
+ 
+ /* generate an array of cgroup subsystem pointers */
+ #define SUBSYS(_x) [_x ## _cgrp_id] = &_x ## _cgrp_subsys,
+@@ -5553,7 +5576,7 @@ static void css_release_work_fn(struct work_struct *work)
+ 	cgroup_unlock();
+ 
+ 	INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
+-	queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
++	queue_rcu_work(cgroup_free_wq, &css->destroy_rwork);
+ }
+ 
+ static void css_release(struct percpu_ref *ref)
+@@ -5562,7 +5585,7 @@ static void css_release(struct percpu_ref *ref)
+ 		container_of(ref, struct cgroup_subsys_state, refcnt);
+ 
+ 	INIT_WORK(&css->destroy_work, css_release_work_fn);
+-	queue_work(cgroup_destroy_wq, &css->destroy_work);
++	queue_work(cgroup_release_wq, &css->destroy_work);
+ }
+ 
+ static void init_and_link_css(struct cgroup_subsys_state *css,
+@@ -5696,7 +5719,7 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
+ 	list_del_rcu(&css->sibling);
+ err_free_css:
+ 	INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
+-	queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
++	queue_rcu_work(cgroup_free_wq, &css->destroy_rwork);
+ 	return ERR_PTR(err);
+ }
+ 
+@@ -5934,7 +5957,7 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
+ 
+ 	if (atomic_dec_and_test(&css->online_cnt)) {
+ 		INIT_WORK(&css->destroy_work, css_killed_work_fn);
+-		queue_work(cgroup_destroy_wq, &css->destroy_work);
++		queue_work(cgroup_offline_wq, &css->destroy_work);
+ 	}
+ }
+ 
+@@ -6320,8 +6343,14 @@ static int __init cgroup_wq_init(void)
+ 	 * We would prefer to do this in cgroup_init() above, but that
+ 	 * is called before init_workqueues(): so leave this until after.
+ 	 */
+-	cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
+-	BUG_ON(!cgroup_destroy_wq);
++	cgroup_offline_wq = alloc_workqueue("cgroup_offline", 0, 1);
++	BUG_ON(!cgroup_offline_wq);
++
++	cgroup_release_wq = alloc_workqueue("cgroup_release", 0, 1);
++	BUG_ON(!cgroup_release_wq);
++
++	cgroup_free_wq = alloc_workqueue("cgroup_free", 0, 1);
++	BUG_ON(!cgroup_free_wq);
+ 	return 0;
+ }
+ core_initcall(cgroup_wq_init);
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index 717e3d1d6a2fa2..f3a97005713db7 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -6794,12 +6794,8 @@ __bpf_kfunc u32 scx_bpf_reenqueue_local(void)
+ 		 * CPUs disagree, they use %ENQUEUE_RESTORE which is bypassed to
+ 		 * the current local DSQ for running tasks and thus are not
+ 		 * visible to the BPF scheduler.
+-		 *
+-		 * Also skip re-enqueueing tasks that can only run on this
+-		 * CPU, as they would just be re-added to the same local
+-		 * DSQ without any benefit.
+ 		 */
+-		if (p->migration_pending || is_migration_disabled(p) || p->nr_cpus_allowed == 1)
++		if (p->migration_pending)
+ 			continue;
+ 
+ 		dispatch_dequeue(rq, p);
+diff --git a/mm/gup.c b/mm/gup.c
+index 3c39cbbeebef1f..10e46ff0904b05 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -2300,6 +2300,31 @@ static void pofs_unpin(struct pages_or_folios *pofs)
+ 		unpin_user_pages(pofs->pages, pofs->nr_entries);
+ }
+ 
++static struct folio *pofs_next_folio(struct folio *folio,
++		struct pages_or_folios *pofs, long *index_ptr)
++{
++	long i = *index_ptr + 1;
++
++	if (!pofs->has_folios && folio_test_large(folio)) {
++		const unsigned long start_pfn = folio_pfn(folio);
++		const unsigned long end_pfn = start_pfn + folio_nr_pages(folio);
++
++		for (; i < pofs->nr_entries; i++) {
++			unsigned long pfn = page_to_pfn(pofs->pages[i]);
++
++			/* Is this page part of this folio? */
++			if (pfn < start_pfn || pfn >= end_pfn)
++				break;
++		}
++	}
++
++	if (unlikely(i == pofs->nr_entries))
++		return NULL;
++	*index_ptr = i;
++
++	return pofs_get_folio(pofs, i);
++}
++
+ /*
+  * Returns the number of collected folios. Return value is always >= 0.
+  */
+@@ -2307,16 +2332,13 @@ static unsigned long collect_longterm_unpinnable_folios(
+ 		struct list_head *movable_folio_list,
+ 		struct pages_or_folios *pofs)
+ {
+-	unsigned long i, collected = 0;
+-	struct folio *prev_folio = NULL;
+-	bool drain_allow = true;
+-
+-	for (i = 0; i < pofs->nr_entries; i++) {
+-		struct folio *folio = pofs_get_folio(pofs, i);
++	unsigned long collected = 0;
++	struct folio *folio;
++	int drained = 0;
++	long i = 0;
+ 
+-		if (folio == prev_folio)
+-			continue;
+-		prev_folio = folio;
++	for (folio = pofs_get_folio(pofs, i); folio;
++	     folio = pofs_next_folio(folio, pofs, &i)) {
+ 
+ 		if (folio_is_longterm_pinnable(folio))
+ 			continue;
+@@ -2331,9 +2353,17 @@ static unsigned long collect_longterm_unpinnable_folios(
+ 			continue;
+ 		}
+ 
+-		if (!folio_test_lru(folio) && drain_allow) {
++		if (drained == 0 && folio_may_be_lru_cached(folio) &&
++				folio_ref_count(folio) !=
++				folio_expected_ref_count(folio) + 1) {
++			lru_add_drain();
++			drained = 1;
++		}
++		if (drained == 1 && folio_may_be_lru_cached(folio) &&
++				folio_ref_count(folio) !=
++				folio_expected_ref_count(folio) + 1) {
+ 			lru_add_drain_all();
+-			drain_allow = false;
++			drained = 2;
+ 		}
+ 
+ 		if (!folio_isolate_lru(folio))
+diff --git a/mm/mlock.c b/mm/mlock.c
+index 3cb72b579ffd33..2f454ed6e51041 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -255,7 +255,7 @@ void mlock_folio(struct folio *folio)
+ 
+ 	folio_get(folio);
+ 	if (!folio_batch_add(fbatch, mlock_lru(folio)) ||
+-	    folio_test_large(folio) || lru_cache_disabled())
++	    !folio_may_be_lru_cached(folio) || lru_cache_disabled())
+ 		mlock_folio_batch(fbatch);
+ 	local_unlock(&mlock_fbatch.lock);
+ }
+@@ -278,7 +278,7 @@ void mlock_new_folio(struct folio *folio)
+ 
+ 	folio_get(folio);
+ 	if (!folio_batch_add(fbatch, mlock_new(folio)) ||
+-	    folio_test_large(folio) || lru_cache_disabled())
++	    !folio_may_be_lru_cached(folio) || lru_cache_disabled())
+ 		mlock_folio_batch(fbatch);
+ 	local_unlock(&mlock_fbatch.lock);
+ }
+@@ -299,7 +299,7 @@ void munlock_folio(struct folio *folio)
+ 	 */
+ 	folio_get(folio);
+ 	if (!folio_batch_add(fbatch, folio) ||
+-	    folio_test_large(folio) || lru_cache_disabled())
++	    !folio_may_be_lru_cached(folio) || lru_cache_disabled())
+ 		mlock_folio_batch(fbatch);
+ 	local_unlock(&mlock_fbatch.lock);
+ }
+diff --git a/mm/swap.c b/mm/swap.c
+index 4fc322f7111a98..a524736323c8b7 100644
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -164,6 +164,10 @@ static void folio_batch_move_lru(struct folio_batch *fbatch, move_fn_t move_fn)
+ 	for (i = 0; i < folio_batch_count(fbatch); i++) {
+ 		struct folio *folio = fbatch->folios[i];
+ 
++		/* block memcg migration while the folio moves between lru */
++		if (move_fn != lru_add && !folio_test_clear_lru(folio))
++			continue;
++
+ 		folio_lruvec_relock_irqsave(folio, &lruvec, &flags);
+ 		move_fn(lruvec, folio);
+ 
+@@ -176,14 +180,10 @@ static void folio_batch_move_lru(struct folio_batch *fbatch, move_fn_t move_fn)
+ }
+ 
+ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,
+-		struct folio *folio, move_fn_t move_fn,
+-		bool on_lru, bool disable_irq)
++		struct folio *folio, move_fn_t move_fn, bool disable_irq)
+ {
+ 	unsigned long flags;
+ 
+-	if (on_lru && !folio_test_clear_lru(folio))
+-		return;
+-
+ 	folio_get(folio);
+ 
+ 	if (disable_irq)
+@@ -191,8 +191,8 @@ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,
+ 	else
+ 		local_lock(&cpu_fbatches.lock);
+ 
+-	if (!folio_batch_add(this_cpu_ptr(fbatch), folio) || folio_test_large(folio) ||
+-	    lru_cache_disabled())
++	if (!folio_batch_add(this_cpu_ptr(fbatch), folio) ||
++			!folio_may_be_lru_cached(folio) || lru_cache_disabled())
+ 		folio_batch_move_lru(this_cpu_ptr(fbatch), move_fn);
+ 
+ 	if (disable_irq)
+@@ -201,13 +201,13 @@ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,
+ 		local_unlock(&cpu_fbatches.lock);
+ }
+ 
+-#define folio_batch_add_and_move(folio, op, on_lru)						\
+-	__folio_batch_add_and_move(								\
+-		&cpu_fbatches.op,								\
+-		folio,										\
+-		op,										\
+-		on_lru,										\
+-		offsetof(struct cpu_fbatches, op) >= offsetof(struct cpu_fbatches, lock_irq)	\
++#define folio_batch_add_and_move(folio, op)		\
++	__folio_batch_add_and_move(			\
++		&cpu_fbatches.op,			\
++		folio,					\
++		op,					\
++		offsetof(struct cpu_fbatches, op) >=	\
++		offsetof(struct cpu_fbatches, lock_irq)	\
+ 	)
+ 
+ static void lru_move_tail(struct lruvec *lruvec, struct folio *folio)
+@@ -231,10 +231,10 @@ static void lru_move_tail(struct lruvec *lruvec, struct folio *folio)
+ void folio_rotate_reclaimable(struct folio *folio)
+ {
+ 	if (folio_test_locked(folio) || folio_test_dirty(folio) ||
+-	    folio_test_unevictable(folio))
++	    folio_test_unevictable(folio) || !folio_test_lru(folio))
+ 		return;
+ 
+-	folio_batch_add_and_move(folio, lru_move_tail, true);
++	folio_batch_add_and_move(folio, lru_move_tail);
+ }
+ 
+ void lru_note_cost(struct lruvec *lruvec, bool file,
+@@ -323,10 +323,11 @@ static void folio_activate_drain(int cpu)
+ 
+ void folio_activate(struct folio *folio)
+ {
+-	if (folio_test_active(folio) || folio_test_unevictable(folio))
++	if (folio_test_active(folio) || folio_test_unevictable(folio) ||
++	    !folio_test_lru(folio))
+ 		return;
+ 
+-	folio_batch_add_and_move(folio, lru_activate, true);
++	folio_batch_add_and_move(folio, lru_activate);
+ }
+ 
+ #else
+@@ -502,7 +503,7 @@ void folio_add_lru(struct folio *folio)
+ 	    lru_gen_in_fault() && !(current->flags & PF_MEMALLOC))
+ 		folio_set_active(folio);
+ 
+-	folio_batch_add_and_move(folio, lru_add, false);
++	folio_batch_add_and_move(folio, lru_add);
+ }
+ EXPORT_SYMBOL(folio_add_lru);
+ 
+@@ -680,13 +681,13 @@ void lru_add_drain_cpu(int cpu)
+ void deactivate_file_folio(struct folio *folio)
+ {
+ 	/* Deactivating an unevictable folio will not accelerate reclaim */
+-	if (folio_test_unevictable(folio))
++	if (folio_test_unevictable(folio) || !folio_test_lru(folio))
+ 		return;
+ 
+ 	if (lru_gen_enabled() && lru_gen_clear_refs(folio))
+ 		return;
+ 
+-	folio_batch_add_and_move(folio, lru_deactivate_file, true);
++	folio_batch_add_and_move(folio, lru_deactivate_file);
+ }
+ 
+ /*
+@@ -699,13 +700,13 @@ void deactivate_file_folio(struct folio *folio)
+  */
+ void folio_deactivate(struct folio *folio)
+ {
+-	if (folio_test_unevictable(folio))
++	if (folio_test_unevictable(folio) || !folio_test_lru(folio))
+ 		return;
+ 
+ 	if (lru_gen_enabled() ? lru_gen_clear_refs(folio) : !folio_test_active(folio))
+ 		return;
+ 
+-	folio_batch_add_and_move(folio, lru_deactivate, true);
++	folio_batch_add_and_move(folio, lru_deactivate);
+ }
+ 
+ /**
+@@ -718,10 +719,11 @@ void folio_deactivate(struct folio *folio)
+ void folio_mark_lazyfree(struct folio *folio)
+ {
+ 	if (!folio_test_anon(folio) || !folio_test_swapbacked(folio) ||
++	    !folio_test_lru(folio) ||
+ 	    folio_test_swapcache(folio) || folio_test_unevictable(folio))
+ 		return;
+ 
+-	folio_batch_add_and_move(folio, lru_lazyfree, true);
++	folio_batch_add_and_move(folio, lru_lazyfree);
+ }
+ 
+ void lru_add_drain(void)
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 424412680cfcc6..b7ed263e6dd701 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -4505,7 +4505,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
+ 	}
+ 
+ 	/* ineligible */
+-	if (!folio_test_lru(folio) || zone > sc->reclaim_idx) {
++	if (zone > sc->reclaim_idx) {
+ 		gen = folio_inc_gen(lruvec, folio, false);
+ 		list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]);
+ 		return true;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 461a9ab540af02..98da33e0c308b0 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3330,6 +3330,7 @@ int tcp_disconnect(struct sock *sk, int flags)
+ 	struct inet_connection_sock *icsk = inet_csk(sk);
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 	int old_state = sk->sk_state;
++	struct request_sock *req;
+ 	u32 seq;
+ 
+ 	if (old_state != TCP_CLOSE)
+@@ -3445,6 +3446,10 @@ int tcp_disconnect(struct sock *sk, int flags)
+ 
+ 
+ 	/* Clean up fastopen related fields */
++	req = rcu_dereference_protected(tp->fastopen_rsk,
++					lockdep_sock_is_held(sk));
++	if (req)
++		reqsk_fastopen_remove(sk, req, false);
+ 	tcp_free_fastopen_req(tp);
+ 	inet_clear_bit(DEFER_CONNECT, sk);
+ 	tp->fastopen_client_fail = 0;
+diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
+index bbb8d5f0eae7d3..3338b6cc85c487 100644
+--- a/net/ipv4/tcp_ao.c
++++ b/net/ipv4/tcp_ao.c
+@@ -1178,7 +1178,9 @@ void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb)
+ 	if (!ao)
+ 		return;
+ 
+-	WRITE_ONCE(ao->risn, tcp_hdr(skb)->seq);
++	/* sk with TCP_REPAIR_ON does not have skb in tcp_finish_connect */
++	if (skb)
++		WRITE_ONCE(ao->risn, tcp_hdr(skb)->seq);
+ 	ao->rcv_sne = 0;
+ 
+ 	hlist_for_each_entry_rcu(key, &ao->head, node, lockdep_sock_is_held(sk))
+diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
+index 307587c8a0037b..7964a7c5f0b2b5 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -1389,7 +1389,7 @@ drv_get_ftm_responder_stats(struct ieee80211_local *local,
+ 			    struct ieee80211_sub_if_data *sdata,
+ 			    struct cfg80211_ftm_responder_stats *ftm_stats)
+ {
+-	u32 ret = -EOPNOTSUPP;
++	int ret = -EOPNOTSUPP;
+ 
+ 	might_sleep();
+ 	lockdep_assert_wiphy(local->hw.wiphy);
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 1bad353d8a772b..35c6755b817a83 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1136,7 +1136,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 	int result, i;
+ 	enum nl80211_band band;
+ 	int channels, max_bitrates;
+-	bool supp_ht, supp_vht, supp_he, supp_eht;
++	bool supp_ht, supp_vht, supp_he, supp_eht, supp_s1g;
+ 	struct cfg80211_chan_def dflt_chandef = {};
+ 
+ 	if (ieee80211_hw_check(hw, QUEUE_CONTROL) &&
+@@ -1252,6 +1252,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 	supp_vht = false;
+ 	supp_he = false;
+ 	supp_eht = false;
++	supp_s1g = false;
+ 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
+ 		const struct ieee80211_sband_iftype_data *iftd;
+ 		struct ieee80211_supported_band *sband;
+@@ -1299,6 +1300,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 			max_bitrates = sband->n_bitrates;
+ 		supp_ht = supp_ht || sband->ht_cap.ht_supported;
+ 		supp_vht = supp_vht || sband->vht_cap.vht_supported;
++		supp_s1g = supp_s1g || sband->s1g_cap.s1g;
+ 
+ 		for_each_sband_iftype_data(sband, i, iftd) {
+ 			u8 he_40_mhz_cap;
+@@ -1432,6 +1434,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 		local->scan_ies_len +=
+ 			2 + sizeof(struct ieee80211_vht_cap);
+ 
++	if (supp_s1g)
++		local->scan_ies_len += 2 + sizeof(struct ieee80211_s1g_cap);
++
+ 	/*
+ 	 * HE cap element is variable in size - set len to allow max size */
+ 	if (supp_he) {
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index c6983471dca552..bb4253aa675a61 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -984,13 +984,13 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
+ 		return false;
+ 	}
+ 
+-	if (mp_opt->deny_join_id0)
+-		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
+-
+ 	if (unlikely(!READ_ONCE(msk->pm.server_side)))
+ 		pr_warn_once("bogus mpc option on established client sk");
+ 
+ set_fully_established:
++	if (mp_opt->deny_join_id0)
++		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
++
+ 	mptcp_data_lock((struct sock *)msk);
+ 	__mptcp_subflow_fully_established(msk, subflow, mp_opt);
+ 	mptcp_data_unlock((struct sock *)msk);
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 50aaf259959aea..ce7d42d3bd007b 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -408,6 +408,7 @@ static int mptcp_event_created(struct sk_buff *skb,
+ 			       const struct sock *ssk)
+ {
+ 	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
++	u16 flags = 0;
+ 
+ 	if (err)
+ 		return err;
+@@ -415,6 +416,12 @@ static int mptcp_event_created(struct sk_buff *skb,
+ 	if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
+ 		return -EMSGSIZE;
+ 
++	if (READ_ONCE(msk->pm.remote_deny_join_id0))
++		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
++
++	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
++		return -EMSGSIZE;
++
+ 	return mptcp_event_add_subflow(skb, ssk);
+ }
+ 
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 1063c53850c057..b895e3ecdc9b7c 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -350,6 +350,20 @@ static void mptcp_close_wake_up(struct sock *sk)
+ 		sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+ }
+ 
++static void mptcp_shutdown_subflows(struct mptcp_sock *msk)
++{
++	struct mptcp_subflow_context *subflow;
++
++	mptcp_for_each_subflow(msk, subflow) {
++		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++		bool slow;
++
++		slow = lock_sock_fast(ssk);
++		tcp_shutdown(ssk, SEND_SHUTDOWN);
++		unlock_sock_fast(ssk, slow);
++	}
++}
++
+ /* called under the msk socket lock */
+ static bool mptcp_pending_data_fin_ack(struct sock *sk)
+ {
+@@ -374,6 +388,7 @@ static void mptcp_check_data_fin_ack(struct sock *sk)
+ 			break;
+ 		case TCP_CLOSING:
+ 		case TCP_LAST_ACK:
++			mptcp_shutdown_subflows(msk);
+ 			mptcp_set_state(sk, TCP_CLOSE);
+ 			break;
+ 		}
+@@ -542,6 +557,7 @@ static bool mptcp_check_data_fin(struct sock *sk)
+ 			mptcp_set_state(sk, TCP_CLOSING);
+ 			break;
+ 		case TCP_FIN_WAIT2:
++			mptcp_shutdown_subflows(msk);
+ 			mptcp_set_state(sk, TCP_CLOSE);
+ 			break;
+ 		default:
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 1802bc5435a1aa..d77a2e374a7ae8 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -882,6 +882,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+ 
+ 			ctx->subflow_id = 1;
+ 			owner = mptcp_sk(ctx->conn);
++
++			if (mp_opt.deny_join_id0)
++				WRITE_ONCE(owner->pm.remote_deny_join_id0, true);
++
+ 			mptcp_pm_new_connection(owner, child, 1);
+ 
+ 			/* with OoO packets we can reach here without ingress
+diff --git a/net/rds/ib_frmr.c b/net/rds/ib_frmr.c
+index 28c1b00221780f..bd861191157b54 100644
+--- a/net/rds/ib_frmr.c
++++ b/net/rds/ib_frmr.c
+@@ -133,12 +133,15 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
+ 
+ 	ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_dma_len,
+ 				&off, PAGE_SIZE);
+-	if (unlikely(ret != ibmr->sg_dma_len))
+-		return ret < 0 ? ret : -EINVAL;
++	if (unlikely(ret != ibmr->sg_dma_len)) {
++		ret = ret < 0 ? ret : -EINVAL;
++		goto out_inc;
++	}
+ 
+-	if (cmpxchg(&frmr->fr_state,
+-		    FRMR_IS_FREE, FRMR_IS_INUSE) != FRMR_IS_FREE)
+-		return -EBUSY;
++	if (cmpxchg(&frmr->fr_state, FRMR_IS_FREE, FRMR_IS_INUSE) != FRMR_IS_FREE) {
++		ret = -EBUSY;
++		goto out_inc;
++	}
+ 
+ 	atomic_inc(&ibmr->ic->i_fastreg_inuse_count);
+ 
+@@ -166,11 +169,10 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
+ 		/* Failure here can be because of -ENOMEM as well */
+ 		rds_transition_frwr_state(ibmr, FRMR_IS_INUSE, FRMR_IS_STALE);
+ 
+-		atomic_inc(&ibmr->ic->i_fastreg_wrs);
+ 		if (printk_ratelimit())
+ 			pr_warn("RDS/IB: %s returned error(%d)\n",
+ 				__func__, ret);
+-		goto out;
++		goto out_inc;
+ 	}
+ 
+ 	/* Wait for the registration to complete in order to prevent an invalid
+@@ -179,8 +181,10 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr)
+ 	 */
+ 	wait_event(frmr->fr_reg_done, !frmr->fr_reg);
+ 
+-out:
++	return ret;
+ 
++out_inc:
++	atomic_inc(&ibmr->ic->i_fastreg_wrs);
+ 	return ret;
+ }
+ 
+diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
+index 41e657e977618a..cf2dcec6ce5afc 100644
+--- a/net/rfkill/rfkill-gpio.c
++++ b/net/rfkill/rfkill-gpio.c
+@@ -94,10 +94,10 @@ static const struct dmi_system_id rfkill_gpio_deny_table[] = {
+ static int rfkill_gpio_probe(struct platform_device *pdev)
+ {
+ 	struct rfkill_gpio_data *rfkill;
+-	struct gpio_desc *gpio;
++	const char *type_name = NULL;
+ 	const char *name_property;
+ 	const char *type_property;
+-	const char *type_name;
++	struct gpio_desc *gpio;
+ 	int ret;
+ 
+ 	if (dmi_check_system(rfkill_gpio_deny_table))
+diff --git a/net/rxrpc/rxgk.c b/net/rxrpc/rxgk.c
+index 1e19c605bcc829..dce5a3d8a964f8 100644
+--- a/net/rxrpc/rxgk.c
++++ b/net/rxrpc/rxgk.c
+@@ -475,7 +475,7 @@ static int rxgk_verify_packet_integrity(struct rxrpc_call *call,
+ 	struct krb5_buffer metadata;
+ 	unsigned int offset = sp->offset, len = sp->len;
+ 	size_t data_offset = 0, data_len = len;
+-	u32 ac;
++	u32 ac = 0;
+ 	int ret = -ENOMEM;
+ 
+ 	_enter("");
+@@ -499,9 +499,10 @@ static int rxgk_verify_packet_integrity(struct rxrpc_call *call,
+ 	ret = rxgk_verify_mic_skb(gk->krb5, gk->rx_Kc, &metadata,
+ 				  skb, &offset, &len, &ac);
+ 	kfree(hdr);
+-	if (ret == -EPROTO) {
+-		rxrpc_abort_eproto(call, skb, ac,
+-				   rxgk_abort_1_verify_mic_eproto);
++	if (ret < 0) {
++		if (ret != -ENOMEM)
++			rxrpc_abort_eproto(call, skb, ac,
++					   rxgk_abort_1_verify_mic_eproto);
+ 	} else {
+ 		sp->offset = offset;
+ 		sp->len = len;
+@@ -524,15 +525,16 @@ static int rxgk_verify_packet_encrypted(struct rxrpc_call *call,
+ 	struct rxgk_header hdr;
+ 	unsigned int offset = sp->offset, len = sp->len;
+ 	int ret;
+-	u32 ac;
++	u32 ac = 0;
+ 
+ 	_enter("");
+ 
+ 	ret = rxgk_decrypt_skb(gk->krb5, gk->rx_enc, skb, &offset, &len, &ac);
+-	if (ret == -EPROTO)
+-		rxrpc_abort_eproto(call, skb, ac, rxgk_abort_2_decrypt_eproto);
+-	if (ret < 0)
++	if (ret < 0) {
++		if (ret != -ENOMEM)
++			rxrpc_abort_eproto(call, skb, ac, rxgk_abort_2_decrypt_eproto);
+ 		goto error;
++	}
+ 
+ 	if (len < sizeof(hdr)) {
+ 		ret = rxrpc_abort_eproto(call, skb, RXGK_PACKETSHORT,
+diff --git a/net/rxrpc/rxgk_app.c b/net/rxrpc/rxgk_app.c
+index b94b77a1c31780..30275cb5ba3e25 100644
+--- a/net/rxrpc/rxgk_app.c
++++ b/net/rxrpc/rxgk_app.c
+@@ -54,6 +54,10 @@ int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,
+ 
+ 	_enter("");
+ 
++	if (ticket_len < 10 * sizeof(__be32))
++		return rxrpc_abort_conn(conn, skb, RXGK_INCONSISTENCY, -EPROTO,
++					rxgk_abort_resp_short_yfs_tkt);
++
+ 	/* Get the session key length */
+ 	ret = skb_copy_bits(skb, ticket_offset, tmp, sizeof(tmp));
+ 	if (ret < 0)
+@@ -187,7 +191,7 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+ 	struct key *server_key;
+ 	unsigned int ticket_offset, ticket_len;
+ 	u32 kvno, enctype;
+-	int ret, ec;
++	int ret, ec = 0;
+ 
+ 	struct {
+ 		__be32 kvno;
+@@ -195,22 +199,23 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+ 		__be32 token_len;
+ 	} container;
+ 
++	if (token_len < sizeof(container))
++		goto short_packet;
++
+ 	/* Decode the RXGK_TokenContainer object.  This tells us which server
+ 	 * key we should be using.  We can then fetch the key, get the secret
+ 	 * and set up the crypto to extract the token.
+ 	 */
+ 	if (skb_copy_bits(skb, token_offset, &container, sizeof(container)) < 0)
+-		return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
+-					rxgk_abort_resp_tok_short);
++		goto short_packet;
+ 
+ 	kvno		= ntohl(container.kvno);
+ 	enctype		= ntohl(container.enctype);
+ 	ticket_len	= ntohl(container.token_len);
+ 	ticket_offset	= token_offset + sizeof(container);
+ 
+-	if (xdr_round_up(ticket_len) > token_len - 3 * 4)
+-		return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
+-					rxgk_abort_resp_tok_short);
++	if (xdr_round_up(ticket_len) > token_len - sizeof(container))
++		goto short_packet;
+ 
+ 	_debug("KVNO %u", kvno);
+ 	_debug("ENC  %u", enctype);
+@@ -236,9 +241,11 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+ 			       &ticket_offset, &ticket_len, &ec);
+ 	crypto_free_aead(token_enc);
+ 	token_enc = NULL;
+-	if (ret < 0)
+-		return rxrpc_abort_conn(conn, skb, ec, ret,
+-					rxgk_abort_resp_tok_dec);
++	if (ret < 0) {
++		if (ret != -ENOMEM)
++			return rxrpc_abort_conn(conn, skb, ec, ret,
++						rxgk_abort_resp_tok_dec);
++	}
+ 
+ 	ret = conn->security->default_decode_ticket(conn, skb, ticket_offset,
+ 						    ticket_len, _key);
+@@ -283,4 +290,8 @@ int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
+ 	 * also come out this way if the ticket decryption fails.
+ 	 */
+ 	return ret;
++
++short_packet:
++	return rxrpc_abort_conn(conn, skb, RXGK_PACKETSHORT, -EPROTO,
++				rxgk_abort_resp_tok_short);
+ }
+diff --git a/net/rxrpc/rxgk_common.h b/net/rxrpc/rxgk_common.h
+index 7370a56559853f..80164d89e19c03 100644
+--- a/net/rxrpc/rxgk_common.h
++++ b/net/rxrpc/rxgk_common.h
+@@ -88,11 +88,16 @@ int rxgk_decrypt_skb(const struct krb5_enctype *krb5,
+ 		*_offset += offset;
+ 		*_len = len;
+ 		break;
++	case -EBADMSG: /* Checksum mismatch. */
+ 	case -EPROTO:
+-	case -EBADMSG:
+ 		*_error_code = RXGK_SEALEDINCON;
+ 		break;
++	case -EMSGSIZE:
++		*_error_code = RXGK_PACKETSHORT;
++		break;
++	case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
+ 	default:
++		*_error_code = RXGK_INCONSISTENCY;
+ 		break;
+ 	}
+ 
+@@ -127,11 +132,16 @@ int rxgk_verify_mic_skb(const struct krb5_enctype *krb5,
+ 		*_offset += offset;
+ 		*_len = len;
+ 		break;
++	case -EBADMSG: /* Checksum mismatch */
+ 	case -EPROTO:
+-	case -EBADMSG:
+ 		*_error_code = RXGK_SEALEDINCON;
+ 		break;
++	case -EMSGSIZE:
++		*_error_code = RXGK_PACKETSHORT;
++		break;
++	case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
+ 	default:
++		*_error_code = RXGK_INCONSISTENCY;
+ 		break;
+ 	}
+ 
+diff --git a/net/tls/tls.h b/net/tls/tls.h
+index 4e077068e6d98a..e4c42731ce39ae 100644
+--- a/net/tls/tls.h
++++ b/net/tls/tls.h
+@@ -141,6 +141,7 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx);
+ 
+ int wait_on_pending_writer(struct sock *sk, long *timeo);
+ void tls_err_abort(struct sock *sk, int err);
++void tls_strp_abort_strp(struct tls_strparser *strp, int err);
+ 
+ int init_prot_info(struct tls_prot_info *prot,
+ 		   const struct tls_crypto_info *crypto_info,
+diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
+index d71643b494a1ae..98e12f0ff57e51 100644
+--- a/net/tls/tls_strp.c
++++ b/net/tls/tls_strp.c
+@@ -13,7 +13,7 @@
+ 
+ static struct workqueue_struct *tls_strp_wq;
+ 
+-static void tls_strp_abort_strp(struct tls_strparser *strp, int err)
++void tls_strp_abort_strp(struct tls_strparser *strp, int err)
+ {
+ 	if (strp->stopped)
+ 		return;
+@@ -211,11 +211,17 @@ static int tls_strp_copyin_frag(struct tls_strparser *strp, struct sk_buff *skb,
+ 				struct sk_buff *in_skb, unsigned int offset,
+ 				size_t in_len)
+ {
++	unsigned int nfrag = skb->len / PAGE_SIZE;
+ 	size_t len, chunk;
+ 	skb_frag_t *frag;
+ 	int sz;
+ 
+-	frag = &skb_shinfo(skb)->frags[skb->len / PAGE_SIZE];
++	if (unlikely(nfrag >= skb_shinfo(skb)->nr_frags)) {
++		DEBUG_NET_WARN_ON_ONCE(1);
++		return -EMSGSIZE;
++	}
++
++	frag = &skb_shinfo(skb)->frags[nfrag];
+ 
+ 	len = in_len;
+ 	/* First make sure we got the header */
+@@ -520,10 +526,8 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ 	tls_strp_load_anchor_with_queue(strp, inq);
+ 	if (!strp->stm.full_len) {
+ 		sz = tls_rx_msg_size(strp, strp->anchor);
+-		if (sz < 0) {
+-			tls_strp_abort_strp(strp, sz);
++		if (sz < 0)
+ 			return sz;
+-		}
+ 
+ 		strp->stm.full_len = sz;
+ 
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index bac65d0d4e3e1e..daac9fd4be7eb5 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -2474,8 +2474,7 @@ int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb)
+ 	return data_len + TLS_HEADER_SIZE;
+ 
+ read_failure:
+-	tls_err_abort(strp->sk, ret);
+-
++	tls_strp_abort_strp(strp, ret);
+ 	return ret;
+ }
+ 
+diff --git a/samples/damon/mtier.c b/samples/damon/mtier.c
+index ed6bed8b3d4d99..88156145172f17 100644
+--- a/samples/damon/mtier.c
++++ b/samples/damon/mtier.c
+@@ -27,14 +27,14 @@ module_param(node1_end_addr, ulong, 0600);
+ static int damon_sample_mtier_enable_store(
+ 		const char *val, const struct kernel_param *kp);
+ 
+-static const struct kernel_param_ops enable_param_ops = {
++static const struct kernel_param_ops enabled_param_ops = {
+ 	.set = damon_sample_mtier_enable_store,
+ 	.get = param_get_bool,
+ };
+ 
+-static bool enable __read_mostly;
+-module_param_cb(enable, &enable_param_ops, &enable, 0600);
+-MODULE_PARM_DESC(enable, "Enable of disable DAMON_SAMPLE_MTIER");
++static bool enabled __read_mostly;
++module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
++MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_MTIER");
+ 
+ static struct damon_ctx *ctxs[2];
+ 
+@@ -156,20 +156,23 @@ static bool init_called;
+ static int damon_sample_mtier_enable_store(
+ 		const char *val, const struct kernel_param *kp)
+ {
+-	bool enabled = enable;
++	bool is_enabled = enabled;
+ 	int err;
+ 
+-	err = kstrtobool(val, &enable);
++	err = kstrtobool(val, &enabled);
+ 	if (err)
+ 		return err;
+ 
+-	if (enable == enabled)
++	if (enabled == is_enabled)
+ 		return 0;
+ 
+-	if (enable) {
++	if (!init_called)
++		return 0;
++
++	if (enabled) {
+ 		err = damon_sample_mtier_start();
+ 		if (err)
+-			enable = false;
++			enabled = false;
+ 		return err;
+ 	}
+ 	damon_sample_mtier_stop();
+@@ -181,10 +184,10 @@ static int __init damon_sample_mtier_init(void)
+ 	int err = 0;
+ 
+ 	init_called = true;
+-	if (enable) {
++	if (enabled) {
+ 		err = damon_sample_mtier_start();
+ 		if (err)
+-			enable = false;
++			enabled = false;
+ 	}
+ 	return 0;
+ }
+diff --git a/samples/damon/prcl.c b/samples/damon/prcl.c
+index 5597e6a08ab226..f971e61e6c5c00 100644
+--- a/samples/damon/prcl.c
++++ b/samples/damon/prcl.c
+@@ -17,14 +17,14 @@ module_param(target_pid, int, 0600);
+ static int damon_sample_prcl_enable_store(
+ 		const char *val, const struct kernel_param *kp);
+ 
+-static const struct kernel_param_ops enable_param_ops = {
++static const struct kernel_param_ops enabled_param_ops = {
+ 	.set = damon_sample_prcl_enable_store,
+ 	.get = param_get_bool,
+ };
+ 
+-static bool enable __read_mostly;
+-module_param_cb(enable, &enable_param_ops, &enable, 0600);
+-MODULE_PARM_DESC(enable, "Enable of disable DAMON_SAMPLE_WSSE");
++static bool enabled __read_mostly;
++module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
++MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_PRCL");
+ 
+ static struct damon_ctx *ctx;
+ static struct pid *target_pidp;
+@@ -109,23 +109,28 @@ static void damon_sample_prcl_stop(void)
+ 		put_pid(target_pidp);
+ }
+ 
++static bool init_called;
++
+ static int damon_sample_prcl_enable_store(
+ 		const char *val, const struct kernel_param *kp)
+ {
+-	bool enabled = enable;
++	bool is_enabled = enabled;
+ 	int err;
+ 
+-	err = kstrtobool(val, &enable);
++	err = kstrtobool(val, &enabled);
+ 	if (err)
+ 		return err;
+ 
+-	if (enable == enabled)
++	if (enabled == is_enabled)
++		return 0;
++
++	if (!init_called)
+ 		return 0;
+ 
+-	if (enable) {
++	if (enabled) {
+ 		err = damon_sample_prcl_start();
+ 		if (err)
+-			enable = false;
++			enabled = false;
+ 		return err;
+ 	}
+ 	damon_sample_prcl_stop();
+@@ -134,6 +139,14 @@ static int damon_sample_prcl_enable_store(
+ 
+ static int __init damon_sample_prcl_init(void)
+ {
++	int err = 0;
++
++	init_called = true;
++	if (enabled) {
++		err = damon_sample_prcl_start();
++		if (err)
++			enabled = false;
++	}
+ 	return 0;
+ }
+ 
+diff --git a/samples/damon/wsse.c b/samples/damon/wsse.c
+index e941958b103249..d50730ee65a7e7 100644
+--- a/samples/damon/wsse.c
++++ b/samples/damon/wsse.c
+@@ -18,14 +18,14 @@ module_param(target_pid, int, 0600);
+ static int damon_sample_wsse_enable_store(
+ 		const char *val, const struct kernel_param *kp);
+ 
+-static const struct kernel_param_ops enable_param_ops = {
++static const struct kernel_param_ops enabled_param_ops = {
+ 	.set = damon_sample_wsse_enable_store,
+ 	.get = param_get_bool,
+ };
+ 
+-static bool enable __read_mostly;
+-module_param_cb(enable, &enable_param_ops, &enable, 0600);
+-MODULE_PARM_DESC(enable, "Enable or disable DAMON_SAMPLE_WSSE");
++static bool enabled __read_mostly;
++module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
++MODULE_PARM_DESC(enabled, "Enable or disable DAMON_SAMPLE_WSSE");
+ 
+ static struct damon_ctx *ctx;
+ static struct pid *target_pidp;
+@@ -94,20 +94,20 @@ static bool init_called;
+ static int damon_sample_wsse_enable_store(
+ 		const char *val, const struct kernel_param *kp)
+ {
+-	bool enabled = enable;
++	bool is_enabled = enabled;
+ 	int err;
+ 
+-	err = kstrtobool(val, &enable);
++	err = kstrtobool(val, &enabled);
+ 	if (err)
+ 		return err;
+ 
+-	if (enable == enabled)
++	if (enabled == is_enabled)
+ 		return 0;
+ 
+-	if (enable) {
++	if (enabled) {
+ 		err = damon_sample_wsse_start();
+ 		if (err)
+-			enable = false;
++			enabled = false;
+ 		return err;
+ 	}
+ 	damon_sample_wsse_stop();
+@@ -119,10 +119,10 @@ static int __init damon_sample_wsse_init(void)
+ 	int err = 0;
+ 
+ 	init_called = true;
+-	if (enable) {
++	if (enabled) {
+ 		err = damon_sample_wsse_start();
+ 		if (err)
+-			enable = false;
++			enabled = false;
+ 	}
+ 	return err;
+ }
+diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
+index 88d1f4b56e4be4..a220ac0c8eb831 100644
+--- a/sound/firewire/motu/motu-hwdep.c
++++ b/sound/firewire/motu/motu-hwdep.c
+@@ -111,7 +111,7 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
+ 		events = 0;
+ 	spin_unlock_irq(&motu->lock);
+ 
+-	return events | EPOLLOUT;
++	return events;
+ }
+ 
+ static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 8458ca4d8d9dab..4819bd332f0390 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10752,6 +10752,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2),
+ 	SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2),
++	SND_PCI_QUIRK(0x103c, 0x89a0, "HP Laptop 15-dw4xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
+ 	SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
+diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c
+index 70fa54d568ef68..4d9589b67099ef 100644
+--- a/sound/soc/amd/acp/acp-i2s.c
++++ b/sound/soc/amd/acp/acp-i2s.c
+@@ -72,7 +72,7 @@ static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
+ 			   unsigned int fmt)
+ {
+ 	struct device *dev = cpu_dai->component->dev;
+-	struct acp_chip_info *chip = dev_get_platdata(dev);
++	struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
+ 	int mode;
+ 
+ 	mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+@@ -196,7 +196,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
+ 	u32 reg_val, fmt_reg, tdm_fmt;
+ 	u32 lrclk_div_val, bclk_div_val;
+ 
+-	chip = dev_get_platdata(dev);
++	chip = dev_get_drvdata(dev->parent);
+ 	rsrc = chip->rsrc;
+ 
+ 	/* These values are as per Hardware Spec */
+@@ -383,7 +383,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
+ {
+ 	struct acp_stream *stream = substream->runtime->private_data;
+ 	struct device *dev = dai->component->dev;
+-	struct acp_chip_info *chip = dev_get_platdata(dev);
++	struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
+ 	struct acp_resource *rsrc = chip->rsrc;
+ 	u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg;
+ 
+@@ -513,14 +513,13 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
+ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+ 	struct device *dev = dai->component->dev;
+-	struct acp_chip_info *chip = dev_get_platdata(dev);
++	struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
+ 	struct acp_resource *rsrc = chip->rsrc;
+ 	struct acp_stream *stream = substream->runtime->private_data;
+ 	u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
+ 	u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
+ 	unsigned int dir = substream->stream;
+ 
+-	chip = dev_get_platdata(dev);
+ 	switch (dai->driver->id) {
+ 	case I2S_SP_INSTANCE:
+ 		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+@@ -629,7 +628,7 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d
+ {
+ 	struct acp_stream *stream = substream->runtime->private_data;
+ 	struct device *dev = dai->component->dev;
+-	struct acp_chip_info *chip = dev_get_platdata(dev);
++	struct acp_chip_info *chip = dev_get_drvdata(dev->parent);
+ 	struct acp_resource *rsrc = chip->rsrc;
+ 	unsigned int dir = substream->stream;
+ 	unsigned int irq_bit = 0;
+diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c
+index b3d401ada17601..2d993428f87e3c 100644
+--- a/sound/soc/codecs/sma1307.c
++++ b/sound/soc/codecs/sma1307.c
+@@ -1737,9 +1737,10 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil
+ 	sma1307->set.checksum = data[sma1307->set.header_size - 2];
+ 	sma1307->set.num_mode = data[sma1307->set.header_size - 1];
+ 	num_mode = sma1307->set.num_mode;
+-	sma1307->set.header = devm_kzalloc(sma1307->dev,
+-					   sma1307->set.header_size,
+-					   GFP_KERNEL);
++	sma1307->set.header = devm_kmalloc_array(sma1307->dev,
++						 sma1307->set.header_size,
++						 sizeof(int),
++						 GFP_KERNEL);
+ 	if (!sma1307->set.header) {
+ 		sma1307->set.status = false;
+ 		return;
+diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
+index 401ee20897b1ba..94873ea630146b 100644
+--- a/sound/soc/codecs/wm8940.c
++++ b/sound/soc/codecs/wm8940.c
+@@ -220,7 +220,7 @@ static const struct snd_kcontrol_new wm8940_snd_controls[] = {
+ 	SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL,
+ 		       0, 255, 0, wm8940_adc_tlv),
+ 	SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum),
+-	SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST,
++	SOC_SINGLE_TLV("Capture Boost Volume", WM8940_ADCBOOST,
+ 		       8, 1, 0, wm8940_capture_boost_vol_tlv),
+ 	SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL,
+ 		       0, 63, 0, wm8940_spk_vol_tlv),
+@@ -693,7 +693,12 @@ static int wm8940_update_clocks(struct snd_soc_dai *dai)
+ 	f = wm8940_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
+ 	if (f != priv->mclk) {
+ 		/* The PLL performs best around 90MHz */
+-		fpll = wm8940_get_mclkdiv(22500000, fs256, &mclkdiv);
++		if (fs256 % 8000)
++			f = 22579200;
++		else
++			f = 24576000;
++
++		fpll = wm8940_get_mclkdiv(f, fs256, &mclkdiv);
+ 	}
+ 
+ 	wm8940_set_dai_pll(dai, 0, 0, priv->mclk, fpll);
+diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
+index bdf437a5403fe2..db16d893a23514 100644
+--- a/sound/soc/codecs/wm8974.c
++++ b/sound/soc/codecs/wm8974.c
+@@ -419,10 +419,14 @@ static int wm8974_update_clocks(struct snd_soc_dai *dai)
+ 	fs256 = 256 * priv->fs;
+ 
+ 	f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
+-
+ 	if (f != priv->mclk) {
+ 		/* The PLL performs best around 90MHz */
+-		fpll = wm8974_get_mclkdiv(22500000, fs256, &mclkdiv);
++		if (fs256 % 8000)
++			f = 22579200;
++		else
++			f = 24576000;
++
++		fpll = wm8974_get_mclkdiv(f, fs256, &mclkdiv);
+ 	}
+ 
+ 	wm8974_set_dai_pll(dai, 0, 0, priv->mclk, fpll);
+diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c
+index 81a2f0339e0552..ff1fa01acb85b2 100644
+--- a/sound/soc/intel/catpt/pcm.c
++++ b/sound/soc/intel/catpt/pcm.c
+@@ -568,8 +568,9 @@ static const struct snd_pcm_hardware catpt_pcm_hardware = {
+ 				  SNDRV_PCM_INFO_RESUME |
+ 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
+ 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
+-				  SNDRV_PCM_FMTBIT_S24_LE |
+ 				  SNDRV_PCM_FMTBIT_S32_LE,
++	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	.period_bytes_min	= PAGE_SIZE,
+ 	.period_bytes_max	= CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN,
+ 	.periods_min		= CATPT_PCM_PERIODS_MIN,
+@@ -699,14 +700,18 @@ static struct snd_soc_dai_driver dai_drivers[] = {
+ 		.channels_min = 2,
+ 		.channels_max = 2,
+ 		.rates = SNDRV_PCM_RATE_48000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	},
+ 	.capture = {
+ 		.stream_name = "Analog Capture",
+ 		.channels_min = 2,
+ 		.channels_max = 4,
+ 		.rates = SNDRV_PCM_RATE_48000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	},
+ },
+ {
+@@ -718,7 +723,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
+ 		.channels_min = 2,
+ 		.channels_max = 2,
+ 		.rates = SNDRV_PCM_RATE_8000_192000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	},
+ },
+ {
+@@ -730,7 +737,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
+ 		.channels_min = 2,
+ 		.channels_max = 2,
+ 		.rates = SNDRV_PCM_RATE_8000_192000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	},
+ },
+ {
+@@ -742,7 +751,9 @@ static struct snd_soc_dai_driver dai_drivers[] = {
+ 		.channels_min = 2,
+ 		.channels_max = 2,
+ 		.rates = SNDRV_PCM_RATE_48000,
+-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
++			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+ 	},
+ },
+ {
+diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
+index 4ebaaf736fb98a..3f5eed5afce55e 100644
+--- a/sound/soc/qcom/qdsp6/audioreach.c
++++ b/sound/soc/qcom/qdsp6/audioreach.c
+@@ -971,6 +971,7 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
+ 	param_data->param_id = PARAM_ID_I2S_INTF_CFG;
+ 	param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
+ 
++	intf_cfg->cfg.lpaif_type = module->hw_interface_type;
+ 	intf_cfg->cfg.intf_idx = module->hw_interface_idx;
+ 	intf_cfg->cfg.sd_line_idx = module->sd_line_idx;
+ 
+diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+index a0d90462fd6a38..528756f1332bcf 100644
+--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
++++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+@@ -213,8 +213,10 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
+ 
+ 	return 0;
+ err:
+-	q6apm_graph_close(dai_data->graph[dai->id]);
+-	dai_data->graph[dai->id] = NULL;
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		q6apm_graph_close(dai_data->graph[dai->id]);
++		dai_data->graph[dai->id] = NULL;
++	}
+ 	return rc;
+ }
+ 
+@@ -260,6 +262,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = {
+ 	.shutdown	= q6apm_lpass_dai_shutdown,
+ 	.set_channel_map  = q6dma_set_channel_map,
+ 	.hw_params        = q6dma_hw_params,
++	.set_fmt	= q6i2s_set_fmt,
+ };
+ 
+ static const struct snd_soc_dai_ops q6hdmi_ops = {
+diff --git a/sound/soc/sdca/sdca_device.c b/sound/soc/sdca/sdca_device.c
+index 0244cdcdd109a7..4798ce2c8f0b40 100644
+--- a/sound/soc/sdca/sdca_device.c
++++ b/sound/soc/sdca/sdca_device.c
+@@ -7,6 +7,7 @@
+  */
+ 
+ #include <linux/acpi.h>
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/property.h>
+ #include <linux/soundwire/sdw.h>
+@@ -55,11 +56,30 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave)
+ 	return false;
+ }
+ 
++static bool sdca_device_quirk_skip_func_type_patching(struct sdw_slave *slave)
++{
++	const char *vendor, *sku;
++
++	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
++	sku = dmi_get_system_info(DMI_PRODUCT_SKU);
++
++	if (vendor && sku &&
++	    !strcmp(vendor, "Dell Inc.") &&
++	    (!strcmp(sku, "0C62") || !strcmp(sku, "0C63") || !strcmp(sku, "0C6B")) &&
++	    slave->sdca_data.interface_revision == 0x061c &&
++	    slave->id.mfg_id == 0x01fa && slave->id.part_id == 0x4243)
++		return true;
++
++	return false;
++}
++
+ bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
+ {
+ 	switch (quirk) {
+ 	case SDCA_QUIRKS_RT712_VB:
+ 		return sdca_device_quirk_rt712_vb(slave);
++	case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING:
++		return sdca_device_quirk_skip_func_type_patching(slave);
+ 	default:
+ 		break;
+ 	}
+diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
+index 050f7338aca95a..ea793869c03858 100644
+--- a/sound/soc/sdca/sdca_functions.c
++++ b/sound/soc/sdca/sdca_functions.c
+@@ -89,6 +89,7 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
+ {
+ 	struct fwnode_handle *function_node = acpi_fwnode_handle(adev);
+ 	struct sdca_device_data *sdca_data = data;
++	struct sdw_slave *slave = container_of(sdca_data, struct sdw_slave, sdca_data);
+ 	struct device *dev = &adev->dev;
+ 	struct fwnode_handle *control5; /* used to identify function type */
+ 	const char *function_name;
+@@ -136,11 +137,13 @@ static int find_sdca_function(struct acpi_device *adev, void *data)
+ 		return ret;
+ 	}
+ 
+-	ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
+-	if (ret < 0) {
+-		dev_err(dev, "SDCA version %#x invalid function type %d\n",
+-			sdca_data->interface_revision, function_type);
+-		return ret;
++	if (!sdca_device_quirk_match(slave, SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING)) {
++		ret = patch_sdca_function_type(sdca_data->interface_revision, &function_type);
++		if (ret < 0) {
++			dev_err(dev, "SDCA version %#x invalid function type %d\n",
++				sdca_data->interface_revision, function_type);
++			return ret;
++		}
+ 	}
+ 
+ 	function_name = get_sdca_function_name(function_type);
+diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c
+index c41c67c2204a41..ff1f8fe2a39bb7 100644
+--- a/sound/soc/sdca/sdca_regmap.c
++++ b/sound/soc/sdca/sdca_regmap.c
+@@ -196,7 +196,7 @@ int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg)
+ 
+ 	control = function_find_control(function, reg);
+ 	if (!control)
+-		return false;
++		return -EINVAL;
+ 
+ 	return clamp_val(control->nbits / BITS_PER_BYTE, sizeof(u8), sizeof(u32));
+ }
+diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
+index aa6b0247d5c99e..a34f472ef1751f 100644
+--- a/sound/soc/sof/intel/hda-stream.c
++++ b/sound/soc/sof/intel/hda-stream.c
+@@ -890,7 +890,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
+ 
+ 	if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
+ 		dev_err(sdev->dev, "error: too many capture streams %d\n",
+-			num_playback);
++			num_capture);
+ 		return -EINVAL;
+ 	}
+ 
+diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_offload.c
+index a25c5a5316901c..9ad76fff741b8d 100644
+--- a/sound/usb/qcom/qc_audio_offload.c
++++ b/sound/usb/qcom/qc_audio_offload.c
+@@ -538,38 +538,33 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long iova,
+ 			umap_size, iova, mapped_iova_size);
+ }
+ 
++static int uaudio_iommu_map_prot(bool dma_coherent)
++{
++	int prot = IOMMU_READ | IOMMU_WRITE;
++
++	if (dma_coherent)
++		prot |= IOMMU_CACHE;
++	return prot;
++}
++
+ /**
+- * uaudio_iommu_map() - maps iommu memory for adsp
++ * uaudio_iommu_map_pa() - maps iommu memory for adsp
+  * @mtype: ring type
+  * @dma_coherent: dma coherent
+  * @pa: physical address for ring/buffer
+  * @size: size of memory region
+- * @sgt: sg table for memory region
+  *
+  * Maps the XHCI related resources to a memory region that is assigned to be
+  * used by the adsp.  This will be mapped to the domain, which is created by
+  * the ASoC USB backend driver.
+  *
+  */
+-static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
+-				      phys_addr_t pa, size_t size,
+-				      struct sg_table *sgt)
++static unsigned long uaudio_iommu_map_pa(enum mem_type mtype, bool dma_coherent,
++					 phys_addr_t pa, size_t size)
+ {
+-	struct scatterlist *sg;
+ 	unsigned long iova = 0;
+-	size_t total_len = 0;
+-	unsigned long iova_sg;
+-	phys_addr_t pa_sg;
+ 	bool map = true;
+-	size_t sg_len;
+-	int prot;
+-	int ret;
+-	int i;
+-
+-	prot = IOMMU_READ | IOMMU_WRITE;
+-
+-	if (dma_coherent)
+-		prot |= IOMMU_CACHE;
++	int prot = uaudio_iommu_map_prot(dma_coherent);
+ 
+ 	switch (mtype) {
+ 	case MEM_EVENT_RING:
+@@ -583,20 +578,41 @@ static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
+ 				     &uaudio_qdev->xfer_ring_iova_size,
+ 				     &uaudio_qdev->xfer_ring_list, size);
+ 		break;
+-	case MEM_XFER_BUF:
+-		iova = uaudio_get_iova(&uaudio_qdev->curr_xfer_buf_iova,
+-				     &uaudio_qdev->xfer_buf_iova_size,
+-				     &uaudio_qdev->xfer_buf_list, size);
+-		break;
+ 	default:
+ 		dev_err(uaudio_qdev->data->dev, "unknown mem type %d\n", mtype);
+ 	}
+ 
+ 	if (!iova || !map)
+-		goto done;
++		return 0;
++
++	iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
+ 
+-	if (!sgt)
+-		goto skip_sgt_map;
++	return iova;
++}
++
++static unsigned long uaudio_iommu_map_xfer_buf(bool dma_coherent, size_t size,
++					       struct sg_table *sgt)
++{
++	struct scatterlist *sg;
++	unsigned long iova = 0;
++	size_t total_len = 0;
++	unsigned long iova_sg;
++	phys_addr_t pa_sg;
++	size_t sg_len;
++	int prot = uaudio_iommu_map_prot(dma_coherent);
++	int ret;
++	int i;
++
++	prot = IOMMU_READ | IOMMU_WRITE;
++
++	if (dma_coherent)
++		prot |= IOMMU_CACHE;
++
++	iova = uaudio_get_iova(&uaudio_qdev->curr_xfer_buf_iova,
++			       &uaudio_qdev->xfer_buf_iova_size,
++			       &uaudio_qdev->xfer_buf_list, size);
++	if (!iova)
++		goto done;
+ 
+ 	iova_sg = iova;
+ 	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+@@ -618,11 +634,6 @@ static unsigned long uaudio_iommu_map(enum mem_type mtype, bool dma_coherent,
+ 		uaudio_iommu_unmap(MEM_XFER_BUF, iova, size, total_len);
+ 		iova = 0;
+ 	}
+-	return iova;
+-
+-skip_sgt_map:
+-	iommu_map(uaudio_qdev->data->domain, iova, pa, size, prot, GFP_KERNEL);
+-
+ done:
+ 	return iova;
+ }
+@@ -1020,7 +1031,6 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
+ 	struct sg_table xfer_buf_sgt;
+ 	dma_addr_t xfer_buf_dma;
+ 	void *xfer_buf;
+-	phys_addr_t xfer_buf_pa;
+ 	u32 len = xfer_buf_len;
+ 	bool dma_coherent;
+ 	dma_addr_t xfer_buf_dma_sysdev;
+@@ -1051,18 +1061,12 @@ static int uaudio_transfer_buffer_setup(struct snd_usb_substream *subs,
+ 	if (!xfer_buf)
+ 		return -ENOMEM;
+ 
+-	/* Remapping is not possible if xfer_buf is outside of linear map */
+-	xfer_buf_pa = virt_to_phys(xfer_buf);
+-	if (WARN_ON(!page_is_ram(PFN_DOWN(xfer_buf_pa)))) {
+-		ret = -ENXIO;
+-		goto unmap_sync;
+-	}
+ 	dma_get_sgtable(subs->dev->bus->sysdev, &xfer_buf_sgt, xfer_buf,
+ 			xfer_buf_dma, len);
+ 
+ 	/* map the physical buffer into sysdev as well */
+-	xfer_buf_dma_sysdev = uaudio_iommu_map(MEM_XFER_BUF, dma_coherent,
+-					       xfer_buf_pa, len, &xfer_buf_sgt);
++	xfer_buf_dma_sysdev = uaudio_iommu_map_xfer_buf(dma_coherent,
++							len, &xfer_buf_sgt);
+ 	if (!xfer_buf_dma_sysdev) {
+ 		ret = -ENOMEM;
+ 		goto unmap_sync;
+@@ -1143,8 +1147,8 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs,
+ 	sg_free_table(sgt);
+ 
+ 	/* data transfer ring */
+-	iova = uaudio_iommu_map(MEM_XFER_RING, dma_coherent, tr_pa,
+-			      PAGE_SIZE, NULL);
++	iova = uaudio_iommu_map_pa(MEM_XFER_RING, dma_coherent, tr_pa,
++				   PAGE_SIZE);
+ 	if (!iova) {
+ 		ret = -ENOMEM;
+ 		goto clear_pa;
+@@ -1207,8 +1211,8 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
+ 	mem_info->dma = sg_dma_address(sgt->sgl);
+ 	sg_free_table(sgt);
+ 
+-	iova = uaudio_iommu_map(MEM_EVENT_RING, dma_coherent, er_pa,
+-			      PAGE_SIZE, NULL);
++	iova = uaudio_iommu_map_pa(MEM_EVENT_RING, dma_coherent, er_pa,
++				   PAGE_SIZE);
+ 	if (!iova) {
+ 		ret = -ENOMEM;
+ 		goto clear_pa;
+diff --git a/tools/arch/loongarch/include/asm/inst.h b/tools/arch/loongarch/include/asm/inst.h
+index c25b5853181dba..d68fad63c8b732 100644
+--- a/tools/arch/loongarch/include/asm/inst.h
++++ b/tools/arch/loongarch/include/asm/inst.h
+@@ -51,6 +51,10 @@ enum reg2i16_op {
+ 	bgeu_op		= 0x1b,
+ };
+ 
++enum reg3_op {
++	amswapw_op	= 0x70c0,
++};
++
+ struct reg0i15_format {
+ 	unsigned int immediate : 15;
+ 	unsigned int opcode : 17;
+@@ -96,6 +100,13 @@ struct reg2i16_format {
+ 	unsigned int opcode : 6;
+ };
+ 
++struct reg3_format {
++	unsigned int rd : 5;
++	unsigned int rj : 5;
++	unsigned int rk : 5;
++	unsigned int opcode : 17;
++};
++
+ union loongarch_instruction {
+ 	unsigned int word;
+ 	struct reg0i15_format	reg0i15_format;
+@@ -105,6 +116,7 @@ union loongarch_instruction {
+ 	struct reg2i12_format	reg2i12_format;
+ 	struct reg2i14_format	reg2i14_format;
+ 	struct reg2i16_format	reg2i16_format;
++	struct reg3_format	reg3_format;
+ };
+ 
+ #define LOONGARCH_INSN_SIZE	sizeof(union loongarch_instruction)
+diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
+index b6fdc68053cc4e..2e555c4060c5e4 100644
+--- a/tools/objtool/arch/loongarch/decode.c
++++ b/tools/objtool/arch/loongarch/decode.c
+@@ -278,6 +278,25 @@ static bool decode_insn_reg2i16_fomat(union loongarch_instruction inst,
+ 	return true;
+ }
+ 
++static bool decode_insn_reg3_fomat(union loongarch_instruction inst,
++				   struct instruction *insn)
++{
++	switch (inst.reg3_format.opcode) {
++	case amswapw_op:
++		if (inst.reg3_format.rd == LOONGARCH_GPR_ZERO &&
++		    inst.reg3_format.rk == LOONGARCH_GPR_RA &&
++		    inst.reg3_format.rj == LOONGARCH_GPR_ZERO) {
++			/* amswap.w $zero, $ra, $zero */
++			insn->type = INSN_BUG;
++		}
++		break;
++	default:
++		return false;
++	}
++
++	return true;
++}
++
+ int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
+ 			    unsigned long offset, unsigned int maxlen,
+ 			    struct instruction *insn)
+@@ -309,11 +328,19 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
+ 		return 0;
+ 	if (decode_insn_reg2i16_fomat(inst, insn))
+ 		return 0;
++	if (decode_insn_reg3_fomat(inst, insn))
++		return 0;
+ 
+-	if (inst.word == 0)
++	if (inst.word == 0) {
++		/* andi $zero, $zero, 0x0 */
+ 		insn->type = INSN_NOP;
+-	else if (inst.reg0i15_format.opcode == break_op) {
+-		/* break */
++	} else if (inst.reg0i15_format.opcode == break_op &&
++		   inst.reg0i15_format.immediate == 0x0) {
++		/* break 0x0 */
++		insn->type = INSN_TRAP;
++	} else if (inst.reg0i15_format.opcode == break_op &&
++		   inst.reg0i15_format.immediate == 0x1) {
++		/* break 0x1 */
+ 		insn->type = INSN_BUG;
+ 	} else if (inst.reg2_format.opcode == ertn_op) {
+ 		/* ertn */
+diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
+index 85b2a93a59ac65..779f6230130af2 100644
+--- a/tools/perf/util/maps.c
++++ b/tools/perf/util/maps.c
+@@ -477,6 +477,7 @@ static int __maps__insert(struct maps *maps, struct map *new)
+ 	}
+ 	/* Insert the value at the end. */
+ 	maps_by_address[nr_maps] = map__get(new);
++	map__set_kmap_maps(new, maps);
+ 	if (maps_by_name)
+ 		maps_by_name[nr_maps] = map__get(new);
+ 
+@@ -502,8 +503,6 @@ static int __maps__insert(struct maps *maps, struct map *new)
+ 	if (map__end(new) < map__start(new))
+ 		RC_CHK_ACCESS(maps)->ends_broken = true;
+ 
+-	map__set_kmap_maps(new, maps);
+-
+ 	return 0;
+ }
+ 
+@@ -891,6 +890,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
+ 		if (before) {
+ 			map__put(maps_by_address[i]);
+ 			maps_by_address[i] = before;
++			map__set_kmap_maps(before, maps);
+ 
+ 			if (maps_by_name) {
+ 				map__put(maps_by_name[ni]);
+@@ -918,6 +918,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
+ 			 */
+ 			map__put(maps_by_address[i]);
+ 			maps_by_address[i] = map__get(new);
++			map__set_kmap_maps(new, maps);
+ 
+ 			if (maps_by_name) {
+ 				map__put(maps_by_name[ni]);
+@@ -942,14 +943,13 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
+ 				 */
+ 				map__put(maps_by_address[i]);
+ 				maps_by_address[i] = map__get(new);
++				map__set_kmap_maps(new, maps);
+ 
+ 				if (maps_by_name) {
+ 					map__put(maps_by_name[ni]);
+ 					maps_by_name[ni] = map__get(new);
+ 				}
+ 
+-				map__set_kmap_maps(new, maps);
+-
+ 				check_invariants(maps);
+ 				return err;
+ 			}
+@@ -1019,6 +1019,7 @@ int maps__copy_from(struct maps *dest, struct maps *parent)
+ 				err = unwind__prepare_access(dest, new, NULL);
+ 				if (!err) {
+ 					dest_maps_by_address[i] = new;
++					map__set_kmap_maps(new, dest);
+ 					if (dest_maps_by_name)
+ 						dest_maps_by_name[i] = map__get(new);
+ 					RC_CHK_ACCESS(dest)->nr_maps = i + 1;
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+index 4f07ac9fa207cb..b148cadb96d0b7 100644
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+@@ -1093,6 +1093,7 @@ int main_loop_s(int listensock)
+ 	struct pollfd polls;
+ 	socklen_t salen;
+ 	int remotesock;
++	int err = 0;
+ 	int fd = 0;
+ 
+ again:
+@@ -1125,7 +1126,7 @@ int main_loop_s(int listensock)
+ 		SOCK_TEST_TCPULP(remotesock, 0);
+ 
+ 		memset(&winfo, 0, sizeof(winfo));
+-		copyfd_io(fd, remotesock, 1, true, &winfo);
++		err = copyfd_io(fd, remotesock, 1, true, &winfo);
+ 	} else {
+ 		perror("accept");
+ 		return 1;
+@@ -1134,10 +1135,10 @@ int main_loop_s(int listensock)
+ 	if (cfg_input)
+ 		close(fd);
+ 
+-	if (--cfg_repeat > 0)
++	if (!err && --cfg_repeat > 0)
+ 		goto again;
+ 
+-	return 0;
++	return err;
+ }
+ 
+ static void init_rng(void)
+@@ -1247,7 +1248,7 @@ void xdisconnect(int fd)
+ 	else
+ 		xerror("bad family");
+ 
+-	strcpy(cmd, "ss -M | grep -q ");
++	strcpy(cmd, "ss -Mnt | grep -q ");
+ 	cmdlen = strlen(cmd);
+ 	if (!inet_ntop(addr.ss_family, raw_addr, &cmd[cmdlen],
+ 		       sizeof(cmd) - cmdlen))
+@@ -1257,7 +1258,7 @@ void xdisconnect(int fd)
+ 
+ 	/*
+ 	 * wait until the pending data is completely flushed and all
+-	 * the MPTCP sockets reached the closed status.
++	 * the sockets reached the closed status.
+ 	 * disconnect will bypass/ignore/drop any pending data.
+ 	 */
+ 	for (i = 0; ; i += msec_sleep) {
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+index e934dd26a59d9b..112c07c4c37a3c 100644
+--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
++++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+@@ -667,22 +667,26 @@ static void process_one_client(int fd, int pipefd)
+ 
+ 	do_getsockopts(&s, fd, ret, ret2);
+ 	if (s.mptcpi_rcv_delta != (uint64_t)ret + 1)
+-		xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64, s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - ret);
++		xerror("mptcpi_rcv_delta %" PRIu64 ", expect %" PRIu64 ", diff %" PRId64,
++		       s.mptcpi_rcv_delta, ret + 1, s.mptcpi_rcv_delta - (ret + 1));
+ 
+ 	/* be nice when running on top of older kernel */
+ 	if (s.pkt_stats_avail) {
+ 		if (s.last_sample.mptcpi_bytes_sent != ret2)
+-			xerror("mptcpi_bytes_sent %" PRIu64 ", expect %" PRIu64,
++			xerror("mptcpi_bytes_sent %" PRIu64 ", expect %" PRIu64
++			       ", diff %" PRId64,
+ 			       s.last_sample.mptcpi_bytes_sent, ret2,
+ 			       s.last_sample.mptcpi_bytes_sent - ret2);
+ 		if (s.last_sample.mptcpi_bytes_received != ret)
+-			xerror("mptcpi_bytes_received %" PRIu64 ", expect %" PRIu64,
++			xerror("mptcpi_bytes_received %" PRIu64 ", expect %" PRIu64
++			       ", diff %" PRId64,
+ 			       s.last_sample.mptcpi_bytes_received, ret,
+ 			       s.last_sample.mptcpi_bytes_received - ret);
+ 		if (s.last_sample.mptcpi_bytes_acked != ret)
+-			xerror("mptcpi_bytes_acked %" PRIu64 ", expect %" PRIu64,
+-			       s.last_sample.mptcpi_bytes_acked, ret2,
+-			       s.last_sample.mptcpi_bytes_acked - ret2);
++			xerror("mptcpi_bytes_acked %" PRIu64 ", expect %" PRIu64
++			       ", diff %" PRId64,
++			       s.last_sample.mptcpi_bytes_acked, ret,
++			       s.last_sample.mptcpi_bytes_acked - ret);
+ 	}
+ 
+ 	close(fd);
+diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+index 994a556f46c151..93fea3442216c8 100644
+--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
++++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+@@ -188,6 +188,13 @@ static int capture_events(int fd, int event_group)
+ 					fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs));
+ 				else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE)
+ 					fprintf(stderr, ",server_side:%u", *(__u8 *)RTA_DATA(attrs));
++				else if (attrs->rta_type == MPTCP_ATTR_FLAGS) {
++					__u16 flags = *(__u16 *)RTA_DATA(attrs);
++
++					/* only print when present, easier */
++					if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0)
++						fprintf(stderr, ",deny_join_id0:1");
++				}
+ 
+ 				attrs = RTA_NEXT(attrs, msg_len);
+ 			}
+diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
+index 333064b0b5ac03..97819e18578f4d 100755
+--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
++++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
+@@ -201,6 +201,9 @@ make_connection()
+ 		is_v6="v4"
+ 	fi
+ 
++	# set this on the client side only: will not affect the rest
++	ip netns exec "$ns2" sysctl -q net.mptcp.allow_join_initial_addr_port=0
++
+ 	:>"$client_evts"
+ 	:>"$server_evts"
+ 
+@@ -223,23 +226,28 @@ make_connection()
+ 	local client_token
+ 	local client_port
+ 	local client_serverside
++	local client_nojoin
+ 	local server_token
+ 	local server_serverside
++	local server_nojoin
+ 
+ 	client_token=$(mptcp_lib_evts_get_info token "$client_evts")
+ 	client_port=$(mptcp_lib_evts_get_info sport "$client_evts")
+ 	client_serverside=$(mptcp_lib_evts_get_info server_side "$client_evts")
++	client_nojoin=$(mptcp_lib_evts_get_info deny_join_id0 "$client_evts")
+ 	server_token=$(mptcp_lib_evts_get_info token "$server_evts")
+ 	server_serverside=$(mptcp_lib_evts_get_info server_side "$server_evts")
++	server_nojoin=$(mptcp_lib_evts_get_info deny_join_id0 "$server_evts")
+ 
+ 	print_test "Established IP${is_v6} MPTCP Connection ns2 => ns1"
+-	if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] &&
+-		   [ "$server_serverside" = 1 ]
++	if [ "${client_token}" != "" ] && [ "${server_token}" != "" ] &&
++	   [ "${client_serverside}" = 0 ] && [ "${server_serverside}" = 1 ] &&
++	   [ "${client_nojoin:-0}" = 0 ] && [ "${server_nojoin:-0}" = 1 ]
+ 	then
+ 		test_pass
+ 		print_title "Connection info: ${client_addr}:${client_port} -> ${connect_addr}:${app_port}"
+ 	else
+-		test_fail "Expected tokens (c:${client_token} - s:${server_token}) and server (c:${client_serverside} - s:${server_serverside})"
++		test_fail "Expected tokens (c:${client_token} - s:${server_token}), server (c:${client_serverside} - s:${server_serverside}), nojoin (c:${client_nojoin} - s:${server_nojoin})"
+ 		mptcp_lib_result_print_all_tap
+ 		exit ${KSFT_FAIL}
+ 	fi


             reply	other threads:[~2025-09-25 12:02 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-25 12:02 Arisu Tachibana [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-10-13 11:56 [gentoo-commits] proj/linux-patches:6.16 commit in: / Arisu Tachibana
2025-10-06 12:01 Arisu Tachibana
2025-10-06 11:06 Arisu Tachibana
2025-10-02 14:17 Arisu Tachibana
2025-10-02 14:14 Arisu Tachibana
2025-10-02 13:42 Arisu Tachibana
2025-10-02 13:30 Arisu Tachibana
2025-10-02 13:25 Arisu Tachibana
2025-10-02  3:28 Arisu Tachibana
2025-10-02  3:28 Arisu Tachibana
2025-10-02  3:12 Arisu Tachibana
2025-09-20  6:29 Arisu Tachibana
2025-09-20  6:29 Arisu Tachibana
2025-09-20  5:31 Arisu Tachibana
2025-09-20  5:25 Arisu Tachibana
2025-09-12  3:56 Arisu Tachibana
2025-09-10  6:18 Arisu Tachibana
2025-09-10  5:57 Arisu Tachibana
2025-09-10  5:30 Arisu Tachibana
2025-09-05 14:01 Arisu Tachibana
2025-09-04 15:46 Arisu Tachibana
2025-09-04 15:33 Arisu Tachibana
2025-08-28 16:37 Arisu Tachibana
2025-08-28 16:01 Arisu Tachibana
2025-08-28 15:31 Arisu Tachibana
2025-08-28 15:19 Arisu Tachibana
2025-08-28 15:14 Arisu Tachibana
2025-08-25  0:00 Arisu Tachibana
2025-08-24 23:09 Arisu Tachibana
2025-08-21  4:31 Arisu Tachibana
2025-08-21  4:31 Arisu Tachibana
2025-08-21  1:07 Arisu Tachibana
2025-08-21  1:00 Arisu Tachibana
2025-08-21  0:27 Arisu Tachibana
2025-08-16  5:54 Arisu Tachibana
2025-08-16  5:54 Arisu Tachibana
2025-08-16  5:21 Arisu Tachibana
2025-08-16  4:02 Arisu Tachibana
2025-08-16  3:07 Arisu Tachibana
2025-07-29  7:43 Arisu Tachibana

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1758801724.fb4386cb8d3a0e3944fcbd135b1a7c53cd28d3ad.alicef@gentoo \
    --to=alicef@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

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

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