From: "Arisu Tachibana" <alicef@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.12 commit in: /
Date: Thu, 25 Sep 2025 12:02:40 +0000 (UTC) [thread overview]
Message-ID: <1758801746.58abc47e9289b91e71cb97f5a3d77336d0fc9948.alicef@gentoo> (raw)
commit: 58abc47e9289b91e71cb97f5a3d77336d0fc9948
Author: Arisu Tachibana <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 25 12:02:26 2025 +0000
Commit: Arisu Tachibana <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Sep 25 12:02:26 2025 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=58abc47e
Linux patch 6.12.49
Signed-off-by: Arisu Tachibana <alicef <AT> gentoo.org>
0000_README | 4 +
1048_linux-6.12.49.patch | 4133 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 4137 insertions(+)
diff --git a/0000_README b/0000_README
index 737863c6..b6db0425 100644
--- a/0000_README
+++ b/0000_README
@@ -235,6 +235,10 @@ Patch: 1047_linux-6.12.48.patch
From: https://www.kernel.org
Desc: Linux 6.12.48
+Patch: 1048_linux-6.12.49.patch
+From: https://www.kernel.org
+Desc: Linux 6.12.49
+
Patch: 1500_fortify-copy-size-value-range-tracking-fix.patch
From: https://git.kernel.org/
Desc: fortify: Hide run-time copy size from value range tracking
diff --git a/1048_linux-6.12.49.patch b/1048_linux-6.12.49.patch
new file mode 100644
index 00000000..4cb7b1bc
--- /dev/null
+++ b/1048_linux-6.12.49.patch
@@ -0,0 +1,4133 @@
+diff --git a/Documentation/admin-guide/hw-vuln/srso.rst b/Documentation/admin-guide/hw-vuln/srso.rst
+index 2ad1c05b8c8839..66af95251a3d1b 100644
+--- a/Documentation/admin-guide/hw-vuln/srso.rst
++++ b/Documentation/admin-guide/hw-vuln/srso.rst
+@@ -104,7 +104,20 @@ The possible values in this file are:
+
+ (spec_rstack_overflow=ibpb-vmexit)
+
++ * 'Mitigation: Reduced Speculation':
+
++ This mitigation gets automatically enabled when the above one "IBPB on
++ VMEXIT" has been selected and the CPU supports the BpSpecReduce bit.
++
++ It gets automatically enabled on machines which have the
++ SRSO_USER_KERNEL_NO=1 CPUID bit. In that case, the code logic is to switch
++ to the above =ibpb-vmexit mitigation because the user/kernel boundary is
++ not affected anymore and thus "safe RET" is not needed.
++
++ After enabling the IBPB on VMEXIT mitigation option, the BpSpecReduce bit
++ is detected (functionality present on all such machines) and that
++ practically overrides IBPB on VMEXIT as it has a lot less performance
++ impact and takes care of the guest->host attack vector too.
+
+ In order to exploit vulnerability, an attacker needs to:
+
+diff --git a/Documentation/netlink/specs/mptcp_pm.yaml b/Documentation/netlink/specs/mptcp_pm.yaml
+index 7e295bad8b2923..a670a9bbe01bb1 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 ede8c04ea112bc..66ae67c52da819 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 12
+-SUBLEVEL = 48
++SUBLEVEL = 49
+ EXTRAVERSION =
+ NAME = Baby Opossum Posse
+
+diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
+index a7a1f15bcc6724..5f35a8bd8996ec 100644
+--- a/arch/loongarch/Kconfig
++++ b/arch/loongarch/Kconfig
+@@ -540,10 +540,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/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/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 2c0d852ca5366b..0e8793617a2e95 100644
+--- a/arch/loongarch/kernel/vdso.c
++++ b/arch/loongarch/kernel/vdso.c
+@@ -108,6 +108,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/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
+index 2b6e701776b6b8..e2cba5117fd25b 100644
+--- a/arch/um/drivers/virtio_uml.c
++++ b/arch/um/drivers/virtio_uml.c
+@@ -1231,10 +1231,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 f1d03cf3957fe8..62c176a2c1ac48 100644
+--- a/arch/um/os-Linux/file.c
++++ b/arch/um/os-Linux/file.c
+@@ -556,7 +556,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/events/intel/core.c b/arch/x86/events/intel/core.c
+index 5e43d390f7a3dd..36d8404f406dec 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -2793,7 +2793,7 @@ static void intel_pmu_read_event(struct perf_event *event)
+ if (pmu_enabled)
+ intel_pmu_disable_all();
+
+- if (is_topdown_event(event))
++ if (is_topdown_count(event))
+ static_call(intel_pmu_update_topdown_event)(event);
+ else
+ intel_pmu_drain_pebs_buffer();
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index 90f1f2f9d31400..16a8c1f3ff6558 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -464,6 +464,11 @@
+ #define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */
+ #define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */
+ #define X86_FEATURE_SRSO_NO (20*32+29) /* CPU is not affected by SRSO */
++#define X86_FEATURE_SRSO_USER_KERNEL_NO (20*32+30) /* CPU is not affected by SRSO across user/kernel boundaries */
++#define X86_FEATURE_SRSO_BP_SPEC_REDUCE (20*32+31) /*
++ * BP_CFG[BpSpecReduce] can be used to mitigate SRSO for VMs.
++ * (SRSO_MSR_FIX in the official doc).
++ */
+
+ /*
+ * Extended auxiliary flags: Linux defined - for features scattered in various
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 2b6e3127ef4e2d..21d07aa9400c7a 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -728,6 +728,7 @@
+
+ /* Zen4 */
+ #define MSR_ZEN4_BP_CFG 0xc001102e
++#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
+ #define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5
+
+ /* Fam 19h MSRs */
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 06bbc297c26c03..f3cb559a598df5 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -2718,6 +2718,7 @@ enum srso_mitigation {
+ SRSO_MITIGATION_SAFE_RET,
+ SRSO_MITIGATION_IBPB,
+ SRSO_MITIGATION_IBPB_ON_VMEXIT,
++ SRSO_MITIGATION_BP_SPEC_REDUCE,
+ };
+
+ enum srso_mitigation_cmd {
+@@ -2735,7 +2736,8 @@ static const char * const srso_strings[] = {
+ [SRSO_MITIGATION_MICROCODE] = "Vulnerable: Microcode, no safe RET",
+ [SRSO_MITIGATION_SAFE_RET] = "Mitigation: Safe RET",
+ [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB",
+- [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only"
++ [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only",
++ [SRSO_MITIGATION_BP_SPEC_REDUCE] = "Mitigation: Reduced Speculation"
+ };
+
+ static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
+@@ -2774,7 +2776,7 @@ static void __init srso_select_mitigation(void)
+ srso_cmd == SRSO_CMD_OFF) {
+ if (boot_cpu_has(X86_FEATURE_SBPB))
+ x86_pred_cmd = PRED_CMD_SBPB;
+- return;
++ goto out;
+ }
+
+ if (has_microcode) {
+@@ -2786,7 +2788,7 @@ static void __init srso_select_mitigation(void)
+ */
+ if (boot_cpu_data.x86 < 0x19 && !cpu_smt_possible()) {
+ setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
+- return;
++ goto out;
+ }
+
+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
+@@ -2810,6 +2812,9 @@ static void __init srso_select_mitigation(void)
+ break;
+
+ case SRSO_CMD_SAFE_RET:
++ if (boot_cpu_has(X86_FEATURE_SRSO_USER_KERNEL_NO))
++ goto ibpb_on_vmexit;
++
+ if (IS_ENABLED(CONFIG_MITIGATION_SRSO)) {
+ /*
+ * Enable the return thunk for generated code
+@@ -2861,7 +2866,14 @@ static void __init srso_select_mitigation(void)
+ }
+ break;
+
++ibpb_on_vmexit:
+ case SRSO_CMD_IBPB_ON_VMEXIT:
++ if (boot_cpu_has(X86_FEATURE_SRSO_BP_SPEC_REDUCE)) {
++ pr_notice("Reducing speculation to address VM/HV SRSO attack vector.\n");
++ srso_mitigation = SRSO_MITIGATION_BP_SPEC_REDUCE;
++ break;
++ }
++
+ if (IS_ENABLED(CONFIG_MITIGATION_IBPB_ENTRY)) {
+ if (has_microcode) {
+ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
+@@ -2883,7 +2895,15 @@ static void __init srso_select_mitigation(void)
+ }
+
+ out:
+- pr_info("%s\n", srso_strings[srso_mitigation]);
++ /*
++ * Clear the feature flag if this mitigation is not selected as that
++ * feature flag controls the BpSpecReduce MSR bit toggling in KVM.
++ */
++ if (srso_mitigation != SRSO_MITIGATION_BP_SPEC_REDUCE)
++ setup_clear_cpu_cap(X86_FEATURE_SRSO_BP_SPEC_REDUCE);
++
++ if (srso_mitigation != SRSO_MITIGATION_NONE)
++ pr_info("%s\n", srso_strings[srso_mitigation]);
+ }
+
+ #undef pr_fmt
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 800f781475c028..9170a9e127b7a8 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -1507,6 +1507,63 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ __free_pages(virt_to_page(svm->msrpm), get_order(MSRPM_SIZE));
+ }
+
++#ifdef CONFIG_CPU_MITIGATIONS
++static DEFINE_SPINLOCK(srso_lock);
++static atomic_t srso_nr_vms;
++
++static void svm_srso_clear_bp_spec_reduce(void *ign)
++{
++ struct svm_cpu_data *sd = this_cpu_ptr(&svm_data);
++
++ if (!sd->bp_spec_reduce_set)
++ return;
++
++ msr_clear_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT);
++ sd->bp_spec_reduce_set = false;
++}
++
++static void svm_srso_vm_destroy(void)
++{
++ if (!cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE))
++ return;
++
++ if (atomic_dec_return(&srso_nr_vms))
++ return;
++
++ guard(spinlock)(&srso_lock);
++
++ /*
++ * Verify a new VM didn't come along, acquire the lock, and increment
++ * the count before this task acquired the lock.
++ */
++ if (atomic_read(&srso_nr_vms))
++ return;
++
++ on_each_cpu(svm_srso_clear_bp_spec_reduce, NULL, 1);
++}
++
++static void svm_srso_vm_init(void)
++{
++ if (!cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE))
++ return;
++
++ /*
++ * Acquire the lock on 0 => 1 transitions to ensure a potential 1 => 0
++ * transition, i.e. destroying the last VM, is fully complete, e.g. so
++ * that a delayed IPI doesn't clear BP_SPEC_REDUCE after a vCPU runs.
++ */
++ if (atomic_inc_not_zero(&srso_nr_vms))
++ return;
++
++ guard(spinlock)(&srso_lock);
++
++ atomic_inc(&srso_nr_vms);
++}
++#else
++static void svm_srso_vm_init(void) { }
++static void svm_srso_vm_destroy(void) { }
++#endif
++
+ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+@@ -1539,6 +1596,11 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm)))
+ kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
+
++ if (cpu_feature_enabled(X86_FEATURE_SRSO_BP_SPEC_REDUCE) &&
++ !sd->bp_spec_reduce_set) {
++ sd->bp_spec_reduce_set = true;
++ msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT);
++ }
+ svm->guest_state_loaded = true;
+ }
+
+@@ -4044,8 +4106,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);
+@@ -5005,6 +5066,8 @@ static void svm_vm_destroy(struct kvm *kvm)
+ {
+ avic_vm_destroy(kvm);
+ sev_vm_destroy(kvm);
++
++ svm_srso_vm_destroy();
+ }
+
+ static int svm_vm_init(struct kvm *kvm)
+@@ -5030,6 +5093,7 @@ static int svm_vm_init(struct kvm *kvm)
+ return ret;
+ }
+
++ svm_srso_vm_init();
+ return 0;
+ }
+
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index d114efac7af78d..1aa9b1e468cb44 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -335,6 +335,8 @@ struct svm_cpu_data {
+ u32 next_asid;
+ u32 min_asid;
+
++ bool bp_spec_reduce_set;
++
+ struct vmcb *save_area;
+ unsigned long save_area_pa;
+
+diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
+index 4bf4fad5b148ef..5a18ecc04a6c35 100644
+--- a/arch/x86/lib/msr.c
++++ b/arch/x86/lib/msr.c
+@@ -103,6 +103,7 @@ int msr_set_bit(u32 msr, u8 bit)
+ {
+ return __flip_bit(msr, bit, true);
+ }
++EXPORT_SYMBOL_GPL(msr_set_bit);
+
+ /**
+ * msr_clear_bit - Clear @bit in a MSR @msr.
+@@ -118,6 +119,7 @@ int msr_clear_bit(u32 msr, u8 bit)
+ {
+ return __flip_bit(msr, bit, false);
+ }
++EXPORT_SYMBOL_GPL(msr_clear_bit);
+
+ #ifdef CONFIG_TRACEPOINTS
+ void do_trace_write_msr(unsigned int msr, u64 val, int failed)
+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/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index b585c321d3454c..b02ff92bae0b1b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -8462,7 +8462,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;
+@@ -8515,7 +8524,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/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index c036bbc92ba96e..7244c3abb7f992 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -2683,7 +2683,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");
+@@ -2753,8 +2753,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 9ba2a667a1f3a1..b18bdb2daddf8b 100644
+--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+@@ -2054,8 +2054,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/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_vm.c b/drivers/gpu/drm/xe/xe_vm.c
+index a4845d4213b006..fc5f0e1351932a 100644
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -239,8 +239,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 6fb2f2919ab1ff..a14ee649d3da3b 100644
+--- a/drivers/iommu/amd/amd_iommu_types.h
++++ b/drivers/iommu/amd/amd_iommu_types.h
+@@ -545,6 +545,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/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
+index f3399087859fd1..91cc1e0c663dbf 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>
+
+@@ -144,8 +145,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;
+@@ -167,6 +171,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;
+
+@@ -184,8 +189,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);
+
+@@ -262,6 +273,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
+ unsigned long *page_size)
+ {
+ int level;
++ unsigned int seqcount;
+ u64 *pte;
+
+ *page_size = 0;
+@@ -269,8 +281,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) {
+@@ -552,6 +568,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 b300f72cf01e68..32d6710e264a4e 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -1768,6 +1768,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,
+@@ -1844,7 +1848,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/md/dm-raid.c b/drivers/md/dm-raid.c
+index 163a5bbd485f97..c69696d2540ab8 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3811,8 +3811,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 c68dc1653cfd1b..cbf4c102c4d0c0 100644
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -457,11 +457,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 12df4ff9eeee53..878fda43b7f73b 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/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 52ff0f9e04e079..00204e42de2e77 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2117,6 +2117,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.
+@@ -3337,7 +3338,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 cbd3859ea475bf..980daecab8ea3d 100644
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+@@ -2735,7 +2735,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.h b/drivers/net/ethernet/intel/ice/ice.h
+index 2960709f6b62ca..0e699a0432c5b2 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -372,9 +372,6 @@ struct ice_vsi {
+ spinlock_t arfs_lock; /* protects aRFS hash table and filter state */
+ atomic_t *arfs_last_fltr_id;
+
+- u16 max_frame;
+- u16 rx_buf_len;
+-
+ struct ice_aqc_vsi_props info; /* VSI properties */
+ struct ice_vsi_vlan_info vlan_info; /* vlan config to be restored */
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c
+index 4a9a6899fc453c..98c3764fed396e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_base.c
++++ b/drivers/net/ethernet/intel/ice/ice_base.c
+@@ -445,7 +445,7 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring)
+ /* Max packet size for this queue - must not be set to a larger value
+ * than 5 x DBUF
+ */
+- rlan_ctx.rxmax = min_t(u32, vsi->max_frame,
++ rlan_ctx.rxmax = min_t(u32, ring->max_frame,
+ ICE_MAX_CHAINED_RX_BUFS * ring->rx_buf_len);
+
+ /* Rx queue threshold in units of 64 */
+@@ -541,8 +541,6 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
+ u32 num_bufs = ICE_RX_DESC_UNUSED(ring);
+ int err;
+
+- ring->rx_buf_len = ring->vsi->rx_buf_len;
+-
+ if (ring->vsi->type == ICE_VSI_PF || ring->vsi->type == ICE_VSI_SF) {
+ if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) {
+ err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
+@@ -641,21 +639,25 @@ int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx)
+ /**
+ * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
+ * @vsi: VSI
++ * @ring: Rx ring to configure
++ *
++ * Determine the maximum frame size and Rx buffer length to use for a PF VSI.
++ * Set these in the associated Rx ring structure.
+ */
+-static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
++static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi, struct ice_rx_ring *ring)
+ {
+ if (!vsi->netdev || test_bit(ICE_FLAG_LEGACY_RX, vsi->back->flags)) {
+- vsi->max_frame = ICE_MAX_FRAME_LEGACY_RX;
+- vsi->rx_buf_len = ICE_RXBUF_1664;
++ ring->max_frame = ICE_MAX_FRAME_LEGACY_RX;
++ ring->rx_buf_len = ICE_RXBUF_1664;
+ #if (PAGE_SIZE < 8192)
+ } else if (!ICE_2K_TOO_SMALL_WITH_PADDING &&
+ (vsi->netdev->mtu <= ETH_DATA_LEN)) {
+- vsi->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
+- vsi->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
++ ring->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
++ ring->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
+ #endif
+ } else {
+- vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
+- vsi->rx_buf_len = ICE_RXBUF_3072;
++ ring->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
++ ring->rx_buf_len = ICE_RXBUF_3072;
+ }
+ }
+
+@@ -670,15 +672,15 @@ int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
+ {
+ u16 i;
+
+- if (vsi->type == ICE_VSI_VF)
+- goto setup_rings;
+-
+- ice_vsi_cfg_frame_size(vsi);
+-setup_rings:
+ /* set up individual rings */
+ ice_for_each_rxq(vsi, i) {
+- int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]);
++ struct ice_rx_ring *ring = vsi->rx_rings[i];
++ int err;
++
++ if (vsi->type != ICE_VSI_VF)
++ ice_vsi_cfg_frame_size(vsi, ring);
+
++ err = ice_vsi_cfg_rxq(ring);
+ if (err)
+ return err;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index cde69f56866562..431a6ed498a4ed 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 7130992d417798..a13531c21d4ad8 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -357,9 +357,9 @@ 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;
+- dma_addr_t dma; /* physical address of ring */
++ u16 max_frame;
+ u16 rx_buf_len;
++ dma_addr_t dma; /* physical address of ring */
+ u8 dcb_tc; /* Traffic class of ring */
+ u8 ptp_rx;
+ #define ICE_RX_FLAGS_RING_BUILD_SKB BIT(1)
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+index 87ffd25b268a2e..471d64d202b760 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -1748,19 +1748,18 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
+ (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
+ qpi->rxq.databuffer_size < 1024))
+ goto error_param;
+- vsi->rx_buf_len = qpi->rxq.databuffer_size;
+- ring->rx_buf_len = vsi->rx_buf_len;
++ ring->rx_buf_len = qpi->rxq.databuffer_size;
+ if (qpi->rxq.max_pkt_size > max_frame_size ||
+ qpi->rxq.max_pkt_size < 64)
+ goto error_param;
+
+- vsi->max_frame = qpi->rxq.max_pkt_size;
++ ring->max_frame = qpi->rxq.max_pkt_size;
+ /* add space for the port VLAN since the VF driver is
+ * not expected to account for it in the MTU
+ * calculation
+ */
+ if (ice_vf_is_port_vlan_ena(vf))
+- vsi->max_frame += VLAN_HLEN;
++ ring->max_frame += VLAN_HLEN;
+
+ if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
+ dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 323db1e2be3886..79d5fc5ac4fcec 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -336,6 +336,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 aadc0667fa04a4..9ba41a427e141c 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -7169,8 +7169,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;
+@@ -7226,7 +7232,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/marvell/octeon_ep/octep_pfvf_mbox.c b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
+index e6eb98d70f3c42..6334b68f28d796 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
+@@ -177,6 +177,7 @@ static void octep_pfvf_get_mac_addr(struct octep_device *oct, u32 vf_id,
+ dev_err(&oct->pdev->dev, "Get VF MAC address failed via host control Mbox\n");
+ 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;
+ }
+
+@@ -186,6 +187,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_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 6176457b846bc1..de2327ffb0f788 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -135,8 +135,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 18ec392d17404c..b561358474c4ff 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+@@ -1497,12 +1497,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
+@@ -1629,8 +1638,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 02a3563f51ad26..d8c304427e2ab8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+@@ -733,6 +733,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/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/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
+index 998586872599b3..c692d2e878b2e3 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 f67be4b8ad4351..523cbd91baf491 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -4461,10 +4461,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/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index c48c2de6f961f7..e1e472b3a301ef 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -2051,6 +2051,11 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
+
+ rq->comp_ring.gen = VMXNET3_INIT_GEN;
+ rq->comp_ring.next2proc = 0;
++
++ if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
++ xdp_rxq_info_unreg(&rq->xdp_rxq);
++ page_pool_destroy(rq->page_pool);
++ rq->page_pool = NULL;
+ }
+
+
+@@ -2091,11 +2096,6 @@ static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+ }
+ }
+
+- if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
+- xdp_rxq_info_unreg(&rq->xdp_rxq);
+- page_pool_destroy(rq->page_pool);
+- rq->page_pool = NULL;
+-
+ if (rq->data_ring.base) {
+ dma_free_coherent(&adapter->pdev->dev,
+ rq->rx_ring[0].size * rq->data_ring.desc_size,
+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 9e223574db7f77..24d82d35041b54 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -890,6 +890,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:
+@@ -929,13 +938,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;
+@@ -1014,6 +1017,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);
+ }
+
+ switch (ns->head->pi_type) {
+diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
+index 5b639c942f17a9..a2f50db2b8bab2 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 8f06adf828361a..1955495ea95f4a 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -146,7 +146,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)
+@@ -538,6 +543,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,
++ },
+ {},
+ };
+
+@@ -635,6 +649,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},
+ };
+
+@@ -654,9 +669,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 d02f15fd3482fa..56fe5d8a1196ed 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 871f03d160c53a..14be797e89c3d1 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1909,8 +1909,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/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
+index fc079b9dcf7192..502571f0c203fa 100644
+--- a/drivers/rtc/rtc-pcf2127.c
++++ b/drivers/rtc/rtc-pcf2127.c
+@@ -1383,11 +1383,6 @@ static int pcf2127_i2c_probe(struct i2c_client *client)
+ variant = &pcf21xx_cfg[type];
+ }
+
+- if (variant->type == PCF2131) {
+- config.read_flag_mask = 0x0;
+- config.write_flag_mask = 0x0;
+- }
+-
+ config.max_register = variant->max_register,
+
+ regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap,
+@@ -1461,6 +1456,11 @@ static int pcf2127_spi_probe(struct spi_device *spi)
+ variant = &pcf21xx_cfg[type];
+ }
+
++ if (variant->type == PCF2131) {
++ config.read_flag_mask = 0x0;
++ config.write_flag_mask = 0x0;
++ }
++
+ config.max_register = variant->max_register;
+
+ regmap = devm_regmap_init_spi(spi, &config);
+diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
+index bdc664ad6a934c..1fcc9348dd439d 100644
+--- a/drivers/usb/host/xhci-dbgcap.c
++++ b/drivers/usb/host/xhci-dbgcap.c
+@@ -101,13 +101,34 @@ static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings)
+ return string_length;
+ }
+
++static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc)
++{
++ struct xhci_ep_ctx *ep_ctx;
++ unsigned int max_burst;
++ dma_addr_t deq;
++
++ max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
++
++ /* Populate bulk out endpoint context: */
++ ep_ctx = dbc_bulkout_ctx(dbc);
++ deq = dbc_bulkout_enq(dbc);
++ ep_ctx->ep_info = 0;
++ ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
++ ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state);
++
++ /* Populate bulk in endpoint context: */
++ ep_ctx = dbc_bulkin_ctx(dbc);
++ deq = dbc_bulkin_enq(dbc);
++ ep_ctx->ep_info = 0;
++ ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
++ ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state);
++}
++
+ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
+ {
+ struct dbc_info_context *info;
+- struct xhci_ep_ctx *ep_ctx;
+ u32 dev_info;
+- dma_addr_t deq, dma;
+- unsigned int max_burst;
++ dma_addr_t dma;
+
+ if (!dbc)
+ return;
+@@ -121,20 +142,8 @@ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
+ info->serial = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3);
+ info->length = cpu_to_le32(string_length);
+
+- /* Populate bulk out endpoint context: */
+- ep_ctx = dbc_bulkout_ctx(dbc);
+- max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
+- deq = dbc_bulkout_enq(dbc);
+- ep_ctx->ep_info = 0;
+- ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
+- ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state);
+-
+- /* Populate bulk in endpoint context: */
+- ep_ctx = dbc_bulkin_ctx(dbc);
+- deq = dbc_bulkin_enq(dbc);
+- ep_ctx->ep_info = 0;
+- ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
+- ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state);
++ /* Populate bulk in and out endpoint contexts: */
++ xhci_dbc_init_ep_contexts(dbc);
+
+ /* Set DbC context and info registers: */
+ lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp);
+@@ -435,6 +444,42 @@ dbc_alloc_ctx(struct device *dev, gfp_t flags)
+ return ctx;
+ }
+
++static void xhci_dbc_ring_init(struct xhci_ring *ring)
++{
++ struct xhci_segment *seg = ring->first_seg;
++
++ /* clear all trbs on ring in case of old ring */
++ memset(seg->trbs, 0, TRB_SEGMENT_SIZE);
++
++ /* Only event ring does not use link TRB */
++ if (ring->type != TYPE_EVENT) {
++ union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
++
++ trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma);
++ trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
++ }
++ xhci_initialize_ring_info(ring);
++}
++
++static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc)
++{
++ struct xhci_ring *in_ring = dbc->eps[BULK_IN].ring;
++ struct xhci_ring *out_ring = dbc->eps[BULK_OUT].ring;
++
++ if (!in_ring || !out_ring || !dbc->ctx) {
++ dev_warn(dbc->dev, "Can't re-init unallocated endpoints\n");
++ return -ENODEV;
++ }
++
++ xhci_dbc_ring_init(in_ring);
++ xhci_dbc_ring_init(out_ring);
++
++ /* set ep context enqueue, dequeue, and cycle to initial values */
++ xhci_dbc_init_ep_contexts(dbc);
++
++ return 0;
++}
++
+ static struct xhci_ring *
+ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
+ {
+@@ -463,15 +508,10 @@ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
+
+ seg->dma = dma;
+
+- /* Only event ring does not use link TRB */
+- if (type != TYPE_EVENT) {
+- union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
+-
+- trb->link.segment_ptr = cpu_to_le64(dma);
+- trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
+- }
+ INIT_LIST_HEAD(&ring->td_list);
+- xhci_initialize_ring_info(ring, 1);
++
++ xhci_dbc_ring_init(ring);
++
+ return ring;
+ dma_fail:
+ kfree(seg);
+@@ -863,7 +903,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
+ dev_info(dbc->dev, "DbC cable unplugged\n");
+ dbc->state = DS_ENABLED;
+ xhci_dbc_flush_requests(dbc);
+-
++ xhci_dbc_reinit_ep_rings(dbc);
+ return EVT_DISC;
+ }
+
+@@ -873,7 +913,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
+ writel(portsc, &dbc->regs->portsc);
+ dbc->state = DS_ENABLED;
+ xhci_dbc_flush_requests(dbc);
+-
++ xhci_dbc_reinit_ep_rings(dbc);
+ return EVT_DISC;
+ }
+
+diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
+index f8ba15e7c225c2..570210e8a8e874 100644
+--- a/drivers/usb/host/xhci-debugfs.c
++++ b/drivers/usb/host/xhci-debugfs.c
+@@ -214,14 +214,11 @@ static void xhci_ring_dump_segment(struct seq_file *s,
+
+ static int xhci_ring_trb_show(struct seq_file *s, void *unused)
+ {
+- int i;
+ struct xhci_ring *ring = *(struct xhci_ring **)s->private;
+ struct xhci_segment *seg = ring->first_seg;
+
+- for (i = 0; i < ring->num_segs; i++) {
++ xhci_for_each_ring_seg(ring->first_seg, seg)
+ xhci_ring_dump_segment(s, seg);
+- seg = seg->next;
+- }
+
+ return 0;
+ }
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 91b47f9573cd7e..c9694526b157dd 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -27,14 +27,12 @@
+ * "All components of all Command and Transfer TRBs shall be initialized to '0'"
+ */
+ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
+- unsigned int cycle_state,
+ unsigned int max_packet,
+ unsigned int num,
+ gfp_t flags)
+ {
+ struct xhci_segment *seg;
+ dma_addr_t dma;
+- int i;
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+
+ seg = kzalloc_node(sizeof(*seg), flags, dev_to_node(dev));
+@@ -56,11 +54,6 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
+ return NULL;
+ }
+ }
+- /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */
+- if (cycle_state == 0) {
+- for (i = 0; i < TRBS_PER_SEGMENT; i++)
+- seg->trbs[i].link.control = cpu_to_le32(TRB_CYCLE);
+- }
+ seg->num = num;
+ seg->dma = dma;
+ seg->next = NULL;
+@@ -138,6 +131,14 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring,
+
+ chain_links = xhci_link_chain_quirk(xhci, ring->type);
+
++ /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */
++ if (ring->cycle_state == 0) {
++ xhci_for_each_ring_seg(ring->first_seg, seg) {
++ for (int i = 0; i < TRBS_PER_SEGMENT; i++)
++ seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE);
++ }
++ }
++
+ next = ring->enq_seg->next;
+ xhci_link_segments(ring->enq_seg, first, ring->type, chain_links);
+ xhci_link_segments(last, next, ring->type, chain_links);
+@@ -224,7 +225,6 @@ static int xhci_update_stream_segment_mapping(
+ struct radix_tree_root *trb_address_map,
+ struct xhci_ring *ring,
+ struct xhci_segment *first_seg,
+- struct xhci_segment *last_seg,
+ gfp_t mem_flags)
+ {
+ struct xhci_segment *seg;
+@@ -234,28 +234,22 @@ static int xhci_update_stream_segment_mapping(
+ if (WARN_ON_ONCE(trb_address_map == NULL))
+ return 0;
+
+- seg = first_seg;
+- do {
++ xhci_for_each_ring_seg(first_seg, seg) {
+ ret = xhci_insert_segment_mapping(trb_address_map,
+ ring, seg, mem_flags);
+ if (ret)
+ goto remove_streams;
+- if (seg == last_seg)
+- return 0;
+- seg = seg->next;
+- } while (seg != first_seg);
++ }
+
+ return 0;
+
+ remove_streams:
+ failed_seg = seg;
+- seg = first_seg;
+- do {
++ xhci_for_each_ring_seg(first_seg, seg) {
+ xhci_remove_segment_mapping(trb_address_map, seg);
+ if (seg == failed_seg)
+ return ret;
+- seg = seg->next;
+- } while (seg != first_seg);
++ }
+
+ return ret;
+ }
+@@ -267,17 +261,14 @@ static void xhci_remove_stream_mapping(struct xhci_ring *ring)
+ if (WARN_ON_ONCE(ring->trb_address_map == NULL))
+ return;
+
+- seg = ring->first_seg;
+- do {
++ xhci_for_each_ring_seg(ring->first_seg, seg)
+ xhci_remove_segment_mapping(ring->trb_address_map, seg);
+- seg = seg->next;
+- } while (seg != ring->first_seg);
+ }
+
+ static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags)
+ {
+ return xhci_update_stream_segment_mapping(ring->trb_address_map, ring,
+- ring->first_seg, ring->last_seg, mem_flags);
++ ring->first_seg, mem_flags);
+ }
+
+ /* XXX: Do we need the hcd structure in all these functions? */
+@@ -297,8 +288,7 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
+ kfree(ring);
+ }
+
+-void xhci_initialize_ring_info(struct xhci_ring *ring,
+- unsigned int cycle_state)
++void xhci_initialize_ring_info(struct xhci_ring *ring)
+ {
+ /* The ring is empty, so the enqueue pointer == dequeue pointer */
+ ring->enqueue = ring->first_seg->trbs;
+@@ -312,7 +302,7 @@ void xhci_initialize_ring_info(struct xhci_ring *ring,
+ * New rings are initialized with cycle state equal to 1; if we are
+ * handling ring expansion, set the cycle state equal to the old ring.
+ */
+- ring->cycle_state = cycle_state;
++ ring->cycle_state = 1;
+
+ /*
+ * Each segment has a link TRB, and leave an extra TRB for SW
+@@ -327,7 +317,6 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
+ struct xhci_segment **first,
+ struct xhci_segment **last,
+ unsigned int num_segs,
+- unsigned int cycle_state,
+ enum xhci_ring_type type,
+ unsigned int max_packet,
+ gfp_t flags)
+@@ -338,7 +327,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
+
+ chain_links = xhci_link_chain_quirk(xhci, type);
+
+- prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags);
++ prev = xhci_segment_alloc(xhci, max_packet, num, flags);
+ if (!prev)
+ return -ENOMEM;
+ num++;
+@@ -347,8 +336,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
+ while (num < num_segs) {
+ struct xhci_segment *next;
+
+- next = xhci_segment_alloc(xhci, cycle_state, max_packet, num,
+- flags);
++ next = xhci_segment_alloc(xhci, max_packet, num, flags);
+ if (!next)
+ goto free_segments;
+
+@@ -373,9 +361,8 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
+ * Set the end flag and the cycle toggle bit on the last segment.
+ * See section 4.9.1 and figures 15 and 16.
+ */
+-struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
+- unsigned int num_segs, unsigned int cycle_state,
+- enum xhci_ring_type type, unsigned int max_packet, gfp_t flags)
++struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs,
++ enum xhci_ring_type type, unsigned int max_packet, gfp_t flags)
+ {
+ struct xhci_ring *ring;
+ int ret;
+@@ -393,7 +380,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
+ return ring;
+
+ ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg, &ring->last_seg, num_segs,
+- cycle_state, type, max_packet, flags);
++ type, max_packet, flags);
+ if (ret)
+ goto fail;
+
+@@ -403,7 +390,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
+ ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |=
+ cpu_to_le32(LINK_TOGGLE);
+ }
+- xhci_initialize_ring_info(ring, cycle_state);
++ xhci_initialize_ring_info(ring);
+ trace_xhci_ring_alloc(ring);
+ return ring;
+
+@@ -431,14 +418,14 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
+ struct xhci_segment *last;
+ int ret;
+
+- ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, ring->cycle_state,
+- ring->type, ring->bounce_buf_len, flags);
++ ret = xhci_alloc_segments_for_ring(xhci, &first, &last, num_new_segs, ring->type,
++ ring->bounce_buf_len, flags);
+ if (ret)
+ return -ENOMEM;
+
+ if (ring->type == TYPE_STREAM) {
+ ret = xhci_update_stream_segment_mapping(ring->trb_address_map,
+- ring, first, last, flags);
++ ring, first, flags);
+ if (ret)
+ goto free_segments;
+ }
+@@ -642,8 +629,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
+
+ for (cur_stream = 1; cur_stream < num_streams; cur_stream++) {
+ stream_info->stream_rings[cur_stream] =
+- xhci_ring_alloc(xhci, 2, 1, TYPE_STREAM, max_packet,
+- mem_flags);
++ xhci_ring_alloc(xhci, 2, TYPE_STREAM, max_packet, mem_flags);
+ cur_ring = stream_info->stream_rings[cur_stream];
+ if (!cur_ring)
+ goto cleanup_rings;
+@@ -984,7 +970,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+ }
+
+ /* Allocate endpoint 0 ring */
+- dev->eps[0].ring = xhci_ring_alloc(xhci, 2, 1, TYPE_CTRL, 0, flags);
++ dev->eps[0].ring = xhci_ring_alloc(xhci, 2, TYPE_CTRL, 0, flags);
+ if (!dev->eps[0].ring)
+ goto fail;
+
+@@ -1467,7 +1453,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
+
+ /* Set up the endpoint ring */
+ virt_dev->eps[ep_index].new_ring =
+- xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags);
++ xhci_ring_alloc(xhci, 2, ring_type, max_packet, mem_flags);
+ if (!virt_dev->eps[ep_index].new_ring)
+ return -ENOMEM;
+
+@@ -2276,7 +2262,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
+ if (!ir)
+ return NULL;
+
+- ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags);
++ ir->event_ring = xhci_ring_alloc(xhci, segs, TYPE_EVENT, 0, flags);
+ if (!ir->event_ring) {
+ xhci_warn(xhci, "Failed to allocate interrupter event ring\n");
+ kfree(ir);
+@@ -2482,7 +2468,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+ goto fail;
+
+ /* Set up the command ring to have one segments for now. */
+- xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, 0, flags);
++ xhci->cmd_ring = xhci_ring_alloc(xhci, 1, TYPE_COMMAND, 0, flags);
+ if (!xhci->cmd_ring)
+ goto fail;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index d5bcd5475b72b1..3970ec831b8ca9 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -41,15 +41,15 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
+
+ static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
+ {
+- struct xhci_segment *seg = ring->first_seg;
++ struct xhci_segment *seg;
+
+ if (!td || !td->start_seg)
+ return false;
+- do {
++
++ xhci_for_each_ring_seg(ring->first_seg, seg) {
+ if (seg == td->start_seg)
+ return true;
+- seg = seg->next;
+- } while (seg && seg != ring->first_seg);
++ }
+
+ return false;
+ }
+@@ -764,16 +764,12 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
+ struct xhci_segment *seg;
+
+ ring = xhci->cmd_ring;
+- seg = ring->deq_seg;
+- do {
+- memset(seg->trbs, 0,
+- sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
+- seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
+- cpu_to_le32(~TRB_CYCLE);
+- seg = seg->next;
+- } while (seg != ring->deq_seg);
+-
+- xhci_initialize_ring_info(ring, 1);
++ xhci_for_each_ring_seg(ring->deq_seg, seg) {
++ memset(seg->trbs, 0, sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
++ seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= cpu_to_le32(~TRB_CYCLE);
++ }
++
++ xhci_initialize_ring_info(ring);
+ /*
+ * Reset the hardware dequeue pointer.
+ * Yes, this will need to be re-written after resume, but we're paranoid
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 67ee2e04994330..b2aeb444daaf5e 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1263,6 +1263,9 @@ static inline const char *xhci_trb_type_string(u8 type)
+ #define AVOID_BEI_INTERVAL_MIN 8
+ #define AVOID_BEI_INTERVAL_MAX 32
+
++#define xhci_for_each_ring_seg(head, seg) \
++ for (seg = head; seg != NULL; seg = (seg->next != head ? seg->next : NULL))
++
+ struct xhci_segment {
+ union xhci_trb *trbs;
+ /* private to HCD */
+@@ -1800,14 +1803,12 @@ void xhci_slot_copy(struct xhci_hcd *xhci,
+ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
+ struct usb_device *udev, struct usb_host_endpoint *ep,
+ gfp_t mem_flags);
+-struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
+- unsigned int num_segs, unsigned int cycle_state,
++struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_segs,
+ enum xhci_ring_type type, unsigned int max_packet, gfp_t flags);
+ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
+ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
+ unsigned int num_trbs, gfp_t flags);
+-void xhci_initialize_ring_info(struct xhci_ring *ring,
+- unsigned int cycle_state);
++void xhci_initialize_ring_info(struct xhci_ring *ring);
+ void xhci_free_endpoint_ring(struct xhci_hcd *xhci,
+ struct xhci_virt_device *virt_dev,
+ unsigned int ep_index);
+diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
+index ffa5b83d3a4a3a..14f96d217e6e1a 100644
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -1744,10 +1744,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 f917fdae7e672b..0022ad003791f4 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -1946,7 +1946,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/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 fee7bc9848a36a..b59647291363b6 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -298,8 +298,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 c0df2c1841243e..e06d02b68c5387 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -1958,7 +1958,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
+ }
+
+ 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))) {
+@@ -2489,10 +2489,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 57b6b191293eea..499f791df77998 100644
+--- a/fs/smb/client/misc.c
++++ b/fs/smb/client/misc.c
+@@ -829,33 +829,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);
+@@ -865,7 +860,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..b1548269c308a1 100644
+--- a/fs/smb/client/smbdirect.c
++++ b/fs/smb/client/smbdirect.c
+@@ -1075,8 +1075,10 @@ static int smbd_negotiate(struct smbd_connection *info)
+ 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;
+@@ -1308,6 +1310,9 @@ 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);
+diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
+index 67c989e5ddaa79..2fc689f99997e8 100644
+--- a/fs/smb/server/transport_rdma.c
++++ b/fs/smb/server/transport_rdma.c
+@@ -553,7 +553,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 <
+@@ -563,15 +563,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;
+
+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 61675ea95e0b98..f18f50d39598ff 100644
+--- a/include/linux/io_uring_types.h
++++ b/include/linux/io_uring_types.h
+@@ -37,6 +37,7 @@ enum io_uring_cmd_flags {
+ /* set when uring wants to cancel a previously issued command */
+ IO_URING_F_CANCEL = (1 << 11),
+ IO_URING_F_COMPAT = (1 << 12),
++ IO_URING_F_TASK_DEAD = (1 << 13),
+ };
+
+ struct io_wq_work_node {
+@@ -399,9 +400,6 @@ struct io_ring_ctx {
+ struct callback_head poll_wq_task_work;
+ struct list_head defer_list;
+
+- 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/minmax.h b/include/linux/minmax.h
+index 98008dd92153db..eaaf5c008e4d05 100644
+--- a/include/linux/minmax.h
++++ b/include/linux/minmax.h
+@@ -8,13 +8,10 @@
+ #include <linux/types.h>
+
+ /*
+- * min()/max()/clamp() macros must accomplish three things:
++ * min()/max()/clamp() macros must accomplish several things:
+ *
+ * - Avoid multiple evaluations of the arguments (so side-effects like
+ * "x++" happen only once) when non-constant.
+- * - Retain result as a constant expressions when called with only
+- * constant expressions (to avoid tripping VLA warnings in stack
+- * allocation usage).
+ * - Perform signed v unsigned type-checking (to generate compile
+ * errors instead of nasty runtime surprises).
+ * - Unsigned char/short are always promoted to signed int and can be
+@@ -31,58 +28,54 @@
+ * bit #0 set if ok for unsigned comparisons
+ * bit #1 set if ok for signed comparisons
+ *
+- * In particular, statically non-negative signed integer
+- * expressions are ok for both.
++ * In particular, statically non-negative signed integer expressions
++ * are ok for both.
+ *
+- * NOTE! Unsigned types smaller than 'int' are implicitly
+- * converted to 'int' in expressions, and are accepted for
+- * signed conversions for now. This is debatable.
++ * NOTE! Unsigned types smaller than 'int' are implicitly converted to 'int'
++ * in expressions, and are accepted for signed conversions for now.
++ * This is debatable.
+ *
+- * Note that 'x' is the original expression, and 'ux' is
+- * the unique variable that contains the value.
++ * Note that 'x' is the original expression, and 'ux' is the unique variable
++ * that contains the value.
+ *
+- * We use 'ux' for pure type checking, and 'x' for when
+- * we need to look at the value (but without evaluating
+- * it for side effects! Careful to only ever evaluate it
+- * with sizeof() or __builtin_constant_p() etc).
++ * We use 'ux' for pure type checking, and 'x' for when we need to look at the
++ * value (but without evaluating it for side effects!
++ * Careful to only ever evaluate it with sizeof() or __builtin_constant_p() etc).
+ *
+- * Pointers end up being checked by the normal C type
+- * rules at the actual comparison, and these expressions
+- * only need to be careful to not cause warnings for
+- * pointer use.
++ * Pointers end up being checked by the normal C type rules at the actual
++ * comparison, and these expressions only need to be careful to not cause
++ * warnings for pointer use.
+ */
+-#define __signed_type_use(x,ux) (2+__is_nonneg(x,ux))
+-#define __unsigned_type_use(x,ux) (1+2*(sizeof(ux)<4))
+-#define __sign_use(x,ux) (is_signed_type(typeof(ux))? \
+- __signed_type_use(x,ux):__unsigned_type_use(x,ux))
++#define __sign_use(ux) (is_signed_type(typeof(ux)) ? \
++ (2 + __is_nonneg(ux)) : (1 + 2 * (sizeof(ux) < 4)))
+
+ /*
+- * To avoid warnings about casting pointers to integers
+- * of different sizes, we need that special sign type.
++ * Check whether a signed value is always non-negative.
+ *
+- * On 64-bit we can just always use 'long', since any
+- * integer or pointer type can just be cast to that.
++ * A cast is needed to avoid any warnings from values that aren't signed
++ * integer types (in which case the result doesn't matter).
+ *
+- * This does not work for 128-bit signed integers since
+- * the cast would truncate them, but we do not use s128
+- * types in the kernel (we do use 'u128', but they will
+- * be handled by the !is_signed_type() case).
++ * On 64-bit any integer or pointer type can safely be cast to 'long long'.
++ * But on 32-bit we need to avoid warnings about casting pointers to integers
++ * of different sizes without truncating 64-bit values so 'long' or 'long long'
++ * must be used depending on the size of the value.
+ *
+- * NOTE! The cast is there only to avoid any warnings
+- * from when values that aren't signed integer types.
++ * This does not work for 128-bit signed integers since the cast would truncate
++ * them, but we do not use s128 types in the kernel (we do use 'u128',
++ * but they are handled by the !is_signed_type() case).
+ */
+-#ifdef CONFIG_64BIT
+- #define __signed_type(ux) long
++#if __SIZEOF_POINTER__ == __SIZEOF_LONG_LONG__
++#define __is_nonneg(ux) statically_true((long long)(ux) >= 0)
+ #else
+- #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L))
++#define __is_nonneg(ux) statically_true( \
++ (typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)))(ux) >= 0)
+ #endif
+-#define __is_nonneg(x,ux) statically_true((__signed_type(ux))(x)>=0)
+
+-#define __types_ok(x,y,ux,uy) \
+- (__sign_use(x,ux) & __sign_use(y,uy))
++#define __types_ok(ux, uy) \
++ (__sign_use(ux) & __sign_use(uy))
+
+-#define __types_ok3(x,y,z,ux,uy,uz) \
+- (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz))
++#define __types_ok3(ux, uy, uz) \
++ (__sign_use(ux) & __sign_use(uy) & __sign_use(uz))
+
+ #define __cmp_op_min <
+ #define __cmp_op_max >
+@@ -97,30 +90,13 @@
+
+ #define __careful_cmp_once(op, x, y, ux, uy) ({ \
+ __auto_type ux = (x); __auto_type uy = (y); \
+- BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \
++ BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \
+ #op"("#x", "#y") signedness error"); \
+ __cmp(op, ux, uy); })
+
+ #define __careful_cmp(op, x, y) \
+ __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
+
+-#define __clamp(val, lo, hi) \
+- ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
+-
+-#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \
+- __auto_type uval = (val); \
+- __auto_type ulo = (lo); \
+- __auto_type uhi = (hi); \
+- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
+- (lo) <= (hi), true), \
+- "clamp() low limit " #lo " greater than high limit " #hi); \
+- BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \
+- "clamp("#val", "#lo", "#hi") signedness error"); \
+- __clamp(uval, ulo, uhi); })
+-
+-#define __careful_clamp(val, lo, hi) \
+- __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
+-
+ /**
+ * min - return minimum of two values of the same or compatible types
+ * @x: first value
+@@ -154,7 +130,7 @@
+
+ #define __careful_op3(op, x, y, z, ux, uy, uz) ({ \
+ __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\
+- BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \
++ BUILD_BUG_ON_MSG(!__types_ok3(ux, uy, uz), \
+ #op"3("#x", "#y", "#z") signedness error"); \
+ __cmp(op, ux, __cmp(op, uy, uz)); })
+
+@@ -176,6 +152,22 @@
+ #define max3(x, y, z) \
+ __careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_))
+
++/**
++ * min_t - return minimum of two values, using the specified type
++ * @type: data type to use
++ * @x: first value
++ * @y: second value
++ */
++#define min_t(type, x, y) __cmp_once(min, type, x, y)
++
++/**
++ * max_t - return maximum of two values, using the specified type
++ * @type: data type to use
++ * @x: first value
++ * @y: second value
++ */
++#define max_t(type, x, y) __cmp_once(max, type, x, y)
++
+ /**
+ * min_not_zero - return the minimum that is _not_ zero, unless both are zero
+ * @x: value1
+@@ -186,39 +178,57 @@
+ typeof(y) __y = (y); \
+ __x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
+
++#define __clamp(val, lo, hi) \
++ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
++
++#define __clamp_once(type, val, lo, hi, uval, ulo, uhi) ({ \
++ type uval = (val); \
++ type ulo = (lo); \
++ type uhi = (hi); \
++ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \
++ "clamp() low limit " #lo " greater than high limit " #hi); \
++ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
++ "clamp("#val", "#lo", "#hi") signedness error"); \
++ __clamp(uval, ulo, uhi); })
++
++#define __careful_clamp(type, val, lo, hi) \
++ __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
++
+ /**
+- * clamp - return a value clamped to a given range with strict typechecking
++ * clamp - return a value clamped to a given range with typechecking
+ * @val: current value
+ * @lo: lowest allowable value
+ * @hi: highest allowable value
+ *
+- * This macro does strict typechecking of @lo/@hi to make sure they are of the
+- * same type as @val. See the unnecessary pointer comparisons.
+- */
+-#define clamp(val, lo, hi) __careful_clamp(val, lo, hi)
+-
+-/*
+- * ..and if you can't take the strict
+- * types, you can specify one yourself.
+- *
+- * Or not use min/max/clamp at all, of course.
++ * This macro checks @val/@lo/@hi to make sure they have compatible
++ * signedness.
+ */
++#define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)
+
+ /**
+- * min_t - return minimum of two values, using the specified type
+- * @type: data type to use
+- * @x: first value
+- * @y: second value
++ * clamp_t - return a value clamped to a given range using a given type
++ * @type: the type of variable to use
++ * @val: current value
++ * @lo: minimum allowable value
++ * @hi: maximum allowable value
++ *
++ * This macro does no typechecking and uses temporary variables of type
++ * @type to make all the comparisons.
+ */
+-#define min_t(type, x, y) __cmp_once(min, type, x, y)
++#define clamp_t(type, val, lo, hi) __careful_clamp(type, val, lo, hi)
+
+ /**
+- * max_t - return maximum of two values, using the specified type
+- * @type: data type to use
+- * @x: first value
+- * @y: second value
++ * clamp_val - return a value clamped to a given range using val's type
++ * @val: current value
++ * @lo: minimum allowable value
++ * @hi: maximum allowable value
++ *
++ * This macro does no typechecking and uses temporary variables of whatever
++ * type the input argument @val is. This is useful when @val is an unsigned
++ * type and @lo and @hi are literals that will otherwise be assigned a signed
++ * integer type.
+ */
+-#define max_t(type, x, y) __cmp_once(max, type, x, y)
++#define clamp_val(val, lo, hi) __careful_clamp(typeof(val), val, lo, hi)
+
+ /*
+ * Do not check the array parameter using __must_be_array().
+@@ -263,31 +273,6 @@
+ */
+ #define max_array(array, len) __minmax_array(max, array, len)
+
+-/**
+- * clamp_t - return a value clamped to a given range using a given type
+- * @type: the type of variable to use
+- * @val: current value
+- * @lo: minimum allowable value
+- * @hi: maximum allowable value
+- *
+- * This macro does no typechecking and uses temporary variables of type
+- * @type to make all the comparisons.
+- */
+-#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi))
+-
+-/**
+- * clamp_val - return a value clamped to a given range using val's type
+- * @val: current value
+- * @lo: minimum allowable value
+- * @hi: maximum allowable value
+- *
+- * This macro does no typechecking and uses temporary variables of whatever
+- * type the input argument @val is. This is useful when @val is an unsigned
+- * type and @lo and @hi are literals that will otherwise be assigned a signed
+- * integer type.
+- */
+-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
+-
+ static inline bool in_range64(u64 val, u64 start, u64 len)
+ {
+ return (val - start) < len;
+@@ -326,9 +311,9 @@ static inline bool in_range32(u32 val, u32 start, u32 len)
+ * Use these carefully: no type checking, and uses the arguments
+ * multiple times. Use for obvious constants only.
+ */
+-#define MIN(a,b) __cmp(min,a,b)
+-#define MAX(a,b) __cmp(max,a,b)
+-#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b))
+-#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b))
++#define MIN(a, b) __cmp(min, a, b)
++#define MAX(a, b) __cmp(max, a, b)
++#define MIN_T(type, a, b) __cmp(min, (type)(a), (type)(b))
++#define MAX_T(type, a, b) __cmp(max, (type)(a), (type)(b))
+
+ #endif /* _LINUX_MINMAX_H */
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index da9749739abde9..9a8eb644f6707d 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -689,6 +689,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/mm.h b/include/linux/mm.h
+index deeb535f920c8a..41f5c88bdf3bc9 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2200,6 +2200,61 @@ static inline bool folio_likely_mapped_shared(struct folio *folio)
+ return atomic_read(&folio->_mapcount) > 0;
+ }
+
++/**
++ * folio_expected_ref_count - calculate the expected folio refcount
++ * @folio: the folio
++ *
++ * Calculate the expected folio refcount, taking references from the pagecache,
++ * swapcache, PG_private and page table mappings into account. Useful in
++ * combination with folio_ref_count() to detect unexpected references (e.g.,
++ * GUP or other temporary references).
++ *
++ * Does currently not consider references from the LRU cache. If the folio
++ * was isolated from the LRU (which is the case during migration or split),
++ * the LRU cache does not apply.
++ *
++ * Calling this function on an unmapped folio -- !folio_mapped() -- that is
++ * locked will return a stable result.
++ *
++ * Calling this function on a mapped folio will not result in a stable result,
++ * because nothing stops additional page table mappings from coming (e.g.,
++ * fork()) or going (e.g., munmap()).
++ *
++ * Calling this function without the folio lock will also not result in a
++ * stable result: for example, the folio might get dropped from the swapcache
++ * concurrently.
++ *
++ * However, even when called without the folio lock or on a mapped folio,
++ * this function can be used to detect unexpected references early (for example,
++ * if it makes sense to even lock the folio and unmap it).
++ *
++ * The caller must add any reference (e.g., from folio_try_get()) it might be
++ * holding itself to the result.
++ *
++ * Returns the expected folio refcount.
++ */
++static inline int folio_expected_ref_count(const struct folio *folio)
++{
++ const int order = folio_order(folio);
++ int ref_count = 0;
++
++ if (WARN_ON_ONCE(folio_test_slab(folio)))
++ return 0;
++
++ if (folio_test_anon(folio)) {
++ /* One reference per page from the swapcache. */
++ ref_count += folio_test_swapcache(folio) << order;
++ } else if (!((unsigned long)folio->mapping & PAGE_MAPPING_FLAGS)) {
++ /* One reference per page from the pagecache. */
++ ref_count += !!folio->mapping << order;
++ /* One reference from PG_private. */
++ ref_count += folio_test_private(folio);
++ }
++
++ /* One reference per page table mapping. */
++ return ref_count + folio_mapcount(folio);
++}
++
+ #ifndef HAVE_ARCH_MAKE_FOLIO_ACCESSIBLE
+ static inline int arch_make_folio_accessible(struct folio *folio)
+ {
+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_uring.c b/io_uring/io_uring.c
+index 52ada466bf98f3..68439eb0dc8f35 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -316,9 +316,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
+ sizeof(struct io_async_rw));
+ ret |= io_alloc_cache_init(&ctx->uring_cache, IO_ALLOC_CACHE_MAX,
+ sizeof(struct uring_cache));
+- spin_lock_init(&ctx->msg_lock);
+- ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX,
+- sizeof(struct io_kiocb));
+ ret |= io_futex_cache_init(ctx);
+ if (ret)
+ goto free_ref;
+@@ -358,7 +355,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
+ 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->uring_cache, kfree);
+- io_alloc_cache_free(&ctx->msg_cache, io_msg_cache_free);
+ io_futex_cache_free(ctx);
+ kfree(ctx->cancel_table.hbs);
+ kfree(ctx->cancel_table_locked.hbs);
+@@ -1358,9 +1354,10 @@ static void io_req_task_cancel(struct io_kiocb *req, struct io_tw_state *ts)
+
+ void io_req_task_submit(struct io_kiocb *req, struct io_tw_state *ts)
+ {
+- io_tw_lock(req->ctx, ts);
+- /* req->task == current here, checking PF_EXITING is safe */
+- if (unlikely(req->task->flags & PF_EXITING))
++ struct io_ring_ctx *ctx = req->ctx;
++
++ io_tw_lock(ctx, ts);
++ 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);
+@@ -2742,7 +2739,6 @@ static __cold void io_ring_ctx_free(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->uring_cache, kfree);
+- io_alloc_cache_free(&ctx->msg_cache, io_msg_cache_free);
+ io_futex_cache_free(ctx);
+ io_destroy_buffers(ctx);
+ mutex_unlock(&ctx->uring_lock);
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 70b6675941ff76..e8a3b75bc6c683 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -421,6 +421,19 @@ static inline bool io_allowed_run_tw(struct io_ring_ctx *ctx)
+ ctx->submitter_task == current);
+ }
+
++/*
++ * Terminate the request if either of these conditions are true:
++ *
++ * 1) It's being executed by the original task, but that task is marked
++ * with PF_EXITING as it's exiting.
++ * 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(struct io_ring_ctx *ctx)
++{
++ 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)
+ {
+ io_req_set_res(req, res, 0);
+diff --git a/io_uring/kbuf.h b/io_uring/kbuf.h
+index 2586a292dfb914..a3ad8aea45c8a8 100644
+--- a/io_uring/kbuf.h
++++ b/io_uring/kbuf.h
+@@ -143,7 +143,7 @@ static inline bool io_kbuf_commit(struct io_kiocb *req,
+ struct io_uring_buf *buf;
+
+ buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
+- if (WARN_ON_ONCE(len > buf->len))
++ if (len > buf->len)
+ len = buf->len;
+ buf->len -= len;
+ if (buf->len) {
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index b68e009bce2180..97708e5132bc4f 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, struct io_tw_state *ts)
+ 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,19 +97,6 @@ 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_kiocb *req)
+ {
+ struct io_ring_ctx *target_ctx = req->file->private_data;
+@@ -124,7 +104,7 @@ static int io_msg_data_remote(struct io_kiocb *req)
+ struct io_kiocb *target;
+ u32 flags = 0;
+
+- target = io_msg_get_kiocb(req->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 28859ae3ee6eb9..d4cf5a1328e639 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 17dea8aa09c9b3..bfdb537572f7ff 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -265,8 +265,7 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts)
+ {
+ int v;
+
+- /* req->task == current here, checking PF_EXITING is safe */
+- if (unlikely(req->task->flags & PF_EXITING))
++ if (unlikely(io_should_terminate_tw(req->ctx)))
+ return -ECANCELED;
+
+ do {
+diff --git a/io_uring/timeout.c b/io_uring/timeout.c
+index 21c4bfea79f1c9..b215b2fbddd01d 100644
+--- a/io_uring/timeout.c
++++ b/io_uring/timeout.c
+@@ -303,7 +303,7 @@ static void io_req_task_link_timeout(struct io_kiocb *req, struct io_tw_state *t
+ int ret = -ENOENT;
+
+ if (prev) {
+- if (!(req->task->flags & PF_EXITING)) {
++ 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 b2ce4b56100271..f927844c8ada79 100644
+--- a/io_uring/uring_cmd.c
++++ b/io_uring/uring_cmd.c
+@@ -116,9 +116,13 @@ EXPORT_SYMBOL_GPL(io_uring_cmd_mark_cancelable);
+ static void io_uring_cmd_work(struct io_kiocb *req, struct io_tw_state *ts)
+ {
+ 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(req->ctx))
++ flags |= IO_URING_F_TASK_DEAD;
+
+ /* task_work executor checks the deffered list completion */
+- ioucmd->task_work_cb(ioucmd, IO_URING_F_COMPLETE_DEFER);
++ ioucmd->task_work_cb(ioucmd, flags);
+ }
+
+ void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index 62933468aaf46c..5fc2801ee921cc 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -123,8 +123,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,
+@@ -5541,7 +5564,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)
+@@ -5550,7 +5573,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,
+@@ -5685,7 +5708,7 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
+ err_free_css:
+ list_del_rcu(&css->rstat_css_node);
+ 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);
+ }
+
+@@ -5918,7 +5941,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);
+ }
+ }
+
+@@ -6296,8 +6319,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/mm/gup.c b/mm/gup.c
+index e323843cc5dd80..e9be7c49542a0f 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -2323,6 +2323,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.
+ */
+@@ -2330,16 +2355,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;
++ unsigned long collected = 0;
+ bool drain_allow = true;
++ struct folio *folio;
++ long i = 0;
+
+- for (i = 0; i < pofs->nr_entries; i++) {
+- struct folio *folio = pofs_get_folio(pofs, i);
+-
+- 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;
+@@ -2354,7 +2376,8 @@ static unsigned long collect_longterm_unpinnable_folios(
+ continue;
+ }
+
+- if (!folio_test_lru(folio) && drain_allow) {
++ if (drain_allow && folio_ref_count(folio) !=
++ folio_expected_ref_count(folio) + 1) {
+ lru_add_drain_all();
+ drain_allow = false;
+ }
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 25e7438af968a4..8619aa884eaa87 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -453,20 +453,6 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
+ }
+ #endif
+
+-static int folio_expected_refs(struct address_space *mapping,
+- struct folio *folio)
+-{
+- int refs = 1;
+- if (!mapping)
+- return refs;
+-
+- refs += folio_nr_pages(folio);
+- if (folio_test_private(folio))
+- refs++;
+-
+- return refs;
+-}
+-
+ /*
+ * Replace the folio in the mapping.
+ *
+@@ -609,7 +595,7 @@ static int __folio_migrate_mapping(struct address_space *mapping,
+ int folio_migrate_mapping(struct address_space *mapping,
+ struct folio *newfolio, struct folio *folio, int extra_count)
+ {
+- int expected_count = folio_expected_refs(mapping, folio) + extra_count;
++ int expected_count = folio_expected_ref_count(folio) + extra_count + 1;
+
+ if (folio_ref_count(folio) != expected_count)
+ return -EAGAIN;
+@@ -626,7 +612,7 @@ int migrate_huge_page_move_mapping(struct address_space *mapping,
+ struct folio *dst, struct folio *src)
+ {
+ XA_STATE(xas, &mapping->i_pages, folio_index(src));
+- int rc, expected_count = folio_expected_refs(mapping, src);
++ int rc, expected_count = folio_expected_ref_count(src) + 1;
+
+ if (folio_ref_count(src) != expected_count)
+ return -EAGAIN;
+@@ -756,7 +742,7 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst,
+ struct folio *src, void *src_private,
+ enum migrate_mode mode)
+ {
+- int rc, expected_count = folio_expected_refs(mapping, src);
++ int rc, expected_count = folio_expected_ref_count(src) + 1;
+
+ /* Check whether src does not have extra refs before we do more work */
+ if (folio_ref_count(src) != expected_count)
+@@ -844,7 +830,7 @@ static int __buffer_migrate_folio(struct address_space *mapping,
+ return migrate_folio(mapping, dst, src, mode);
+
+ /* Check whether page does not have extra refs before we do more work */
+- expected_count = folio_expected_refs(mapping, src);
++ expected_count = folio_expected_ref_count(src) + 1;
+ if (folio_ref_count(src) != expected_count)
+ return -EAGAIN;
+
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index e3c1e2e1560d75..0ceed77af0fbdf 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -4352,7 +4352,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 156da81bce068e..988992ff898b3d 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3286,6 +3286,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)
+@@ -3400,6 +3401,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 d1c10f5f951604..69de9fdd779f28 100644
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -1388,7 +1388,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 caedc939eea19e..c745de0aae7762 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1120,7 +1120,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) &&
+@@ -1236,6 +1236,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;
+@@ -1283,6 +1284,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;
+@@ -1411,6 +1413,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 7d4718a57bdccd..479a3bfa87aa2e 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -985,13 +985,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 b763729b85e0a6..463c2e7956d52e 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -2211,6 +2211,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;
+@@ -2218,6 +2219,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 d865d08a0c5eda..dde097502230d2 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -413,6 +413,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)
+ {
+@@ -437,6 +451,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;
+ }
+@@ -605,6 +620,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 a05f201d194c52..17d1a9d8b0e98b 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -888,6 +888,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 a8e21060112ffd..2b27d4fe9d3632 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/tls/tls.h b/net/tls/tls.h
+index e1eaf12b374264..fca0c0e1700478 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 ee92ce3255f936..f46550b96061ea 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -2440,8 +2440,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/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 eb0e404c178411..5f061d2d9fc969 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10666,6 +10666,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/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
+index 8a532f7d750c8b..808a4d4b6f80b3 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 0ee3655cad01fb..c0a8fc867301c2 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 9c98a35ad09945..b46aff1110e143 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/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
+index 3ac63ce67ab1ce..24f3cc7676142b 100644
+--- a/sound/soc/sof/intel/hda-stream.c
++++ b/sound/soc/sof/intel/hda-stream.c
+@@ -864,7 +864,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/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 69b66994f2a155..5687c4996517c8 100644
+--- a/tools/objtool/arch/loongarch/decode.c
++++ b/tools/objtool/arch/loongarch/decode.c
+@@ -281,6 +281,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)
+@@ -312,11 +331,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/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+index c83a8b47bbdfa5..fc9eff0e89e226 100644
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
+@@ -1079,6 +1079,7 @@ int main_loop_s(int listensock)
+ struct pollfd polls;
+ socklen_t salen;
+ int remotesock;
++ int err = 0;
+ int fd = 0;
+
+ again:
+@@ -1111,7 +1112,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;
+@@ -1120,10 +1121,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)
+@@ -1233,7 +1234,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))
+@@ -1243,7 +1244,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 926b0be87c9905..1dc2bd6ee4a50e 100644
+--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
++++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+@@ -658,22 +658,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 3651f73451cf8b..cc682bf675b2b6 100755
+--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
++++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
+@@ -173,6 +173,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"
+
+@@ -195,23 +198,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
next reply other threads:[~2025-09-25 12:02 UTC|newest]
Thread overview: 79+ 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-15 17:30 [gentoo-commits] proj/linux-patches:6.12 commit in: / Arisu Tachibana
2025-10-13 11:56 Arisu Tachibana
2025-10-06 11:06 Arisu Tachibana
2025-10-02 13:25 Arisu Tachibana
2025-09-20 6:14 Arisu Tachibana
2025-09-20 5:26 Arisu Tachibana
2025-09-12 3:56 Arisu Tachibana
2025-09-10 6:21 Arisu Tachibana
2025-09-10 5:31 Arisu Tachibana
2025-09-05 12:48 Arisu Tachibana
2025-09-04 15:48 Arisu Tachibana
2025-09-04 15:33 Arisu Tachibana
2025-08-28 15:24 Arisu Tachibana
2025-08-28 13:54 Arisu Tachibana
2025-08-28 13:27 Arisu Tachibana
2025-08-28 11:49 Arisu Tachibana
2025-08-21 1:11 Arisu Tachibana
2025-08-16 3:10 Arisu Tachibana
2025-08-01 10:31 Arisu Tachibana
2025-07-18 12:05 Arisu Tachibana
2025-07-14 16:20 Arisu Tachibana
2025-07-11 2:28 Arisu Tachibana
2025-07-06 13:42 Arisu Tachibana
2025-06-27 11:26 Mike Pagano
2025-06-27 11:17 Mike Pagano
2025-06-19 14:22 Mike Pagano
2025-06-10 12:15 Mike Pagano
2025-06-04 18:10 Mike Pagano
2025-05-29 16:35 Mike Pagano
2025-05-27 20:05 Mike Pagano
2025-05-22 13:37 Mike Pagano
2025-05-18 14:32 Mike Pagano
2025-05-09 10:57 Mike Pagano
2025-05-05 11:31 Mike Pagano
2025-05-02 11:35 Mike Pagano
2025-04-25 11:54 Mike Pagano
2025-04-25 11:47 Mike Pagano
2025-04-22 18:48 Mike Pagano
2025-04-20 9:38 Mike Pagano
2025-04-10 13:50 Mike Pagano
2025-04-10 13:29 Mike Pagano
2025-04-07 10:30 Mike Pagano
2025-03-29 10:59 Mike Pagano
2025-03-29 10:47 Mike Pagano
2025-03-23 11:31 Mike Pagano
2025-03-20 22:39 Mike Pagano
2025-03-13 12:54 Mike Pagano
2025-03-07 18:22 Mike Pagano
2025-02-27 13:22 Mike Pagano
2025-02-21 13:31 Mike Pagano
2025-02-18 11:26 Mike Pagano
2025-02-17 15:44 Mike Pagano
2025-02-17 11:25 Mike Pagano
2025-02-17 11:16 Mike Pagano
2025-02-16 21:48 Mike Pagano
2025-02-08 11:26 Mike Pagano
2025-02-01 23:07 Mike Pagano
2025-01-30 12:47 Mike Pagano
2025-01-23 17:02 Mike Pagano
2025-01-17 13:18 Mike Pagano
2025-01-17 13:18 Mike Pagano
2025-01-09 13:51 Mike Pagano
2025-01-02 12:31 Mike Pagano
2024-12-27 14:08 Mike Pagano
2024-12-19 18:07 Mike Pagano
2024-12-15 0:02 Mike Pagano
2024-12-14 23:59 Mike Pagano
2024-12-14 23:47 Mike Pagano
2024-12-11 21:01 Mike Pagano
2024-12-09 23:13 Mike Pagano
2024-12-09 11:35 Mike Pagano
2024-12-06 12:44 Mike Pagano
2024-12-05 20:05 Mike Pagano
2024-12-05 14:06 Mike Pagano
2024-12-02 17:15 Mike Pagano
2024-11-30 17:33 Mike Pagano
2024-11-22 17:45 Mike Pagano
2024-11-21 13:12 Mike Pagano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1758801746.58abc47e9289b91e71cb97f5a3d77336d0fc9948.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