commit: 14d311c73d3eac20ff67e8b6c935fb69f0b4fd20 Author: Arisu Tachibana <alicef <AT> gentoo <DOT> org> AuthorDate: Fri Aug 1 10:31:15 2025 +0000 Commit: Arisu Tachibana <alicef <AT> gentoo <DOT> org> CommitDate: Fri Aug 1 10:31:15 2025 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=14d311c7
Linux patch 6.6.101 Signed-off-by: Arisu Tachibana <alicef <AT> gentoo.org> 0000_README | 4 + 1100_linux-6.6.101.patch | 3102 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3106 insertions(+) diff --git a/0000_README b/0000_README index ade2cd5b..68e18812 100644 --- a/0000_README +++ b/0000_README @@ -443,6 +443,10 @@ Patch: 1099_linux-6.6.100.patch From: https://www.kernel.org Desc: Linux 6.6.100 +Patch: 1100_linux-6.6.101.patch +From: https://www.kernel.org +Desc: Linux 6.6.101 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch Desc: Enable link security restrictions by default. diff --git a/1100_linux-6.6.101.patch b/1100_linux-6.6.101.patch new file mode 100644 index 00000000..f5531955 --- /dev/null +++ b/1100_linux-6.6.101.patch @@ -0,0 +1,3102 @@ +diff --git a/Makefile b/Makefile +index 8d6550abc9cb2c..116eb523392a23 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 100 ++SUBLEVEL = 101 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 5ba42f69f8ce0c..351d0b039b5ca6 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -142,7 +142,7 @@ endif + # Need -Uarm for gcc < 3.x + KBUILD_CPPFLAGS +=$(cpp-y) + KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm +-KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include asm/unified.h -msoft-float ++KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include $(srctree)/arch/arm/include/asm/unified.h -msoft-float + + CHECKFLAGS += -D__arm__ + +diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h +index 376a980f2bad08..0fa067c2324de9 100644 +--- a/arch/arm64/include/asm/assembler.h ++++ b/arch/arm64/include/asm/assembler.h +@@ -45,6 +45,11 @@ + /* + * Save/restore interrupts. + */ ++ .macro save_and_disable_daif, flags ++ mrs \flags, daif ++ msr daifset, #0xf ++ .endm ++ + .macro save_and_disable_irq, flags + mrs \flags, daif + msr daifset, #3 +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index b6d381f743f3ec..2ce9ef9d924aac 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -364,6 +364,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { + }; + + static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { ++ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_ECBHB_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_TIDCP1_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_HCX_SHIFT, 4, 0), +diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S +index 7fcbee0f6c0e4e..60a3cf3da7181d 100644 +--- a/arch/arm64/kernel/entry.S ++++ b/arch/arm64/kernel/entry.S +@@ -824,6 +824,7 @@ SYM_CODE_END(__bp_harden_el1_vectors) + * + */ + SYM_FUNC_START(cpu_switch_to) ++ save_and_disable_daif x11 + mov x10, #THREAD_CPU_CONTEXT + add x8, x0, x10 + mov x9, sp +@@ -847,6 +848,7 @@ SYM_FUNC_START(cpu_switch_to) + ptrauth_keys_install_kernel x1, x8, x9, x10 + scs_save x0 + scs_load_current ++ restore_irq x11 + ret + SYM_FUNC_END(cpu_switch_to) + NOKPROBE(cpu_switch_to) +@@ -873,6 +875,7 @@ NOKPROBE(ret_from_fork) + * Calls func(regs) using this CPU's irq stack and shadow irq stack. + */ + SYM_FUNC_START(call_on_irq_stack) ++ save_and_disable_daif x9 + #ifdef CONFIG_SHADOW_CALL_STACK + get_current_task x16 + scs_save x16 +@@ -887,8 +890,10 @@ SYM_FUNC_START(call_on_irq_stack) + + /* Move to the new stack and call the function there */ + add sp, x16, #IRQ_STACK_SIZE ++ restore_irq x9 + blr x1 + ++ save_and_disable_daif x9 + /* + * Restore the SP from the FP, and restore the FP and LR from the frame + * record. +@@ -896,6 +901,7 @@ SYM_FUNC_START(call_on_irq_stack) + mov sp, x29 + ldp x29, x30, [sp], #16 + scs_load_current ++ restore_irq x9 + ret + SYM_FUNC_END(call_on_irq_stack) + NOKPROBE(call_on_irq_stack) +diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig +index fccf742c55c2c3..5c1619f2518853 100644 +--- a/arch/powerpc/crypto/Kconfig ++++ b/arch/powerpc/crypto/Kconfig +@@ -129,6 +129,7 @@ config CRYPTO_CHACHA20_P10 + config CRYPTO_POLY1305_P10 + tristate "Hash functions: Poly1305 (P10 or later)" + depends on PPC64 && CPU_LITTLE_ENDIAN && VSX ++ depends on BROKEN # Needs to be fixed to work in softirq context + select CRYPTO_HASH + select CRYPTO_LIB_POLY1305_GENERIC + help +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 835c9febb6a854..87ea4339e03a28 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -2734,7 +2734,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/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c +index 42c70d28ef272d..865ae4be233b37 100644 +--- a/arch/x86/hyperv/irqdomain.c ++++ b/arch/x86/hyperv/irqdomain.c +@@ -192,7 +192,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) + struct pci_dev *dev; + struct hv_interrupt_entry out_entry, *stored_entry; + struct irq_cfg *cfg = irqd_cfg(data); +- const cpumask_t *affinity; + int cpu; + u64 status; + +@@ -204,8 +203,7 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) + return; + } + +- affinity = irq_data_get_effective_affinity_mask(data); +- cpu = cpumask_first_and(affinity, cpu_online_mask); ++ cpu = cpumask_first(irq_data_get_effective_affinity_mask(data)); + + if (data->chip_data) { + /* +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 5fcdfbb792bd9f..864d62e9461418 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -549,6 +549,8 @@ static bool amd_check_tsa_microcode(void) + p.model = c->x86_model; + p.ext_model = c->x86_model >> 4; + p.stepping = c->x86_stepping; ++ /* reserved bits are expected to be 0 in test below */ ++ p.__reserved = 0; + + if (cpu_has(c, X86_FEATURE_ZEN3) || + cpu_has(c, X86_FEATURE_ZEN4)) { +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 3011f7f9381b7f..1209e01f8c7f97 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1173,6 +1173,8 @@ struct regmap *__regmap_init(struct device *dev, + err_map: + kfree(map); + err: ++ if (bus && bus->free_on_exit) ++ kfree(bus); + return ERR_PTR(ret); + } + EXPORT_SYMBOL_GPL(__regmap_init); +diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c +index b405ee330af1fc..350e7b24ee2b09 100644 +--- a/drivers/bus/fsl-mc/fsl-mc-bus.c ++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c +@@ -942,6 +942,7 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev, + struct fsl_mc_obj_desc endpoint_desc = {{ 0 }}; + struct dprc_endpoint endpoint1 = {{ 0 }}; + struct dprc_endpoint endpoint2 = {{ 0 }}; ++ struct fsl_mc_bus *mc_bus; + int state, err; + + mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); +@@ -965,6 +966,8 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev, + strcpy(endpoint_desc.type, endpoint2.type); + endpoint_desc.id = endpoint2.id; + endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev); ++ if (endpoint) ++ return endpoint; + + /* + * We know that the device has an endpoint because we verified by +@@ -972,17 +975,13 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev, + * yet discovered by the fsl-mc bus, thus the lookup returned NULL. + * Force a rescan of the devices in this container and retry the lookup. + */ +- if (!endpoint) { +- struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); +- +- if (mutex_trylock(&mc_bus->scan_mutex)) { +- err = dprc_scan_objects(mc_bus_dev, true); +- mutex_unlock(&mc_bus->scan_mutex); +- } +- +- if (err < 0) +- return ERR_PTR(err); ++ mc_bus = to_fsl_mc_bus(mc_bus_dev); ++ if (mutex_trylock(&mc_bus->scan_mutex)) { ++ err = dprc_scan_objects(mc_bus_dev, true); ++ mutex_unlock(&mc_bus->scan_mutex); + } ++ if (err < 0) ++ return ERR_PTR(err); + + endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev); + /* +diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c +index 05ae9122823f80..e713ef611434da 100644 +--- a/drivers/comedi/drivers/comedi_test.c ++++ b/drivers/comedi/drivers/comedi_test.c +@@ -790,7 +790,7 @@ static void waveform_detach(struct comedi_device *dev) + { + struct waveform_private *devpriv = dev->private; + +- if (devpriv) { ++ if (devpriv && dev->n_subdevices) { + del_timer_sync(&devpriv->ai_timer); + del_timer_sync(&devpriv->ao_timer); + } +diff --git a/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c b/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c +index 1e748e8ce12d5d..b68903212b6404 100644 +--- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c +@@ -27,12 +27,14 @@ MODULE_DEVICE_TABLE(pci, adf_pci_tbl); + + static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent); + static void adf_remove(struct pci_dev *dev); ++static void adf_shutdown(struct pci_dev *dev); + + static struct pci_driver adf_driver = { + .id_table = adf_pci_tbl, + .name = ADF_DH895XCC_DEVICE_NAME, + .probe = adf_probe, + .remove = adf_remove, ++ .shutdown = adf_shutdown, + .sriov_configure = adf_sriov_configure, + .err_handler = &adf_err_handler, + }; +@@ -227,6 +229,13 @@ static void adf_remove(struct pci_dev *pdev) + kfree(accel_dev); + } + ++static void adf_shutdown(struct pci_dev *pdev) ++{ ++ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); ++ ++ adf_dev_down(accel_dev, false); ++} ++ + static int __init adfdrv_init(void) + { + request_module("intel_qat"); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index 6b7c6f45a80a86..b77b4723323164 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -1130,13 +1130,12 @@ svm_range_split_head(struct svm_range *prange, + } + + static void +-svm_range_add_child(struct svm_range *prange, struct mm_struct *mm, +- struct svm_range *pchild, enum svm_work_list_ops op) ++svm_range_add_child(struct svm_range *prange, struct svm_range *pchild, enum svm_work_list_ops op) + { + pr_debug("add child 0x%p [0x%lx 0x%lx] to prange 0x%p child list %d\n", + pchild, pchild->start, pchild->last, prange, op); + +- pchild->work_item.mm = mm; ++ pchild->work_item.mm = NULL; + pchild->work_item.op = op; + list_add_tail(&pchild->child_list, &prange->child_list); + } +@@ -1182,14 +1181,14 @@ svm_range_split_by_granularity(struct kfd_process *p, struct mm_struct *mm, + r = svm_range_split(prange, start, prange->last, &head); + if (r) + return r; +- svm_range_add_child(parent, mm, head, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_ADD_RANGE); + } + + if (last < prange->last) { + r = svm_range_split(prange, prange->start, last, &tail); + if (r) + return r; +- svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_ADD_RANGE); + } + + /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */ +@@ -2393,15 +2392,17 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange, + prange->work_item.op != SVM_OP_UNMAP_RANGE) + prange->work_item.op = op; + } else { +- prange->work_item.op = op; +- +- /* Pairs with mmput in deferred_list_work */ +- mmget(mm); +- prange->work_item.mm = mm; +- list_add_tail(&prange->deferred_list, +- &prange->svms->deferred_range_list); +- pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n", +- prange, prange->start, prange->last, op); ++ /* Pairs with mmput in deferred_list_work. ++ * If process is exiting and mm is gone, don't update mmu notifier. ++ */ ++ if (mmget_not_zero(mm)) { ++ prange->work_item.mm = mm; ++ prange->work_item.op = op; ++ list_add_tail(&prange->deferred_list, ++ &prange->svms->deferred_range_list); ++ pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n", ++ prange, prange->start, prange->last, op); ++ } + } + spin_unlock(&svms->deferred_list_lock); + } +@@ -2415,8 +2416,7 @@ void schedule_deferred_list_work(struct svm_range_list *svms) + } + + static void +-svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent, +- struct svm_range *prange, unsigned long start, ++svm_range_unmap_split(struct svm_range *parent, struct svm_range *prange, unsigned long start, + unsigned long last) + { + struct svm_range *head; +@@ -2437,12 +2437,12 @@ svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent, + svm_range_split(tail, last + 1, tail->last, &head); + + if (head != prange && tail != prange) { +- svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE); +- svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_ADD_RANGE); + } else if (tail != prange) { +- svm_range_add_child(parent, mm, tail, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, tail, SVM_OP_UNMAP_RANGE); + } else if (head != prange) { +- svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE); ++ svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE); + } else if (parent != prange) { + prange->work_item.op = SVM_OP_UNMAP_RANGE; + } +@@ -2481,14 +2481,14 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange, + l = min(last, pchild->last); + if (l >= s) + svm_range_unmap_from_gpus(pchild, s, l, trigger); +- svm_range_unmap_split(mm, prange, pchild, start, last); ++ svm_range_unmap_split(prange, pchild, start, last); + mutex_unlock(&pchild->lock); + } + s = max(start, prange->start); + l = min(last, prange->last); + if (l >= s) + svm_range_unmap_from_gpus(prange, s, l, trigger); +- svm_range_unmap_split(mm, prange, prange, start, last); ++ svm_range_unmap_split(prange, prange, start, last); + + if (unmap_parent) + svm_range_add_list_work(svms, prange, mm, SVM_OP_UNMAP_RANGE); +@@ -2531,8 +2531,6 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, + + if (range->event == MMU_NOTIFY_RELEASE) + return true; +- if (!mmget_not_zero(mni->mm)) +- return true; + + start = mni->interval_tree.start; + last = mni->interval_tree.last; +@@ -2559,7 +2557,6 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, + } + + svm_range_unlock(prange); +- mmput(mni->mm); + + return true; + } +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index 002f8aaa509bc9..59cbff209acd6e 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -1352,7 +1352,7 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, + HPD_DISABLE, 0); + mutex_unlock(&pdata->comms_mutex); +- }; ++ } + + drm_bridge_add(&pdata->bridge); + +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index c8b6d0f79c9b41..9a894e234f6239 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -1293,6 +1293,12 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) + void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, + u8 *link_bw, u8 *rate_select) + { ++ struct drm_i915_private *i915 = dp_to_i915(intel_dp); ++ ++ /* FIXME g4x can't generate an exact 2.7GHz with the 96MHz non-SSC refclk */ ++ if (IS_G4X(i915) && port_clock == 268800) ++ port_clock = 270000; ++ + /* eDP 1.4 rate select method. */ + if (intel_dp->use_rate_select) { + *link_bw = 0; +diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c +index eed3b8bed9e40f..245a1ef5278e88 100644 +--- a/drivers/gpu/drm/scheduler/sched_entity.c ++++ b/drivers/gpu/drm/scheduler/sched_entity.c +@@ -346,20 +346,9 @@ void drm_sched_entity_destroy(struct drm_sched_entity *entity) + } + EXPORT_SYMBOL(drm_sched_entity_destroy); + +-/* drm_sched_entity_clear_dep - callback to clear the entities dependency */ +-static void drm_sched_entity_clear_dep(struct dma_fence *f, +- struct dma_fence_cb *cb) +-{ +- struct drm_sched_entity *entity = +- container_of(cb, struct drm_sched_entity, cb); +- +- entity->dependency = NULL; +- dma_fence_put(f); +-} +- + /* +- * drm_sched_entity_clear_dep - callback to clear the entities dependency and +- * wake up scheduler ++ * drm_sched_entity_wakeup - callback to clear the entity's dependency and ++ * wake up the scheduler + */ + static void drm_sched_entity_wakeup(struct dma_fence *f, + struct dma_fence_cb *cb) +@@ -367,7 +356,8 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, + struct drm_sched_entity *entity = + container_of(cb, struct drm_sched_entity, cb); + +- drm_sched_entity_clear_dep(f, cb); ++ entity->dependency = NULL; ++ dma_fence_put(f); + drm_sched_wakeup_if_can_queue(entity->rq->sched); + } + +@@ -420,13 +410,6 @@ static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity) + fence = dma_fence_get(&s_fence->scheduled); + dma_fence_put(entity->dependency); + entity->dependency = fence; +- if (!dma_fence_add_callback(fence, &entity->cb, +- drm_sched_entity_clear_dep)) +- return true; +- +- /* Ignore it when it is already scheduled */ +- dma_fence_put(fence); +- return false; + } + + if (!dma_fence_add_callback(entity->dependency, &entity->cb, +diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c +index ee92a315f074fe..f324f397356c2b 100644 +--- a/drivers/i2c/busses/i2c-qup.c ++++ b/drivers/i2c/busses/i2c-qup.c +@@ -452,8 +452,10 @@ static int qup_i2c_bus_active(struct qup_i2c_dev *qup, int len) + if (!(status & I2C_STATUS_BUS_ACTIVE)) + break; + +- if (time_after(jiffies, timeout)) ++ if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; ++ break; ++ } + + usleep_range(len, len * 2); + } +diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c +index 08a81daedc115e..5766231b13cd17 100644 +--- a/drivers/i2c/busses/i2c-tegra.c ++++ b/drivers/i2c/busses/i2c-tegra.c +@@ -607,7 +607,6 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev) + static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) + { + u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode; +- acpi_handle handle = ACPI_HANDLE(i2c_dev->dev); + struct i2c_timings *t = &i2c_dev->timings; + int err; + +@@ -619,11 +618,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) + * emit a noisy warning on error, which won't stay unnoticed and + * won't hose machine entirely. + */ +- if (handle) +- err = acpi_evaluate_object(handle, "_RST", NULL, NULL); +- else +- err = reset_control_reset(i2c_dev->rst); +- ++ err = device_reset(i2c_dev->dev); + WARN_ON_ONCE(err); + + if (IS_DVC(i2c_dev)) +@@ -1668,19 +1663,6 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev) + i2c_dev->is_vi = true; + } + +-static int tegra_i2c_init_reset(struct tegra_i2c_dev *i2c_dev) +-{ +- if (ACPI_HANDLE(i2c_dev->dev)) +- return 0; +- +- i2c_dev->rst = devm_reset_control_get_exclusive(i2c_dev->dev, "i2c"); +- if (IS_ERR(i2c_dev->rst)) +- return dev_err_probe(i2c_dev->dev, PTR_ERR(i2c_dev->rst), +- "failed to get reset control\n"); +- +- return 0; +-} +- + static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev) + { + int err; +@@ -1790,10 +1772,6 @@ static int tegra_i2c_probe(struct platform_device *pdev) + + tegra_i2c_parse_dt(i2c_dev); + +- err = tegra_i2c_init_reset(i2c_dev); +- if (err) +- return err; +- + err = tegra_i2c_init_clocks(i2c_dev); + if (err) + return err; +diff --git a/drivers/i2c/busses/i2c-virtio.c b/drivers/i2c/busses/i2c-virtio.c +index c60ae531ba57c7..726c162cabd868 100644 +--- a/drivers/i2c/busses/i2c-virtio.c ++++ b/drivers/i2c/busses/i2c-virtio.c +@@ -116,15 +116,16 @@ static int virtio_i2c_complete_reqs(struct virtqueue *vq, + for (i = 0; i < num; i++) { + struct virtio_i2c_req *req = &reqs[i]; + +- wait_for_completion(&req->completion); +- +- if (!failed && req->in_hdr.status != VIRTIO_I2C_MSG_OK) +- failed = true; ++ if (!failed) { ++ if (wait_for_completion_interruptible(&req->completion)) ++ failed = true; ++ else if (req->in_hdr.status != VIRTIO_I2C_MSG_OK) ++ failed = true; ++ else ++ j++; ++ } + + i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed); +- +- if (!failed) +- j++; + } + + return j; +diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c +index edd0c3a35ab73c..202561cad4012b 100644 +--- a/drivers/iio/adc/ad7949.c ++++ b/drivers/iio/adc/ad7949.c +@@ -308,7 +308,6 @@ static void ad7949_disable_reg(void *reg) + + static int ad7949_spi_probe(struct spi_device *spi) + { +- u32 spi_ctrl_mask = spi->controller->bits_per_word_mask; + struct device *dev = &spi->dev; + const struct ad7949_adc_spec *spec; + struct ad7949_adc_chip *ad7949_adc; +@@ -337,11 +336,11 @@ static int ad7949_spi_probe(struct spi_device *spi) + ad7949_adc->resolution = spec->resolution; + + /* Set SPI bits per word */ +- if (spi_ctrl_mask & SPI_BPW_MASK(ad7949_adc->resolution)) { ++ if (spi_is_bpw_supported(spi, ad7949_adc->resolution)) { + spi->bits_per_word = ad7949_adc->resolution; +- } else if (spi_ctrl_mask == SPI_BPW_MASK(16)) { ++ } else if (spi_is_bpw_supported(spi, 16)) { + spi->bits_per_word = 16; +- } else if (spi_ctrl_mask == SPI_BPW_MASK(8)) { ++ } else if (spi_is_bpw_supported(spi, 8)) { + spi->bits_per_word = 8; + } else { + dev_err(dev, "unable to find common BPW with spi controller\n"); +diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c +index a47591e1bad9da..24f73279075393 100644 +--- a/drivers/iio/light/hid-sensor-prox.c ++++ b/drivers/iio/light/hid-sensor-prox.c +@@ -102,8 +102,7 @@ static int prox_read_raw(struct iio_dev *indio_dev, + ret_type = prox_state->scale_precision; + break; + case IIO_CHAN_INFO_OFFSET: +- *val = hid_sensor_convert_exponent( +- prox_state->prox_attr.unit_expo); ++ *val = 0; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: +@@ -227,6 +226,11 @@ static int prox_parse_report(struct platform_device *pdev, + dev_dbg(&pdev->dev, "prox %x:%x\n", st->prox_attr.index, + st->prox_attr.report_id); + ++ st->scale_precision = hid_sensor_format_scale(hsdev->usage, ++ &st->prox_attr, ++ &st->scale_pre_decml, ++ &st->scale_post_decml); ++ + return ret; + } + +diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c +index 0b88203720b059..77c0b89259911f 100644 +--- a/drivers/infiniband/core/cache.c ++++ b/drivers/infiniband/core/cache.c +@@ -582,8 +582,8 @@ static int __ib_cache_gid_add(struct ib_device *ib_dev, u32 port, + out_unlock: + mutex_unlock(&table->lock); + if (ret) +- pr_warn("%s: unable to add gid %pI6 error=%d\n", +- __func__, gid->raw, ret); ++ pr_warn_ratelimited("%s: unable to add gid %pI6 error=%d\n", ++ __func__, gid->raw, ret); + return ret; + } + +diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c +index c5f4207fddce92..a34b9533d8f18e 100644 +--- a/drivers/input/keyboard/gpio_keys.c ++++ b/drivers/input/keyboard/gpio_keys.c +@@ -495,7 +495,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) + if (bdata->release_delay) + hrtimer_start(&bdata->release_timer, + ms_to_ktime(bdata->release_delay), +- HRTIMER_MODE_REL_HARD); ++ HRTIMER_MODE_REL); + out: + spin_unlock_irqrestore(&bdata->lock, flags); + return IRQ_HANDLED; +@@ -632,7 +632,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, + + bdata->release_delay = button->debounce_interval; + hrtimer_init(&bdata->release_timer, +- CLOCK_REALTIME, HRTIMER_MODE_REL_HARD); ++ CLOCK_REALTIME, HRTIMER_MODE_REL); + bdata->release_timer.function = gpio_keys_irq_timer; + + isr = gpio_keys_irq_isr; +diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c +index a626dbc719995f..728589ec802641 100644 +--- a/drivers/interconnect/qcom/sc7280.c ++++ b/drivers/interconnect/qcom/sc7280.c +@@ -165,6 +165,7 @@ static struct qcom_icc_node xm_pcie3_1 = { + .id = SC7280_MASTER_PCIE_1, + .channels = 1, + .buswidth = 8, ++ .num_links = 1, + .links = { SC7280_SLAVE_ANOC_PCIE_GEM_NOC }, + }; + +diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c +index beafca6ba0df4d..275d34119acdcb 100644 +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -2858,7 +2858,12 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ + const struct nand_op_instr *instr = NULL; + unsigned int op_id = 0; + unsigned int len = 0; +- int ret; ++ int ret, reg_base; ++ ++ reg_base = NAND_READ_LOCATION_0; ++ ++ if (nandc->props->qpic_v2) ++ reg_base = NAND_READ_LOCATION_LAST_CW_0; + + ret = qcom_parse_instructions(chip, subop, &q_op); + if (ret) +@@ -2910,7 +2915,10 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ + op_id = q_op.data_instr_idx; + len = nand_subop_get_data_len(subop, op_id); + +- nandc_set_read_loc(chip, 0, 0, 0, len, 1); ++ if (nandc->props->qpic_v2) ++ nandc_set_read_loc_last(chip, reg_base, 0, len, 1); ++ else ++ nandc_set_read_loc_first(chip, reg_base, 0, len, 1); + + if (!nandc->props->qpic_v2) { + write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 7d9a7c92d4cf63..6018444a76b9bc 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -125,13 +125,16 @@ void can_change_state(struct net_device *dev, struct can_frame *cf, + EXPORT_SYMBOL_GPL(can_change_state); + + /* CAN device restart for bus-off recovery */ +-static void can_restart(struct net_device *dev) ++static int can_restart(struct net_device *dev) + { + struct can_priv *priv = netdev_priv(dev); + struct sk_buff *skb; + struct can_frame *cf; + int err; + ++ if (!priv->do_set_mode) ++ return -EOPNOTSUPP; ++ + if (netif_carrier_ok(dev)) + netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); + +@@ -142,24 +145,25 @@ static void can_restart(struct net_device *dev) + + /* send restart message upstream */ + skb = alloc_can_err_skb(dev, &cf); +- if (!skb) +- goto restart; +- +- cf->can_id |= CAN_ERR_RESTARTED; +- +- netif_rx(skb); +- +-restart: +- netdev_dbg(dev, "restarted\n"); +- priv->can_stats.restarts++; ++ if (skb) { ++ cf->can_id |= CAN_ERR_RESTARTED; ++ netif_rx(skb); ++ } + + /* Now restart the device */ + netif_carrier_on(dev); + err = priv->do_set_mode(dev, CAN_MODE_START); + if (err) { +- netdev_err(dev, "Error %d during restart", err); ++ netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err)); + netif_carrier_off(dev); ++ ++ return err; ++ } else { ++ netdev_dbg(dev, "Restarted\n"); ++ priv->can_stats.restarts++; + } ++ ++ return 0; + } + + static void can_restart_work(struct work_struct *work) +@@ -184,9 +188,8 @@ int can_restart_now(struct net_device *dev) + return -EBUSY; + + cancel_delayed_work_sync(&priv->restart_work); +- can_restart(dev); + +- return 0; ++ return can_restart(dev); + } + + /* CAN bus-off +diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c +index 01aacdcda26066..abe8dc051d94f1 100644 +--- a/drivers/net/can/dev/netlink.c ++++ b/drivers/net/can/dev/netlink.c +@@ -285,6 +285,12 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], + } + + if (data[IFLA_CAN_RESTART_MS]) { ++ if (!priv->do_set_mode) { ++ NL_SET_ERR_MSG(extack, ++ "Device doesn't support restart from Bus Off"); ++ return -EOPNOTSUPP; ++ } ++ + /* Do not allow changing restart delay while running */ + if (dev->flags & IFF_UP) + return -EBUSY; +@@ -292,6 +298,12 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], + } + + if (data[IFLA_CAN_RESTART]) { ++ if (!priv->do_set_mode) { ++ NL_SET_ERR_MSG(extack, ++ "Device doesn't support restart from Bus Off"); ++ return -EOPNOTSUPP; ++ } ++ + /* Do not allow a restart while not running */ + if (!(dev->flags & IFF_UP)) + return -EINVAL; +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +index d3c36a6f84b01d..81a99f4824d054 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +@@ -4654,12 +4654,19 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) + return PTR_ERR(dpmac_dev); + } + +- if (IS_ERR(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) ++ if (IS_ERR(dpmac_dev)) + return 0; + ++ if (dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) { ++ err = 0; ++ goto out_put_device; ++ } ++ + mac = kzalloc(sizeof(struct dpaa2_mac), GFP_KERNEL); +- if (!mac) +- return -ENOMEM; ++ if (!mac) { ++ err = -ENOMEM; ++ goto out_put_device; ++ } + + mac->mc_dev = dpmac_dev; + mac->mc_io = priv->mc_io; +@@ -4693,6 +4700,8 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) + dpaa2_mac_close(mac); + err_free_mac: + kfree(mac); ++out_put_device: ++ put_device(&dpmac_dev->dev); + return err; + } + +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +index a05a8525caa459..76795bb0b564b7 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +@@ -1447,12 +1447,19 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv) + if (PTR_ERR(dpmac_dev) == -EPROBE_DEFER) + return PTR_ERR(dpmac_dev); + +- if (IS_ERR(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) ++ if (IS_ERR(dpmac_dev)) + return 0; + ++ if (dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) { ++ err = 0; ++ goto out_put_device; ++ } ++ + mac = kzalloc(sizeof(*mac), GFP_KERNEL); +- if (!mac) +- return -ENOMEM; ++ if (!mac) { ++ err = -ENOMEM; ++ goto out_put_device; ++ } + + mac->mc_dev = dpmac_dev; + mac->mc_io = port_priv->ethsw_data->mc_io; +@@ -1482,6 +1489,8 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv) + dpaa2_mac_close(mac); + err_free_mac: + kfree(mac); ++out_put_device: ++ put_device(&dpmac_dev->dev); + return err; + } + +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index b4745d94cbbdbf..ec189f0703f99e 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -1801,49 +1801,56 @@ static void gve_turnup(struct gve_priv *priv) + gve_set_napi_enabled(priv); + } + +-static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue) ++static struct gve_notify_block *gve_get_tx_notify_block(struct gve_priv *priv, ++ unsigned int txqueue) + { +- struct gve_notify_block *block; +- struct gve_tx_ring *tx = NULL; +- struct gve_priv *priv; +- u32 last_nic_done; +- u32 current_time; + u32 ntfy_idx; + +- netdev_info(dev, "Timeout on tx queue, %d", txqueue); +- priv = netdev_priv(dev); + if (txqueue > priv->tx_cfg.num_queues) +- goto reset; ++ return NULL; + + ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue); + if (ntfy_idx >= priv->num_ntfy_blks) +- goto reset; ++ return NULL; ++ ++ return &priv->ntfy_blocks[ntfy_idx]; ++} ++ ++static bool gve_tx_timeout_try_q_kick(struct gve_priv *priv, ++ unsigned int txqueue) ++{ ++ struct gve_notify_block *block; ++ u32 current_time; + +- block = &priv->ntfy_blocks[ntfy_idx]; +- tx = block->tx; ++ block = gve_get_tx_notify_block(priv, txqueue); ++ ++ if (!block) ++ return false; + + current_time = jiffies_to_msecs(jiffies); +- if (tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time) +- goto reset; ++ if (block->tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time) ++ return false; + +- /* Check to see if there are missed completions, which will allow us to +- * kick the queue. +- */ +- last_nic_done = gve_tx_load_event_counter(priv, tx); +- if (last_nic_done - tx->done) { +- netdev_info(dev, "Kicking queue %d", txqueue); +- iowrite32be(GVE_IRQ_MASK, gve_irq_doorbell(priv, block)); +- napi_schedule(&block->napi); +- tx->last_kick_msec = current_time; +- goto out; +- } // Else reset. ++ netdev_info(priv->dev, "Kicking queue %d", txqueue); ++ napi_schedule(&block->napi); ++ block->tx->last_kick_msec = current_time; ++ return true; ++} + +-reset: +- gve_schedule_reset(priv); ++static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue) ++{ ++ struct gve_notify_block *block; ++ struct gve_priv *priv; + +-out: +- if (tx) +- tx->queue_timeout++; ++ netdev_info(dev, "Timeout on tx queue, %d", txqueue); ++ priv = netdev_priv(dev); ++ ++ if (!gve_tx_timeout_try_q_kick(priv, txqueue)) ++ gve_schedule_reset(priv); ++ ++ block = gve_get_tx_notify_block(priv, txqueue); ++ if (block) ++ block->tx->queue_timeout++; + priv->tx_timeo_cnt++; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 0ed01f4d680618..dbf44a17987eb4 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -11,6 +11,7 @@ + #include <linux/irq.h> + #include <linux/ip.h> + #include <linux/ipv6.h> ++#include <linux/iommu.h> + #include <linux/module.h> + #include <linux/pci.h> + #include <linux/skbuff.h> +@@ -1039,6 +1040,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring, + static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) + { + u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size; ++ struct net_device *netdev = ring_to_netdev(ring); ++ struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hns3_tx_spare *tx_spare; + struct page *page; + dma_addr_t dma; +@@ -1080,6 +1083,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) + tx_spare->buf = page_address(page); + tx_spare->len = PAGE_SIZE << order; + ring->tx_spare = tx_spare; ++ ring->tx_copybreak = priv->tx_copybreak; + return; + + dma_mapping_error: +@@ -4879,6 +4883,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) + devm_kfree(&pdev->dev, priv->tqp_vector); + } + ++static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv) ++{ ++#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024) ++#define HNS3_MAX_PACKET_SIZE (64 * 1024) ++ ++ struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev); ++ struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle); ++ struct hnae3_handle *handle = priv->ae_handle; ++ ++ if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) ++ return; ++ ++ if (!(domain && iommu_is_dma_domain(domain))) ++ return; ++ ++ priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE; ++ priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE; ++ ++ if (priv->tx_copybreak < priv->min_tx_copybreak) ++ priv->tx_copybreak = priv->min_tx_copybreak; ++ if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size) ++ handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size; ++} ++ + static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, + unsigned int ring_type) + { +@@ -5113,6 +5141,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) + int i, j; + int ret; + ++ hns3_update_tx_spare_buf_config(priv); + for (i = 0; i < ring_num; i++) { + ret = hns3_alloc_ring_memory(&priv->ring[i]); + if (ret) { +@@ -5317,6 +5346,8 @@ static int hns3_client_init(struct hnae3_handle *handle) + priv->ae_handle = handle; + priv->tx_timeout_count = 0; + priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; ++ priv->min_tx_copybreak = 0; ++ priv->min_tx_spare_buf_size = 0; + set_bit(HNS3_NIC_STATE_DOWN, &priv->state); + + handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +index d36c4ed16d8dd2..caf7a4df858527 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +@@ -596,6 +596,8 @@ struct hns3_nic_priv { + struct hns3_enet_coalesce rx_coal; + u32 tx_copybreak; + u32 rx_copybreak; ++ u32 min_tx_copybreak; ++ u32 min_tx_spare_buf_size; + }; + + union l3_hdr_info { +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 4d318af748a0b7..789f72d1067f8a 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -9493,33 +9493,36 @@ static bool hclge_need_enable_vport_vlan_filter(struct hclge_vport *vport) + return false; + } + +-int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) ++static int __hclge_enable_vport_vlan_filter(struct hclge_vport *vport, ++ bool request_en) + { +- struct hclge_dev *hdev = vport->back; + bool need_en; + int ret; + +- mutex_lock(&hdev->vport_lock); +- +- vport->req_vlan_fltr_en = request_en; +- + need_en = hclge_need_enable_vport_vlan_filter(vport); +- if (need_en == vport->cur_vlan_fltr_en) { +- mutex_unlock(&hdev->vport_lock); ++ if (need_en == vport->cur_vlan_fltr_en) + return 0; +- } + + ret = hclge_set_vport_vlan_filter(vport, need_en); +- if (ret) { +- mutex_unlock(&hdev->vport_lock); ++ if (ret) + return ret; +- } + + vport->cur_vlan_fltr_en = need_en; + ++ return 0; ++} ++ ++int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) ++{ ++ struct hclge_dev *hdev = vport->back; ++ int ret; ++ ++ mutex_lock(&hdev->vport_lock); ++ vport->req_vlan_fltr_en = request_en; ++ ret = __hclge_enable_vport_vlan_filter(vport, request_en); + mutex_unlock(&hdev->vport_lock); + +- return 0; ++ return ret; + } + + static int hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) +@@ -10540,16 +10543,19 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev) + &vport->state)) + continue; + +- ret = hclge_enable_vport_vlan_filter(vport, +- vport->req_vlan_fltr_en); ++ mutex_lock(&hdev->vport_lock); ++ ret = __hclge_enable_vport_vlan_filter(vport, ++ vport->req_vlan_fltr_en); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to sync vlan filter state for vport%u, ret = %d\n", + vport->vport_id, ret); + set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, + &vport->state); ++ mutex_unlock(&hdev->vport_lock); + return; + } ++ mutex_unlock(&hdev->vport_lock); + } + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +index 9a806ac727cf5b..c1e88e67ebb657 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +@@ -497,14 +497,14 @@ int hclge_ptp_init(struct hclge_dev *hdev) + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init freq, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + ret = hclge_ptp_set_ts_mode(hdev, &hdev->ptp->ts_cfg); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init ts mode, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + ktime_get_real_ts64(&ts); +@@ -512,7 +512,7 @@ int hclge_ptp_init(struct hclge_dev *hdev) + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to init ts time, ret = %d\n", ret); +- goto out; ++ goto out_clear_int; + } + + set_bit(HCLGE_STATE_PTP_EN, &hdev->state); +@@ -520,6 +520,9 @@ int hclge_ptp_init(struct hclge_dev *hdev) + + return 0; + ++out_clear_int: ++ clear_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags); ++ hclge_ptp_int_en(hdev, false); + out: + hclge_ptp_destroy_clock(hdev); + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 1ba0b57c7a72d7..68a9aeeed3da06 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3029,11 +3029,7 @@ static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) + + static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) + { +- struct hnae3_handle *nic = &hdev->nic; +- struct hnae3_knic_private_info *kinfo = &nic->kinfo; +- +- return min_t(u32, hdev->rss_size_max, +- hdev->num_tqps / kinfo->tc_info.num_tc); ++ return min(hdev->rss_size_max, hdev->num_tqps); + } + + /** +diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h +index 0a35d36c2c8571..955bb116185728 100644 +--- a/drivers/net/ethernet/intel/e1000e/defines.h ++++ b/drivers/net/ethernet/intel/e1000e/defines.h +@@ -638,6 +638,9 @@ + /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ + #define NVM_SUM 0xBABA + ++/* Uninitialized ("empty") checksum word value */ ++#define NVM_CHECKSUM_UNINITIALIZED 0xFFFF ++ + /* PBA (printed board assembly) number words */ + #define NVM_PBA_OFFSET_0 8 + #define NVM_PBA_OFFSET_1 9 +diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c +index 364378133526a1..df4e7d781cb1cb 100644 +--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c ++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c +@@ -4274,6 +4274,8 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) + ret_val = e1000e_update_nvm_checksum(hw); + if (ret_val) + return ret_val; ++ } else if (hw->mac.type == e1000_pch_tgp) { ++ return 0; + } + } + +diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c +index e609f4df86f455..16369e6d245a4a 100644 +--- a/drivers/net/ethernet/intel/e1000e/nvm.c ++++ b/drivers/net/ethernet/intel/e1000e/nvm.c +@@ -558,6 +558,12 @@ s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) + checksum += nvm_data; + } + ++ if (hw->mac.type == e1000_pch_tgp && ++ nvm_data == NVM_CHECKSUM_UNINITIALIZED) { ++ e_dbg("Uninitialized NVM Checksum on TGP platform - ignoring\n"); ++ return 0; ++ } ++ + if (checksum != (u16)NVM_SUM) { + e_dbg("NVM Checksum Invalid\n"); + return -E1000_ERR_NVM; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index 4e90570ba7803a..a89f7ca510fdb8 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -246,6 +246,7 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = { + I40E_NETDEV_STAT(rx_errors), + I40E_NETDEV_STAT(tx_errors), + I40E_NETDEV_STAT(rx_dropped), ++ I40E_NETDEV_STAT(rx_missed_errors), + I40E_NETDEV_STAT(tx_dropped), + I40E_NETDEV_STAT(collisions), + I40E_NETDEV_STAT(rx_length_errors), +@@ -322,7 +323,7 @@ static const struct i40e_stats i40e_gstrings_stats[] = { + I40E_PF_STAT("port.rx_broadcast", stats.eth.rx_broadcast), + I40E_PF_STAT("port.tx_broadcast", stats.eth.tx_broadcast), + I40E_PF_STAT("port.tx_errors", stats.eth.tx_errors), +- I40E_PF_STAT("port.rx_dropped", stats.eth.rx_discards), ++ I40E_PF_STAT("port.rx_discards", stats.eth.rx_discards), + I40E_PF_STAT("port.tx_dropped_link_down", stats.tx_dropped_link_down), + I40E_PF_STAT("port.rx_crc_errors", stats.crc_errors), + I40E_PF_STAT("port.illegal_bytes", stats.illegal_bytes), +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 806cec458a0726..b749aa3e783ffe 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -509,6 +509,7 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev, + stats->tx_dropped = vsi_stats->tx_dropped; + stats->rx_errors = vsi_stats->rx_errors; + stats->rx_dropped = vsi_stats->rx_dropped; ++ stats->rx_missed_errors = vsi_stats->rx_missed_errors; + stats->rx_crc_errors = vsi_stats->rx_crc_errors; + stats->rx_length_errors = vsi_stats->rx_length_errors; + } +@@ -700,17 +701,13 @@ i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw, + struct i40e_eth_stats *stat_offset, + struct i40e_eth_stats *stat) + { +- u64 rx_rdpc, rx_rxerr; +- + i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded, +- &stat_offset->rx_discards, &rx_rdpc); ++ &stat_offset->rx_discards, &stat->rx_discards); + i40e_stat_update64(hw, + I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)), + I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)), + offset_loaded, &stat_offset->rx_discards_other, +- &rx_rxerr); +- +- stat->rx_discards = rx_rdpc + rx_rxerr; ++ &stat->rx_discards_other); + } + + /** +@@ -732,9 +729,6 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi) + i40e_stat_update32(hw, I40E_GLV_TEPC(stat_idx), + vsi->stat_offsets_loaded, + &oes->tx_errors, &es->tx_errors); +- i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), +- vsi->stat_offsets_loaded, +- &oes->rx_discards, &es->rx_discards); + i40e_stat_update32(hw, I40E_GLV_RUPP(stat_idx), + vsi->stat_offsets_loaded, + &oes->rx_unknown_protocol, &es->rx_unknown_protocol); +@@ -991,8 +985,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) + ns->tx_errors = es->tx_errors; + ons->multicast = oes->rx_multicast; + ns->multicast = es->rx_multicast; +- ons->rx_dropped = oes->rx_discards; +- ns->rx_dropped = es->rx_discards; ++ ons->rx_dropped = oes->rx_discards_other; ++ ns->rx_dropped = es->rx_discards_other; ++ ons->rx_missed_errors = oes->rx_discards; ++ ns->rx_missed_errors = es->rx_discards; + ons->tx_dropped = oes->tx_discards; + ns->tx_dropped = es->tx_discards; + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 80036942dc764a..6d7a4f2c3a49b7 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -3143,10 +3143,10 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) + const u8 *addr = al->list[i].addr; + + /* Allow to delete VF primary MAC only if it was not set +- * administratively by PF or if VF is trusted. ++ * administratively by PF. + */ + if (ether_addr_equal(addr, vf->default_lan_addr.addr)) { +- if (i40e_can_vf_change_mac(vf)) ++ if (!vf->pf_set_mac) + was_unimac_deleted = true; + else + continue; +@@ -5010,8 +5010,8 @@ int i40e_get_vf_stats(struct net_device *netdev, int vf_id, + vf_stats->tx_bytes = stats->tx_bytes; + vf_stats->broadcast = stats->rx_broadcast; + vf_stats->multicast = stats->rx_multicast; +- vf_stats->rx_dropped = stats->rx_discards; +- vf_stats->tx_dropped = stats->tx_discards; ++ vf_stats->rx_dropped = stats->rx_discards + stats->rx_discards_other; ++ vf_stats->tx_dropped = stats->tx_errors; + + return 0; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c +index b27ec93638b6b4..cd97974b451a04 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ddp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c +@@ -1884,6 +1884,8 @@ enum ice_ddp_state ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, + return ICE_DDP_PKG_ERR; + + buf_copy = devm_kmemdup(ice_hw_to_dev(hw), buf, len, GFP_KERNEL); ++ if (!buf_copy) ++ return ICE_DDP_PKG_ERR; + + state = ice_init_pkg(hw, buf_copy, len); + if (!ice_is_init_pkg_successful(state)) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +index 3e6bd27f6315d8..5a2126679415c7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -1916,8 +1916,8 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, + + err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context, + pages_queue, token, force_polling); +- if (callback) +- return err; ++ if (callback && !err) ++ return 0; + + if (err > 0) /* Failed in FW, command didn't execute */ + err = deliv_status_to_err(err); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 326c72b3df8671..86fb8197594f5e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -1170,19 +1170,19 @@ static void esw_set_peer_miss_rule_source_port(struct mlx5_eswitch *esw, + static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + struct mlx5_core_dev *peer_dev) + { ++ struct mlx5_eswitch *peer_esw = peer_dev->priv.eswitch; + struct mlx5_flow_destination dest = {}; + struct mlx5_flow_act flow_act = {0}; + struct mlx5_flow_handle **flows; +- /* total vports is the same for both e-switches */ +- int nvports = esw->total_vports; + struct mlx5_flow_handle *flow; ++ struct mlx5_vport *peer_vport; + struct mlx5_flow_spec *spec; +- struct mlx5_vport *vport; + int err, pfindex; + unsigned long i; + void *misc; + +- if (!MLX5_VPORT_MANAGER(esw->dev) && !mlx5_core_is_ecpf_esw_manager(esw->dev)) ++ if (!MLX5_VPORT_MANAGER(peer_dev) && ++ !mlx5_core_is_ecpf_esw_manager(peer_dev)) + return 0; + + spec = kvzalloc(sizeof(*spec), GFP_KERNEL); +@@ -1191,7 +1191,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + + peer_miss_rules_setup(esw, peer_dev, spec, &dest); + +- flows = kvcalloc(nvports, sizeof(*flows), GFP_KERNEL); ++ flows = kvcalloc(peer_esw->total_vports, sizeof(*flows), GFP_KERNEL); + if (!flows) { + err = -ENOMEM; + goto alloc_flows_err; +@@ -1201,10 +1201,10 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + misc = MLX5_ADDR_OF(fte_match_param, spec->match_value, + misc_parameters); + +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch, +- spec, MLX5_VPORT_PF); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ esw_set_peer_miss_rule_source_port(esw, peer_esw, spec, ++ MLX5_VPORT_PF); + + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1212,11 +1212,11 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_pf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); + MLX5_SET(fte_match_set_misc, misc, source_port, MLX5_VPORT_ECPF); + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1224,13 +1224,14 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_ecpf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) { ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) { + esw_set_peer_miss_rule_source_port(esw, +- peer_dev->priv.eswitch, +- spec, vport->vport); ++ peer_esw, ++ spec, peer_vport->vport); + + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); +@@ -1238,22 +1239,22 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + err = PTR_ERR(flow); + goto add_vf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + +- if (mlx5_core_ec_sriov_enabled(esw->dev)) { +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- if (i >= mlx5_core_max_ec_vfs(peer_dev)) +- break; +- esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch, +- spec, vport->vport); ++ if (mlx5_core_ec_sriov_enabled(peer_dev)) { ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) { ++ esw_set_peer_miss_rule_source_port(esw, peer_esw, ++ spec, ++ peer_vport->vport); + flow = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, + spec, &flow_act, &dest, 1); + if (IS_ERR(flow)) { + err = PTR_ERR(flow); + goto add_ec_vf_flow_err; + } +- flows[vport->index] = flow; ++ flows[peer_vport->index] = flow; + } + } + +@@ -1270,25 +1271,27 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + return 0; + + add_ec_vf_flow_err: +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- if (!flows[vport->index]) ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) { ++ if (!flows[peer_vport->index]) + continue; +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_vf_flow_err: +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) { +- if (!flows[vport->index]) ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) { ++ if (!flows[peer_vport->index]) + continue; +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_ecpf_flow_err: +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + add_pf_flow_err: + esw_warn(esw->dev, "FDB: Failed to add peer miss flow rule err %d\n", err); +@@ -1301,37 +1304,34 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + static void esw_del_fdb_peer_miss_rules(struct mlx5_eswitch *esw, + struct mlx5_core_dev *peer_dev) + { ++ struct mlx5_eswitch *peer_esw = peer_dev->priv.eswitch; + u16 peer_index = mlx5_get_dev_index(peer_dev); + struct mlx5_flow_handle **flows; +- struct mlx5_vport *vport; ++ struct mlx5_vport *peer_vport; + unsigned long i; + + flows = esw->fdb_table.offloads.peer_miss_rules[peer_index]; + if (!flows) + return; + +- if (mlx5_core_ec_sriov_enabled(esw->dev)) { +- mlx5_esw_for_each_ec_vf_vport(esw, i, vport, mlx5_core_max_ec_vfs(esw->dev)) { +- /* The flow for a particular vport could be NULL if the other ECPF +- * has fewer or no VFs enabled +- */ +- if (!flows[vport->index]) +- continue; +- mlx5_del_flow_rules(flows[vport->index]); +- } ++ if (mlx5_core_ec_sriov_enabled(peer_dev)) { ++ mlx5_esw_for_each_ec_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_ec_vfs(peer_dev)) ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + +- mlx5_esw_for_each_vf_vport(esw, i, vport, mlx5_core_max_vfs(esw->dev)) +- mlx5_del_flow_rules(flows[vport->index]); ++ mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, ++ mlx5_core_max_vfs(peer_dev)) ++ mlx5_del_flow_rules(flows[peer_vport->index]); + +- if (mlx5_ecpf_vport_exists(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_ecpf_vport_exists(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_ECPF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + +- if (mlx5_core_is_ecpf_esw_manager(esw->dev)) { +- vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_PF); +- mlx5_del_flow_rules(flows[vport->index]); ++ if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { ++ peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); ++ mlx5_del_flow_rules(flows[peer_vport->index]); + } + + kvfree(flows); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +index 8e2ec395633171..15b7d22d3639f2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +@@ -1087,6 +1087,9 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw, + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + ++ if (!msta->wcid.sta) ++ return; ++ + mt792x_mutex_acquire(dev); + + if (enabled) +diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile +index b457de5abf7d79..8012de299174ff 100644 +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -58,6 +58,8 @@ obj-$(CONFIG_X86_PLATFORM_DRIVERS_HP) += hp/ + # Hewlett Packard Enterprise + obj-$(CONFIG_UV_SYSFS) += uv_sysfs.o + ++obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o ++ + # IBM Thinkpad and Lenovo + obj-$(CONFIG_IBM_RTL) += ibm_rtl.o + obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o +@@ -108,7 +110,6 @@ obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o + obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o + + # Platform drivers +-obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o + obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o + obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o + obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index e84fcb444d872a..17a9e4bd638dcc 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -1600,7 +1600,7 @@ static int ideapad_kbd_bl_init(struct ideapad_private *priv) + priv->kbd_bl.led.name = "platform::" LED_FUNCTION_KBD_BACKLIGHT; + priv->kbd_bl.led.brightness_get = ideapad_kbd_bl_led_cdev_brightness_get; + priv->kbd_bl.led.brightness_set_blocking = ideapad_kbd_bl_led_cdev_brightness_set; +- priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED; ++ priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED | LED_RETAIN_AT_SHUTDOWN; + + err = led_classdev_register(&priv->platform_device->dev, &priv->kbd_bl.led); + if (err) +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index d2e21dc61dd7d5..1d49612eeb7e54 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -5422,6 +5422,7 @@ static void regulator_remove_coupling(struct regulator_dev *rdev) + ERR_PTR(err)); + } + ++ rdev->coupling_desc.n_coupled = 0; + kfree(rdev->coupling_desc.coupled_rdevs); + rdev->coupling_desc.coupled_rdevs = NULL; + } +diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c +index af0d90beba6380..76ba36c83e5228 100644 +--- a/drivers/s390/net/ism_drv.c ++++ b/drivers/s390/net/ism_drv.c +@@ -130,6 +130,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) + struct ism_req_hdr *req = cmd; + struct ism_resp_hdr *resp = cmd; + ++ spin_lock(&ism->cmd_lock); + __ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req)); + __ism_write_cmd(ism, req, 0, sizeof(*req)); + +@@ -143,6 +144,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) + } + __ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp)); + out: ++ spin_unlock(&ism->cmd_lock); + return resp->ret; + } + +@@ -630,6 +632,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) + return -ENOMEM; + + spin_lock_init(&ism->lock); ++ spin_lock_init(&ism->cmd_lock); + dev_set_drvdata(&pdev->dev, ism); + ism->pdev = pdev; + ism->dev.parent = &pdev->dev; +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index 9285a683324f4f..7c17b8c0425e3c 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -1870,11 +1870,6 @@ static int cqspi_probe(struct platform_device *pdev) + + pm_runtime_enable(dev); + +- if (cqspi->rx_chan) { +- dma_release_channel(cqspi->rx_chan); +- goto probe_setup_failed; +- } +- + ret = spi_register_controller(host); + if (ret) { + dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +index 92aa98bbdc6628..6028558f96111c 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -720,8 +720,7 @@ int vchiq_shutdown(struct vchiq_instance *instance) + int status = 0; + struct vchiq_state *state = instance->state; + +- if (mutex_lock_killable(&state->mutex)) +- return -EAGAIN; ++ mutex_lock(&state->mutex); + + /* Remove all services */ + vchiq_shutdown_internal(state, instance); +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index bfcbccb400c3a8..5774b50eeaf7f7 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -1041,7 +1041,7 @@ static int tcpm_set_attached_state(struct tcpm_port *port, bool attached) + port->data_role); + } + +-static int tcpm_set_roles(struct tcpm_port *port, bool attached, ++static int tcpm_set_roles(struct tcpm_port *port, bool attached, int state, + enum typec_role role, enum typec_data_role data) + { + enum typec_orientation orientation; +@@ -1078,7 +1078,7 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached, + } + } + +- ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation); ++ ret = tcpm_mux_set(port, state, usb_role, orientation); + if (ret < 0) + return ret; + +@@ -3622,16 +3622,6 @@ static int tcpm_src_attach(struct tcpm_port *port) + + tcpm_enable_auto_vbus_discharge(port, true); + +- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port)); +- if (ret < 0) +- return ret; +- +- if (port->pd_supported) { +- ret = port->tcpc->set_pd_rx(port->tcpc, true); +- if (ret < 0) +- goto out_disable_mux; +- } +- + /* + * USB Type-C specification, version 1.2, + * chapter 4.5.2.2.8.1 (Attached.SRC Requirements) +@@ -3641,13 +3631,24 @@ static int tcpm_src_attach(struct tcpm_port *port) + (polarity == TYPEC_POLARITY_CC2 && port->cc1 == TYPEC_CC_RA)) { + ret = tcpm_set_vconn(port, true); + if (ret < 0) +- goto out_disable_pd; ++ return ret; + } + + ret = tcpm_set_vbus(port, true); + if (ret < 0) + goto out_disable_vconn; + ++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, TYPEC_SOURCE, ++ tcpm_data_role_for_source(port)); ++ if (ret < 0) ++ goto out_disable_vbus; ++ ++ if (port->pd_supported) { ++ ret = port->tcpc->set_pd_rx(port->tcpc, true); ++ if (ret < 0) ++ goto out_disable_mux; ++ } ++ + port->pd_capable = false; + + port->partner = NULL; +@@ -3657,14 +3658,14 @@ static int tcpm_src_attach(struct tcpm_port *port) + + return 0; + +-out_disable_vconn: +- tcpm_set_vconn(port, false); +-out_disable_pd: +- if (port->pd_supported) +- port->tcpc->set_pd_rx(port->tcpc, false); + out_disable_mux: + tcpm_mux_set(port, TYPEC_STATE_SAFE, USB_ROLE_NONE, + TYPEC_ORIENTATION_NONE); ++out_disable_vbus: ++ tcpm_set_vbus(port, false); ++out_disable_vconn: ++ tcpm_set_vconn(port, false); ++ + return ret; + } + +@@ -3780,7 +3781,8 @@ static int tcpm_snk_attach(struct tcpm_port *port) + + tcpm_enable_auto_vbus_discharge(port, true); + +- ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port)); ++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, ++ TYPEC_SINK, tcpm_data_role_for_sink(port)); + if (ret < 0) + return ret; + +@@ -3802,12 +3804,24 @@ static void tcpm_snk_detach(struct tcpm_port *port) + static int tcpm_acc_attach(struct tcpm_port *port) + { + int ret; ++ enum typec_role role; ++ enum typec_data_role data; ++ int state = TYPEC_STATE_USB; + + if (port->attached) + return 0; + +- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, +- tcpm_data_role_for_source(port)); ++ role = tcpm_port_is_sink(port) ? TYPEC_SINK : TYPEC_SOURCE; ++ data = tcpm_port_is_sink(port) ? tcpm_data_role_for_sink(port) ++ : tcpm_data_role_for_source(port); ++ ++ if (tcpm_port_is_audio(port)) ++ state = TYPEC_MODE_AUDIO; ++ ++ if (tcpm_port_is_debug(port)) ++ state = TYPEC_MODE_DEBUG; ++ ++ ret = tcpm_set_roles(port, true, state, role, data); + if (ret < 0) + return ret; + +@@ -4509,7 +4523,7 @@ static void run_state_machine(struct tcpm_port *port) + */ + tcpm_set_vconn(port, false); + tcpm_set_vbus(port, false); +- tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE, ++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SOURCE, + tcpm_data_role_for_source(port)); + /* + * If tcpc fails to notify vbus off, TCPM will wait for PD_T_SAFE_0V + +@@ -4541,7 +4555,7 @@ static void run_state_machine(struct tcpm_port *port) + tcpm_set_vconn(port, false); + if (port->pd_capable) + tcpm_set_charge(port, false); +- tcpm_set_roles(port, port->self_powered, TYPEC_SINK, ++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SINK, + tcpm_data_role_for_sink(port)); + /* + * VBUS may or may not toggle, depending on the adapter. +@@ -4647,10 +4661,10 @@ static void run_state_machine(struct tcpm_port *port) + case DR_SWAP_CHANGE_DR: + tcpm_unregister_altmodes(port); + if (port->data_role == TYPEC_HOST) +- tcpm_set_roles(port, true, port->pwr_role, ++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role, + TYPEC_DEVICE); + else +- tcpm_set_roles(port, true, port->pwr_role, ++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role, + TYPEC_HOST); + tcpm_ams_finish(port); + tcpm_set_state(port, ready_state(port), 0); +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index c5f04234d9511a..db4582687b958f 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -2739,7 +2739,7 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num, + void (*recycle)(struct virtqueue *vq, void *buf)) + { + struct vring_virtqueue *vq = to_vvq(_vq); +- int err; ++ int err, err_reset; + + if (num > vq->vq.num_max) + return -E2BIG; +@@ -2759,7 +2759,11 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num, + else + err = virtqueue_resize_split(_vq, num); + +- return virtqueue_enable_after_reset(_vq); ++ err_reset = virtqueue_enable_after_reset(_vq); ++ if (err_reset) ++ return err_reset; ++ ++ return err; + } + EXPORT_SYMBOL_GPL(virtqueue_resize); + +diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c +index aa59788a61e6e4..86e088fd386ee5 100644 +--- a/fs/erofs/decompressor.c ++++ b/fs/erofs/decompressor.c +@@ -342,14 +342,12 @@ static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq, + + if (outpages > inpages) { + DBG_BUGON(!rq->out[outpages - 1]); +- if (rq->out[outpages - 1] != rq->in[inpages - 1]) { ++ if (rq->out[outpages - 1] != rq->in[inpages - 1]) + memcpy_to_page(rq->out[outpages - 1], 0, src + + (interlaced_offset ? 0 : righthalf), + lefthalf); +- } else if (!interlaced_offset) { ++ else if (!interlaced_offset) + memmove(src, src + righthalf, lefthalf); +- flush_dcache_page(rq->in[inpages - 1]); +- } + } + kunmap_local(src); + return 0; +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index 496e4c7c52a4e0..d852b43ac43e32 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -122,9 +122,11 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl) + + /* + * bit 30: I/O error occurred on this page ++ * bit 29: CPU has dirty data in D-cache (needs aliasing handling); + * bit 0 - 29: remaining parts to complete this page + */ +-#define Z_EROFS_PAGE_EIO (1 << 30) ++#define Z_EROFS_ONLINEPAGE_EIO 30 ++#define Z_EROFS_ONLINEPAGE_DIRTY 29 + + static inline void z_erofs_onlinepage_init(struct page *page) + { +@@ -143,7 +145,7 @@ static inline void z_erofs_onlinepage_split(struct page *page) + atomic_inc((atomic_t *)&page->private); + } + +-static void z_erofs_onlinepage_endio(struct page *page, int err) ++static void z_erofs_onlinepage_end(struct page *page, int err, bool dirty) + { + int orig, v; + +@@ -151,16 +153,20 @@ static void z_erofs_onlinepage_endio(struct page *page, int err) + + do { + orig = atomic_read((atomic_t *)&page->private); +- v = (orig - 1) | (err ? Z_EROFS_PAGE_EIO : 0); ++ DBG_BUGON(orig <= 0); ++ v = dirty << Z_EROFS_ONLINEPAGE_DIRTY; ++ v |= (orig - 1) | (!!err << Z_EROFS_ONLINEPAGE_EIO); + } while (atomic_cmpxchg((atomic_t *)&page->private, orig, v) != orig); + +- if (!(v & ~Z_EROFS_PAGE_EIO)) { +- set_page_private(page, 0); +- ClearPagePrivate(page); +- if (!(v & Z_EROFS_PAGE_EIO)) +- SetPageUptodate(page); +- unlock_page(page); +- } ++ if (v & (BIT(Z_EROFS_ONLINEPAGE_DIRTY) - 1)) ++ return; ++ set_page_private(page, 0); ++ ClearPagePrivate(page); ++ if (v & BIT(Z_EROFS_ONLINEPAGE_DIRTY)) ++ flush_dcache_page(page); ++ if (!(v & BIT(Z_EROFS_ONLINEPAGE_EIO))) ++ SetPageUptodate(page); ++ unlock_page(page); + } + + #define Z_EROFS_ONSTACK_PAGES 32 +@@ -1060,7 +1066,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, + goto repeat; + + out: +- z_erofs_onlinepage_endio(page, err); ++ z_erofs_onlinepage_end(page, err, false); + return err; + } + +@@ -1163,7 +1169,7 @@ static void z_erofs_fill_other_copies(struct z_erofs_decompress_backend *be, + cur += len; + } + kunmap_local(dst); +- z_erofs_onlinepage_endio(bvi->bvec.page, err); ++ z_erofs_onlinepage_end(bvi->bvec.page, err, true); + list_del(p); + kfree(bvi); + } +@@ -1333,7 +1339,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, + /* recycle all individual short-lived pages */ + if (z_erofs_put_shortlivedpage(be->pagepool, page)) + continue; +- z_erofs_onlinepage_endio(page, err); ++ z_erofs_onlinepage_end(page, err, true); + } + + if (be->decompressed_pages != be->onstack_pages) +diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c +index 9a6d504228e7c5..35f3144d703b5c 100644 +--- a/fs/jfs/jfs_imap.c ++++ b/fs/jfs/jfs_imap.c +@@ -3029,14 +3029,23 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, + * + * RETURN VALUES: + * 0 - success +- * -ENOMEM - insufficient memory ++ * -EINVAL - unexpected inode type + */ + static int copy_from_dinode(struct dinode * dip, struct inode *ip) + { + struct jfs_inode_info *jfs_ip = JFS_IP(ip); + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); ++ int fileset = le32_to_cpu(dip->di_fileset); ++ ++ switch (fileset) { ++ case AGGR_RESERVED_I: case AGGREGATE_I: case BMAP_I: ++ case LOG_I: case BADBLOCK_I: case FILESYSTEM_I: ++ break; ++ default: ++ return -EINVAL; ++ } + +- jfs_ip->fileset = le32_to_cpu(dip->di_fileset); ++ jfs_ip->fileset = fileset; + jfs_ip->mode2 = le32_to_cpu(dip->di_mode); + jfs_set_inode_flags(ip); + +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 5f2d73f36e0d2f..8c47c13c8e7168 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -517,11 +517,18 @@ static int __nilfs_read_inode(struct super_block *sb, + inode->i_op = &nilfs_symlink_inode_operations; + inode_nohighmem(inode); + inode->i_mapping->a_ops = &nilfs_aops; +- } else { ++ } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || ++ S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { + inode->i_op = &nilfs_special_inode_operations; + init_special_inode( + inode, inode->i_mode, + huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); ++ } else { ++ nilfs_error(sb, ++ "invalid file type bits in mode 0%o for inode %lu", ++ inode->i_mode, ino); ++ err = -EIO; ++ goto failed_unmap; + } + nilfs_ifile_unmap_inode(root->ifile, ino, bh); + brelse(bh); +diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c +index e7bcc383003103..66b20c3d963eb2 100644 +--- a/fs/smb/server/connection.c ++++ b/fs/smb/server/connection.c +@@ -39,8 +39,10 @@ void ksmbd_conn_free(struct ksmbd_conn *conn) + xa_destroy(&conn->sessions); + kvfree(conn->request_buf); + kfree(conn->preauth_info); +- if (atomic_dec_and_test(&conn->refcnt)) ++ if (atomic_dec_and_test(&conn->refcnt)) { ++ conn->transport->ops->free_transport(conn->transport); + kfree(conn); ++ } + } + + /** +diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h +index dc07c6eb8c1921..47e6a8694c0fc1 100644 +--- a/fs/smb/server/connection.h ++++ b/fs/smb/server/connection.h +@@ -132,6 +132,7 @@ struct ksmbd_transport_ops { + void *buf, unsigned int len, + struct smb2_buffer_desc_v1 *desc, + unsigned int desc_len); ++ void (*free_transport)(struct ksmbd_transport *kt); + }; + + struct ksmbd_transport { +diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c +index 7b6639949c250c..eaef459776151b 100644 +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -158,7 +158,8 @@ struct smb_direct_transport { + }; + + #define KSMBD_TRANS(t) ((struct ksmbd_transport *)&((t)->transport)) +- ++#define SMBD_TRANS(t) ((struct smb_direct_transport *)container_of(t, \ ++ struct smb_direct_transport, transport)) + enum { + SMB_DIRECT_MSG_NEGOTIATE_REQ = 0, + SMB_DIRECT_MSG_DATA_TRANSFER +@@ -409,6 +410,11 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) + return NULL; + } + ++static void smb_direct_free_transport(struct ksmbd_transport *kt) ++{ ++ kfree(SMBD_TRANS(kt)); ++} ++ + static void free_transport(struct smb_direct_transport *t) + { + struct smb_direct_recvmsg *recvmsg; +@@ -455,7 +461,6 @@ static void free_transport(struct smb_direct_transport *t) + + smb_direct_destroy_pools(t); + ksmbd_conn_free(KSMBD_TRANS(t)->conn); +- kfree(t); + } + + static struct smb_direct_sendmsg +@@ -2301,4 +2306,5 @@ static struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops = { + .read = smb_direct_read, + .rdma_read = smb_direct_rdma_read, + .rdma_write = smb_direct_rdma_write, ++ .free_transport = smb_direct_free_transport, + }; +diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c +index 2ce7f75059cb35..64941a49438f37 100644 +--- a/fs/smb/server/transport_tcp.c ++++ b/fs/smb/server/transport_tcp.c +@@ -93,17 +93,21 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk) + return t; + } + +-static void free_transport(struct tcp_transport *t) ++static void ksmbd_tcp_free_transport(struct ksmbd_transport *kt) + { +- kernel_sock_shutdown(t->sock, SHUT_RDWR); +- sock_release(t->sock); +- t->sock = NULL; ++ struct tcp_transport *t = TCP_TRANS(kt); + +- ksmbd_conn_free(KSMBD_TRANS(t)->conn); ++ sock_release(t->sock); + kfree(t->iov); + kfree(t); + } + ++static void free_transport(struct tcp_transport *t) ++{ ++ kernel_sock_shutdown(t->sock, SHUT_RDWR); ++ ksmbd_conn_free(KSMBD_TRANS(t)->conn); ++} ++ + /** + * kvec_array_init() - initialize a IO vector segment + * @new: IO vector to be initialized +@@ -655,4 +659,5 @@ static struct ksmbd_transport_ops ksmbd_tcp_transport_ops = { + .read = ksmbd_tcp_read, + .writev = ksmbd_tcp_writev, + .disconnect = ksmbd_tcp_disconnect, ++ .free_transport = ksmbd_tcp_free_transport, + }; +diff --git a/fs/smb/server/transport_tcp.h b/fs/smb/server/transport_tcp.h +index e338bebe322f10..5925ec5df47552 100644 +--- a/fs/smb/server/transport_tcp.h ++++ b/fs/smb/server/transport_tcp.h +@@ -7,6 +7,7 @@ + #define __KSMBD_TRANSPORT_TCP_H__ + + int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz); ++void ksmbd_free_transport(struct ksmbd_transport *kt); + int ksmbd_tcp_init(void); + void ksmbd_tcp_destroy(void); + +diff --git a/include/linux/ism.h b/include/linux/ism.h +index 9a4c204df3da1d..04e2fc1973ce4e 100644 +--- a/include/linux/ism.h ++++ b/include/linux/ism.h +@@ -28,6 +28,7 @@ struct ism_dmb { + + struct ism_dev { + spinlock_t lock; /* protects the ism device */ ++ spinlock_t cmd_lock; /* serializes cmds */ + struct list_head list; + struct pci_dev *pdev; + +diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h +index 33dcbec719254a..9e13b8040b12ca 100644 +--- a/include/linux/sprintf.h ++++ b/include/linux/sprintf.h +@@ -4,6 +4,7 @@ + + #include <linux/compiler_attributes.h> + #include <linux/types.h> ++#include <linux/stdarg.h> + + int num_to_str(char *buf, int size, unsigned long long num, unsigned int width); + +diff --git a/kernel/resource.c b/kernel/resource.c +index 635e858db0fe81..6506839f8a8118 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -1222,8 +1222,9 @@ static int __request_region_locked(struct resource *res, struct resource *parent + * become unavailable to other users. Conflicts are + * not expected. Warn to aid debugging if encountered. + */ +- if (conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) { +- pr_warn("Unaddressable device %s %pR conflicts with %pR", ++ if (parent == &iomem_resource && ++ conflict->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY) { ++ pr_warn("Unaddressable device %s %pR conflicts with %pR\n", + conflict->name, conflict, res); + } + if (conflict != parent) { +diff --git a/mm/kasan/report.c b/mm/kasan/report.c +index 44636fa953a723..7301773b5208a4 100644 +--- a/mm/kasan/report.c ++++ b/mm/kasan/report.c +@@ -385,7 +385,9 @@ static void print_address_description(void *addr, u8 tag, + } + + if (is_vmalloc_addr(addr)) { +- pr_err("The buggy address %px belongs to a vmalloc virtual mapping\n", addr); ++ pr_err("The buggy address belongs to a"); ++ if (!vmalloc_dump_obj(addr)) ++ pr_cont(" vmalloc virtual mapping\n"); + page = vmalloc_to_page(addr); + } + +diff --git a/mm/khugepaged.c b/mm/khugepaged.c +index a87cfe1d4b7beb..f227b39ae4cf74 100644 +--- a/mm/khugepaged.c ++++ b/mm/khugepaged.c +@@ -2387,7 +2387,7 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, int *result, + VM_BUG_ON(khugepaged_scan.address < hstart || + khugepaged_scan.address + HPAGE_PMD_SIZE > + hend); +- if (IS_ENABLED(CONFIG_SHMEM) && vma->vm_file) { ++ if (IS_ENABLED(CONFIG_SHMEM) && !vma_is_anonymous(vma)) { + struct file *file = get_file(vma->vm_file); + pgoff_t pgoff = linear_page_index(vma, + khugepaged_scan.address); +@@ -2734,7 +2734,7 @@ int madvise_collapse(struct vm_area_struct *vma, struct vm_area_struct **prev, + mmap_assert_locked(mm); + memset(cc->node_load, 0, sizeof(cc->node_load)); + nodes_clear(cc->alloc_nmask); +- if (IS_ENABLED(CONFIG_SHMEM) && vma->vm_file) { ++ if (IS_ENABLED(CONFIG_SHMEM) && !vma_is_anonymous(vma)) { + struct file *file = get_file(vma->vm_file); + pgoff_t pgoff = linear_page_index(vma, addr); + +diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c +index b58f957429f053..c82070167d8aa8 100644 +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -988,6 +988,9 @@ static struct zspage *alloc_zspage(struct zs_pool *pool, + if (!zspage) + return NULL; + ++ if (!IS_ENABLED(CONFIG_COMPACTION)) ++ gfp &= ~__GFP_MOVABLE; ++ + zspage->magic = ZSPAGE_MAGIC; + migrate_lock_init(zspage); + +diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c +index c7236daa24152a..0d7c14a4966819 100644 +--- a/net/appletalk/aarp.c ++++ b/net/appletalk/aarp.c +@@ -35,6 +35,7 @@ + #include <linux/seq_file.h> + #include <linux/export.h> + #include <linux/etherdevice.h> ++#include <linux/refcount.h> + + int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; + int sysctl_aarp_tick_time = AARP_TICK_TIME; +@@ -44,6 +45,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + /* Lists of aarp entries */ + /** + * struct aarp_entry - AARP entry ++ * @refcnt: Reference count + * @last_sent: Last time we xmitted the aarp request + * @packet_queue: Queue of frames wait for resolution + * @status: Used for proxy AARP +@@ -55,6 +57,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + * @next: Next entry in chain + */ + struct aarp_entry { ++ refcount_t refcnt; + /* These first two are only used for unresolved entries */ + unsigned long last_sent; + struct sk_buff_head packet_queue; +@@ -79,6 +82,17 @@ static DEFINE_RWLOCK(aarp_lock); + /* Used to walk the list and purge/kick entries. */ + static struct timer_list aarp_timer; + ++static inline void aarp_entry_get(struct aarp_entry *a) ++{ ++ refcount_inc(&a->refcnt); ++} ++ ++static inline void aarp_entry_put(struct aarp_entry *a) ++{ ++ if (refcount_dec_and_test(&a->refcnt)) ++ kfree(a); ++} ++ + /* + * Delete an aarp queue + * +@@ -87,7 +101,7 @@ static struct timer_list aarp_timer; + static void __aarp_expire(struct aarp_entry *a) + { + skb_queue_purge(&a->packet_queue); +- kfree(a); ++ aarp_entry_put(a); + } + + /* +@@ -380,9 +394,11 @@ static void aarp_purge(void) + static struct aarp_entry *aarp_alloc(void) + { + struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); ++ if (!a) ++ return NULL; + +- if (a) +- skb_queue_head_init(&a->packet_queue); ++ refcount_set(&a->refcnt, 1); ++ skb_queue_head_init(&a->packet_queue); + return a; + } + +@@ -508,6 +524,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) + entry->dev = atif->dev; + + write_lock_bh(&aarp_lock); ++ aarp_entry_get(entry); + + hash = sa->s_node % (AARP_HASH_SIZE - 1); + entry->next = proxies[hash]; +@@ -533,6 +550,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) + retval = 1; + } + ++ aarp_entry_put(entry); + write_unlock_bh(&aarp_lock); + out: + return retval; +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 6ef98608ac64cc..8d4889a730064d 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -979,8 +979,9 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, + if (subflow->mp_join) + goto reset; + subflow->mp_capable = 0; ++ if (!mptcp_try_fallback(ssk)) ++ goto reset; + pr_fallback(msk); +- mptcp_do_fallback(ssk); + return false; + } + +diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c +index 157a574fab0ccf..29c167e5fc0255 100644 +--- a/net/mptcp/pm.c ++++ b/net/mptcp/pm.c +@@ -304,8 +304,14 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) + + pr_debug("fail_seq=%llu\n", fail_seq); + +- if (!READ_ONCE(msk->allow_infinite_fallback)) ++ /* After accepting the fail, we can't create any other subflows */ ++ spin_lock_bh(&msk->fallback_lock); ++ if (!msk->allow_infinite_fallback) { ++ spin_unlock_bh(&msk->fallback_lock); + return; ++ } ++ msk->allow_subflows = false; ++ spin_unlock_bh(&msk->fallback_lock); + + if (!subflow->fail_tout) { + pr_debug("send MP_FAIL response and infinite map\n"); +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 140c3ffcb86ba0..e3f09467b36b2f 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -623,10 +623,9 @@ static bool mptcp_check_data_fin(struct sock *sk) + + static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk) + { +- if (READ_ONCE(msk->allow_infinite_fallback)) { ++ if (mptcp_try_fallback(ssk)) { + MPTCP_INC_STATS(sock_net(ssk), + MPTCP_MIB_DSSCORRUPTIONFALLBACK); +- mptcp_do_fallback(ssk); + } else { + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET); + mptcp_subflow_reset(ssk); +@@ -876,7 +875,7 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk) + static void mptcp_subflow_joined(struct mptcp_sock *msk, struct sock *ssk) + { + mptcp_subflow_ctx(ssk)->map_seq = READ_ONCE(msk->ack_seq); +- WRITE_ONCE(msk->allow_infinite_fallback, false); ++ msk->allow_infinite_fallback = false; + mptcp_event(MPTCP_EVENT_SUB_ESTABLISHED, msk, ssk, GFP_ATOMIC); + } + +@@ -887,6 +886,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk) + if (sk->sk_state != TCP_ESTABLISHED) + return false; + ++ spin_lock_bh(&msk->fallback_lock); ++ if (!msk->allow_subflows) { ++ spin_unlock_bh(&msk->fallback_lock); ++ return false; ++ } ++ mptcp_subflow_joined(msk, ssk); ++ spin_unlock_bh(&msk->fallback_lock); ++ + /* attach to msk socket only after we are sure we will deal with it + * at close time + */ +@@ -895,7 +902,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk) + + mptcp_subflow_ctx(ssk)->subflow_id = msk->subflow_id++; + mptcp_sockopt_sync_locked(msk, ssk); +- mptcp_subflow_joined(msk, ssk); + mptcp_stop_tout_timer(sk); + __mptcp_propagate_sndbuf(sk, ssk); + return true; +@@ -1231,10 +1237,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, + mpext->infinite_map = 1; + mpext->data_len = 0; + ++ if (!mptcp_try_fallback(ssk)) { ++ mptcp_subflow_reset(ssk); ++ return; ++ } ++ + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX); + mptcp_subflow_ctx(ssk)->send_infinite_map = 0; + pr_fallback(msk); +- mptcp_do_fallback(ssk); + } + + #define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1)) +@@ -2606,9 +2616,9 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk) + + static void __mptcp_retrans(struct sock *sk) + { ++ struct mptcp_sendmsg_info info = { .data_lock_held = true, }; + struct mptcp_sock *msk = mptcp_sk(sk); + struct mptcp_subflow_context *subflow; +- struct mptcp_sendmsg_info info = {}; + struct mptcp_data_frag *dfrag; + struct sock *ssk; + int ret, err; +@@ -2653,6 +2663,18 @@ static void __mptcp_retrans(struct sock *sk) + info.sent = 0; + info.limit = READ_ONCE(msk->csum_enabled) ? dfrag->data_len : + dfrag->already_sent; ++ ++ /* ++ * make the whole retrans decision, xmit, disallow ++ * fallback atomic ++ */ ++ spin_lock_bh(&msk->fallback_lock); ++ if (__mptcp_check_fallback(msk)) { ++ spin_unlock_bh(&msk->fallback_lock); ++ release_sock(ssk); ++ return; ++ } ++ + while (info.sent < info.limit) { + ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info); + if (ret <= 0) +@@ -2666,8 +2688,9 @@ static void __mptcp_retrans(struct sock *sk) + len = max(copied, len); + tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle, + info.size_goal); +- WRITE_ONCE(msk->allow_infinite_fallback, false); ++ msk->allow_infinite_fallback = false; + } ++ spin_unlock_bh(&msk->fallback_lock); + + release_sock(ssk); + } +@@ -2796,11 +2819,13 @@ static void __mptcp_init_sock(struct sock *sk) + WRITE_ONCE(msk->first, NULL); + inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; + WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); +- WRITE_ONCE(msk->allow_infinite_fallback, true); ++ msk->allow_infinite_fallback = true; ++ msk->allow_subflows = true; + msk->recovery = false; + msk->subflow_id = 1; + + mptcp_pm_data_init(msk); ++ spin_lock_init(&msk->fallback_lock); + + /* re-use the csk retrans timer for MPTCP-level retrans */ + timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0); +@@ -3183,7 +3208,16 @@ static int mptcp_disconnect(struct sock *sk, int flags) + * subflow + */ + mptcp_destroy_common(msk, MPTCP_CF_FASTCLOSE); ++ ++ /* The first subflow is already in TCP_CLOSE status, the following ++ * can't overlap with a fallback anymore ++ */ ++ spin_lock_bh(&msk->fallback_lock); ++ msk->allow_subflows = true; ++ msk->allow_infinite_fallback = true; + WRITE_ONCE(msk->flags, 0); ++ spin_unlock_bh(&msk->fallback_lock); ++ + msk->cb_flags = 0; + msk->recovery = false; + msk->can_ack = false; +@@ -3599,7 +3633,13 @@ bool mptcp_finish_join(struct sock *ssk) + + /* active subflow, already present inside the conn_list */ + if (!list_empty(&subflow->node)) { ++ spin_lock_bh(&msk->fallback_lock); ++ if (!msk->allow_subflows) { ++ spin_unlock_bh(&msk->fallback_lock); ++ return false; ++ } + mptcp_subflow_joined(msk, ssk); ++ spin_unlock_bh(&msk->fallback_lock); + mptcp_propagate_sndbuf(parent, ssk); + return true; + } +@@ -3712,7 +3752,7 @@ static void mptcp_subflow_early_fallback(struct mptcp_sock *msk, + struct mptcp_subflow_context *subflow) + { + subflow->request_mptcp = 0; +- __mptcp_do_fallback(msk); ++ WARN_ON_ONCE(!__mptcp_try_fallback(msk)); + } + + static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index d67add91c9b905..c5f41cdb36c4b1 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -330,10 +330,16 @@ struct mptcp_sock { + u64 rtt_us; /* last maximum rtt of subflows */ + } rcvq_space; + u8 scaling_ratio; ++ bool allow_subflows; + + u32 subflow_id; + u32 setsockopt_seq; + char ca_name[TCP_CA_NAME_MAX]; ++ ++ spinlock_t fallback_lock; /* protects fallback, ++ * allow_infinite_fallback and ++ * allow_join ++ */ + }; + + #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock) +@@ -1097,25 +1103,33 @@ static inline bool mptcp_check_fallback(const struct sock *sk) + return __mptcp_check_fallback(msk); + } + +-static inline void __mptcp_do_fallback(struct mptcp_sock *msk) ++static inline bool __mptcp_try_fallback(struct mptcp_sock *msk) + { + if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags)) { + pr_debug("TCP fallback already done (msk=%p)\n", msk); +- return; ++ return true; + } +- if (WARN_ON_ONCE(!READ_ONCE(msk->allow_infinite_fallback))) +- return; ++ spin_lock_bh(&msk->fallback_lock); ++ if (!msk->allow_infinite_fallback) { ++ spin_unlock_bh(&msk->fallback_lock); ++ return false; ++ } ++ ++ msk->allow_subflows = false; + set_bit(MPTCP_FALLBACK_DONE, &msk->flags); ++ spin_unlock_bh(&msk->fallback_lock); ++ return true; + } + +-static inline void mptcp_do_fallback(struct sock *ssk) ++static inline bool mptcp_try_fallback(struct sock *ssk) + { + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + struct sock *sk = subflow->conn; + struct mptcp_sock *msk; + + msk = mptcp_sk(sk); +- __mptcp_do_fallback(msk); ++ if (!__mptcp_try_fallback(msk)) ++ return false; + if (READ_ONCE(msk->snd_data_fin_enable) && !(ssk->sk_shutdown & SEND_SHUTDOWN)) { + gfp_t saved_allocation = ssk->sk_allocation; + +@@ -1127,6 +1141,7 @@ static inline void mptcp_do_fallback(struct sock *ssk) + tcp_shutdown(ssk, SEND_SHUTDOWN); + ssk->sk_allocation = saved_allocation; + } ++ return true; + } + + #define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)\n", __func__, a) +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index f4b8ca8be81e8a..a01ea18283c726 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -524,9 +524,11 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) + mptcp_get_options(skb, &mp_opt); + if (subflow->request_mptcp) { + if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYNACK)) { ++ if (!mptcp_try_fallback(sk)) ++ goto do_reset; ++ + MPTCP_INC_STATS(sock_net(sk), + MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); +- mptcp_do_fallback(sk); + pr_fallback(msk); + goto fallback; + } +@@ -1255,20 +1257,29 @@ static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ss + mptcp_schedule_work(sk); + } + +-static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) ++static bool mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) + { + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + unsigned long fail_tout; + ++ /* we are really failing, prevent any later subflow join */ ++ spin_lock_bh(&msk->fallback_lock); ++ if (!msk->allow_infinite_fallback) { ++ spin_unlock_bh(&msk->fallback_lock); ++ return false; ++ } ++ msk->allow_subflows = false; ++ spin_unlock_bh(&msk->fallback_lock); ++ + /* greceful failure can happen only on the MPC subflow */ + if (WARN_ON_ONCE(ssk != READ_ONCE(msk->first))) +- return; ++ return false; + + /* since the close timeout take precedence on the fail one, + * no need to start the latter when the first is already set + */ + if (sock_flag((struct sock *)msk, SOCK_DEAD)) +- return; ++ return true; + + /* we don't need extreme accuracy here, use a zero fail_tout as special + * value meaning no fail timeout at all; +@@ -1280,6 +1291,7 @@ static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) + tcp_send_ack(ssk); + + mptcp_reset_tout_timer(msk, subflow->fail_tout); ++ return true; + } + + static bool subflow_check_data_avail(struct sock *ssk) +@@ -1340,17 +1352,16 @@ static bool subflow_check_data_avail(struct sock *ssk) + (subflow->mp_join || subflow->valid_csum_seen)) { + subflow->send_mp_fail = 1; + +- if (!READ_ONCE(msk->allow_infinite_fallback)) { ++ if (!mptcp_subflow_fail(msk, ssk)) { + subflow->reset_transient = 0; + subflow->reset_reason = MPTCP_RST_EMIDDLEBOX; + goto reset; + } +- mptcp_subflow_fail(msk, ssk); + WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_DATA_AVAIL); + return true; + } + +- if (!READ_ONCE(msk->allow_infinite_fallback)) { ++ if (!mptcp_try_fallback(ssk)) { + /* fatal protocol error, close the socket. + * subflow_error_report() will introduce the appropriate barriers + */ +@@ -1366,8 +1377,6 @@ static bool subflow_check_data_avail(struct sock *ssk) + WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); + return false; + } +- +- mptcp_do_fallback(ssk); + } + + skb = skb_peek(&ssk->sk_receive_queue); +@@ -1612,7 +1621,6 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, + /* discard the subflow socket */ + mptcp_sock_graft(ssk, sk->sk_socket); + iput(SOCK_INODE(sf)); +- WRITE_ONCE(msk->allow_infinite_fallback, false); + mptcp_stop_tout_timer(sk); + return 0; + +@@ -1790,7 +1798,7 @@ static void subflow_state_change(struct sock *sk) + + msk = mptcp_sk(parent); + if (subflow_simultaneous_connect(sk)) { +- mptcp_do_fallback(sk); ++ WARN_ON_ONCE(!mptcp_try_fallback(sk)); + pr_fallback(msk); + subflow->conn_finished = 1; + mptcp_propagate_state(parent, sk, subflow, NULL); +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index a2b321fec13c1d..c3f9a6375b4ea6 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -539,9 +539,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + + static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl) + { +- struct qfq_sched *q = qdisc_priv(sch); +- +- qfq_rm_from_agg(q, cl); + gen_kill_estimator(&cl->rate_est); + qdisc_put(cl->qdisc); + kfree(cl); +@@ -562,10 +559,11 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg, + + qdisc_purge_queue(cl->qdisc); + qdisc_class_hash_remove(&q->clhash, &cl->common); +- qfq_destroy_class(sch, cl); ++ qfq_rm_from_agg(q, cl); + + sch_tree_unlock(sch); + ++ qfq_destroy_class(sch, cl); + return 0; + } + +@@ -1506,6 +1504,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch) + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i], + common.hnode) { ++ qfq_rm_from_agg(q, cl); + qfq_destroy_class(sch, cl); + } + } +diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c +index e21cc71095bb27..ca6db1e960ce64 100644 +--- a/net/xfrm/xfrm_interface_core.c ++++ b/net/xfrm/xfrm_interface_core.c +@@ -880,7 +880,7 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], + return -EINVAL; + } + +- if (p.collect_md) { ++ if (p.collect_md || xi->p.collect_md) { + NL_SET_ERR_MSG(extack, "collect_md can't be changed"); + return -EINVAL; + } +@@ -891,11 +891,6 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], + } else { + if (xi->dev != dev) + return -EEXIST; +- if (xi->p.collect_md) { +- NL_SET_ERR_MSG(extack, +- "device can't be changed to collect_md"); +- return -EINVAL; +- } + } + + return xfrmi_update(xi, &p); +diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c +index d967e70a705859..12a144a269ee89 100644 +--- a/sound/pci/hda/hda_tegra.c ++++ b/sound/pci/hda/hda_tegra.c +@@ -72,6 +72,10 @@ + struct hda_tegra_soc { + bool has_hda2codec_2x_reset; + bool has_hda2hdmi; ++ bool has_hda2codec_2x; ++ bool input_stream; ++ bool always_on; ++ bool requires_init; + }; + + struct hda_tegra { +@@ -187,7 +191,9 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) + if (rc != 0) + return rc; + if (chip->running) { +- hda_tegra_init(hda); ++ if (hda->soc->requires_init) ++ hda_tegra_init(hda); ++ + azx_init_chip(chip, 1); + /* disable controller wake up event*/ + azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & +@@ -252,7 +258,8 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) + bus->remap_addr = hda->regs + HDA_BAR0; + bus->addr = res->start + HDA_BAR0; + +- hda_tegra_init(hda); ++ if (hda->soc->requires_init) ++ hda_tegra_init(hda); + + return 0; + } +@@ -325,7 +332,7 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) + * starts with offset 0 which is wrong as HW register for output stream + * offset starts with 4. + */ +- if (of_device_is_compatible(np, "nvidia,tegra234-hda")) ++ if (!hda->soc->input_stream) + chip->capture_streams = 4; + + chip->playback_streams = (gcap >> 12) & 0x0f; +@@ -421,7 +428,6 @@ static int hda_tegra_create(struct snd_card *card, + chip->driver_caps = driver_caps; + chip->driver_type = driver_caps & 0xff; + chip->dev_index = 0; +- chip->jackpoll_interval = msecs_to_jiffies(5000); + INIT_LIST_HEAD(&chip->pcm_list); + + chip->codec_probe_mask = -1; +@@ -438,7 +444,16 @@ static int hda_tegra_create(struct snd_card *card, + chip->bus.core.sync_write = 0; + chip->bus.core.needs_damn_long_delay = 1; + chip->bus.core.aligned_mmio = 1; +- chip->bus.jackpoll_in_suspend = 1; ++ ++ /* ++ * HDA power domain and clocks are always on for Tegra264 and ++ * the jack detection logic would work always, so no need of ++ * jack polling mechanism running. ++ */ ++ if (!hda->soc->always_on) { ++ chip->jackpoll_interval = msecs_to_jiffies(5000); ++ chip->bus.jackpoll_in_suspend = 1; ++ } + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) { +@@ -452,22 +467,44 @@ static int hda_tegra_create(struct snd_card *card, + static const struct hda_tegra_soc tegra30_data = { + .has_hda2codec_2x_reset = true, + .has_hda2hdmi = true, ++ .has_hda2codec_2x = true, ++ .input_stream = true, ++ .always_on = false, ++ .requires_init = true, + }; + + static const struct hda_tegra_soc tegra194_data = { + .has_hda2codec_2x_reset = false, + .has_hda2hdmi = true, ++ .has_hda2codec_2x = true, ++ .input_stream = true, ++ .always_on = false, ++ .requires_init = true, + }; + + static const struct hda_tegra_soc tegra234_data = { + .has_hda2codec_2x_reset = true, + .has_hda2hdmi = false, ++ .has_hda2codec_2x = true, ++ .input_stream = false, ++ .always_on = false, ++ .requires_init = true, ++}; ++ ++static const struct hda_tegra_soc tegra264_data = { ++ .has_hda2codec_2x_reset = true, ++ .has_hda2hdmi = false, ++ .has_hda2codec_2x = false, ++ .input_stream = false, ++ .always_on = true, ++ .requires_init = false, + }; + + static const struct of_device_id hda_tegra_match[] = { + { .compatible = "nvidia,tegra30-hda", .data = &tegra30_data }, + { .compatible = "nvidia,tegra194-hda", .data = &tegra194_data }, + { .compatible = "nvidia,tegra234-hda", .data = &tegra234_data }, ++ { .compatible = "nvidia,tegra264-hda", .data = &tegra264_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, hda_tegra_match); +@@ -522,7 +559,9 @@ static int hda_tegra_probe(struct platform_device *pdev) + hda->clocks[hda->nclocks++].id = "hda"; + if (hda->soc->has_hda2hdmi) + hda->clocks[hda->nclocks++].id = "hda2hdmi"; +- hda->clocks[hda->nclocks++].id = "hda2codec_2x"; ++ ++ if (hda->soc->has_hda2codec_2x) ++ hda->clocks[hda->nclocks++].id = "hda2codec_2x"; + + err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); + if (err < 0) +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index f030700cd60d75..f2c03fbf892f1b 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -4559,6 +4559,9 @@ HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi), + HDA_CODEC_ENTRY(0x10de0031, "Tegra234 HDMI/DP", patch_tegra234_hdmi), ++HDA_CODEC_ENTRY(0x10de0033, "SoC 33 HDMI/DP", patch_tegra234_hdmi), ++HDA_CODEC_ENTRY(0x10de0034, "Tegra264 HDMI/DP", patch_tegra234_hdmi), ++HDA_CODEC_ENTRY(0x10de0035, "SoC 35 HDMI/DP", patch_tegra234_hdmi), + HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi), +@@ -4597,15 +4600,32 @@ HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009a, "GPU 9a HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de009b, "GPU 9b HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de009c, "GPU 9c HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a1, "GPU a1 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a3, "GPU a3 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a4, "GPU a4 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a5, "GPU a5 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a6, "GPU a6 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a7, "GPU a7 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a8, "GPU a8 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a9, "GPU a9 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00aa, "GPU aa HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00ab, "GPU ab HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00ad, "GPU ad HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00ae, "GPU ae HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00af, "GPU af HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00b0, "GPU b0 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00b1, "GPU b1 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00c0, "GPU c0 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00c1, "GPU c1 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00c3, "GPU c3 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00c4, "GPU c4 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00c5, "GPU c5 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch), + HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch), + HDA_CODEC_ENTRY(0x67663d82, "Arise 82 HDMI/DP", patch_gf_hdmi), +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 614784c0ba3188..e12e3134b5e16b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10103,6 +10103,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x87b7, "HP Laptop 14-fq0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x87cc, "HP Pavilion 15-eg0xxx", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87d3, "HP Laptop 15-gw0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x87df, "HP ProBook 430 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), +diff --git a/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c +index 2c57ceede095eb..a84c41862ff8c9 100644 +--- a/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c ++++ b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c +@@ -12,7 +12,6 @@ + #include <sys/wait.h> + #include <sys/mount.h> + #include <fcntl.h> +-#include "network_helpers.h" + + #define STACK_SIZE (1024 * 1024) + static char child_stack[STACK_SIZE]; +@@ -75,50 +74,6 @@ static int test_current_pid_tgid_tp(void *args) + return ret; + } + +-static int test_current_pid_tgid_cgrp(void *args) +-{ +- struct test_ns_current_pid_tgid__bss *bss; +- struct test_ns_current_pid_tgid *skel; +- int server_fd = -1, ret = -1, err; +- int cgroup_fd = *(int *)args; +- pid_t tgid, pid; +- +- skel = test_ns_current_pid_tgid__open(); +- if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open")) +- return ret; +- +- bpf_program__set_autoload(skel->progs.cgroup_bind4, true); +- +- err = test_ns_current_pid_tgid__load(skel); +- if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load")) +- goto cleanup; +- +- bss = skel->bss; +- if (get_pid_tgid(&pid, &tgid, bss)) +- goto cleanup; +- +- skel->links.cgroup_bind4 = bpf_program__attach_cgroup( +- skel->progs.cgroup_bind4, cgroup_fd); +- if (!ASSERT_OK_PTR(skel->links.cgroup_bind4, "bpf_program__attach_cgroup")) +- goto cleanup; +- +- server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0); +- if (!ASSERT_GE(server_fd, 0, "start_server")) +- goto cleanup; +- +- if (!ASSERT_EQ(bss->user_pid, pid, "pid")) +- goto cleanup; +- if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid")) +- goto cleanup; +- ret = 0; +- +-cleanup: +- if (server_fd >= 0) +- close(server_fd); +- test_ns_current_pid_tgid__destroy(skel); +- return ret; +-} +- + static void test_ns_current_pid_tgid_new_ns(int (*fn)(void *), void *arg) + { + int wstatus; +@@ -140,25 +95,6 @@ static void test_ns_current_pid_tgid_new_ns(int (*fn)(void *), void *arg) + return; + } + +-static void test_in_netns(int (*fn)(void *), void *arg) +-{ +- struct nstoken *nstoken = NULL; +- +- SYS(cleanup, "ip netns add ns_current_pid_tgid"); +- SYS(cleanup, "ip -net ns_current_pid_tgid link set dev lo up"); +- +- nstoken = open_netns("ns_current_pid_tgid"); +- if (!ASSERT_OK_PTR(nstoken, "open_netns")) +- goto cleanup; +- +- test_ns_current_pid_tgid_new_ns(fn, arg); +- +-cleanup: +- if (nstoken) +- close_netns(nstoken); +- SYS_NOFAIL("ip netns del ns_current_pid_tgid"); +-} +- + /* TODO: use a different tracepoint */ + void serial_test_ns_current_pid_tgid(void) + { +@@ -166,13 +102,4 @@ void serial_test_ns_current_pid_tgid(void) + test_current_pid_tgid_tp(NULL); + if (test__start_subtest("new_ns_tp")) + test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_tp, NULL); +- if (test__start_subtest("new_ns_cgrp")) { +- int cgroup_fd = -1; +- +- cgroup_fd = test__join_cgroup("/sock_addr"); +- if (ASSERT_GE(cgroup_fd, 0, "join_cgroup")) { +- test_in_netns(test_current_pid_tgid_cgrp, &cgroup_fd); +- close(cgroup_fd); +- } +- } + } +diff --git a/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c +index d0010e698f6688..aa3ec7ca16d9b6 100644 +--- a/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c ++++ b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c +@@ -28,11 +28,4 @@ int tp_handler(const void *ctx) + return 0; + } + +-SEC("?cgroup/bind4") +-int cgroup_bind4(struct bpf_sock_addr *ctx) +-{ +- get_pid_tgid(); +- return 1; +-} +- + char _license[] SEC("license") = "GPL"; +diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile +index 7b936a92685949..3c2fb9efb0b140 100644 +--- a/tools/testing/selftests/net/mptcp/Makefile ++++ b/tools/testing/selftests/net/mptcp/Makefile +@@ -4,7 +4,8 @@ top_srcdir = ../../../../.. + + CFLAGS = -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INCLUDES) + +-TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh diag.sh \ ++TEST_PROGS := mptcp_connect.sh mptcp_connect_mmap.sh mptcp_connect_sendfile.sh \ ++ mptcp_connect_checksum.sh pm_netlink.sh mptcp_join.sh diag.sh \ + simult_flows.sh mptcp_sockopt.sh userspace_pm.sh + + TEST_GEN_FILES = mptcp_connect pm_nl_ctl mptcp_sockopt mptcp_inq +diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect_checksum.sh b/tools/testing/selftests/net/mptcp/mptcp_connect_checksum.sh +new file mode 100644 +index 00000000000000..ce93ec2f107fba +--- /dev/null ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect_checksum.sh +@@ -0,0 +1,5 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++MPTCP_LIB_KSFT_TEST="$(basename "${0}" .sh)" \ ++ "$(dirname "${0}")/mptcp_connect.sh" -C "${@}" +diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect_mmap.sh b/tools/testing/selftests/net/mptcp/mptcp_connect_mmap.sh +new file mode 100644 +index 00000000000000..5dd30f9394af6a +--- /dev/null ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect_mmap.sh +@@ -0,0 +1,5 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++MPTCP_LIB_KSFT_TEST="$(basename "${0}" .sh)" \ ++ "$(dirname "${0}")/mptcp_connect.sh" -m mmap "${@}" +diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect_sendfile.sh b/tools/testing/selftests/net/mptcp/mptcp_connect_sendfile.sh +new file mode 100644 +index 00000000000000..1d16fb1cc9bb6d +--- /dev/null ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect_sendfile.sh +@@ -0,0 +1,5 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++MPTCP_LIB_KSFT_TEST="$(basename "${0}" .sh)" \ ++ "$(dirname "${0}")/mptcp_connect.sh" -m sendfile "${@}"
