diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-01-10 12:16:10 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-01-10 12:16:10 -0500 |
commit | c14326fce46638009baf2da6a6794dd857059860 (patch) | |
tree | 25819f9de2938f6a8c8335d4bb07665f5ef7e15e /1010_linux-6.6.11.patch | |
parent | Linux patch 6.6.10 (diff) | |
download | linux-patches-c14326fce46638009baf2da6a6794dd857059860.tar.gz linux-patches-c14326fce46638009baf2da6a6794dd857059860.tar.bz2 linux-patches-c14326fce46638009baf2da6a6794dd857059860.zip |
Linux patch 6.6.11
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
Diffstat (limited to '1010_linux-6.6.11.patch')
-rw-r--r-- | 1010_linux-6.6.11.patch | 5526 |
1 files changed, 5526 insertions, 0 deletions
diff --git a/1010_linux-6.6.11.patch b/1010_linux-6.6.11.patch new file mode 100644 index 00000000..a33162c4 --- /dev/null +++ b/1010_linux-6.6.11.patch @@ -0,0 +1,5526 @@ +diff --git a/Makefile b/Makefile +index 50a862316e156..43edafa7f262d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 10 ++SUBLEVEL = 11 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c +index cb63921232a6f..6ec3445f3c723 100644 +--- a/arch/arm/mach-sunxi/mc_smp.c ++++ b/arch/arm/mach-sunxi/mc_smp.c +@@ -807,12 +807,12 @@ static int __init sunxi_mc_smp_init(void) + break; + } + +- is_a83t = sunxi_mc_smp_data[i].is_a83t; +- + of_node_put(node); + if (ret) + return -ENODEV; + ++ is_a83t = sunxi_mc_smp_data[i].is_a83t; ++ + if (!sunxi_mc_smp_cpu_table_init()) + return -EINVAL; + +diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c +index b1f25bac280b4..71d52a670d951 100644 +--- a/arch/powerpc/platforms/pseries/vas.c ++++ b/arch/powerpc/platforms/pseries/vas.c +@@ -385,11 +385,15 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + * same fault IRQ is not freed by the OS before. + */ + mutex_lock(&vas_pseries_mutex); +- if (migration_in_progress) ++ if (migration_in_progress) { + rc = -EBUSY; +- else ++ } else { + rc = allocate_setup_window(txwin, (u64 *)&domain[0], + cop_feat_caps->win_type); ++ if (!rc) ++ caps->nr_open_wins_progress++; ++ } ++ + mutex_unlock(&vas_pseries_mutex); + if (rc) + goto out; +@@ -404,8 +408,17 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + goto out_free; + + txwin->win_type = cop_feat_caps->win_type; +- mutex_lock(&vas_pseries_mutex); ++ + /* ++ * The migration SUSPEND thread sets migration_in_progress and ++ * closes all open windows from the list. But the window is ++ * added to the list after open and modify HCALLs. So possible ++ * that migration_in_progress is set before modify HCALL which ++ * may cause some windows are still open when the hypervisor ++ * initiates the migration. ++ * So checks the migration_in_progress flag again and close all ++ * open windows. ++ * + * Possible to lose the acquired credit with DLPAR core + * removal after the window is opened. So if there are any + * closed windows (means with lost credits), do not give new +@@ -413,9 +426,11 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + * after the existing windows are reopened when credits are + * available. + */ +- if (!caps->nr_close_wins) { ++ mutex_lock(&vas_pseries_mutex); ++ if (!caps->nr_close_wins && !migration_in_progress) { + list_add(&txwin->win_list, &caps->list); + caps->nr_open_windows++; ++ caps->nr_open_wins_progress--; + mutex_unlock(&vas_pseries_mutex); + vas_user_win_add_mm_context(&txwin->vas_win.task_ref); + return &txwin->vas_win; +@@ -433,6 +448,12 @@ out_free: + */ + free_irq_setup(txwin); + h_deallocate_vas_window(txwin->vas_win.winid); ++ /* ++ * Hold mutex and reduce nr_open_wins_progress counter. ++ */ ++ mutex_lock(&vas_pseries_mutex); ++ caps->nr_open_wins_progress--; ++ mutex_unlock(&vas_pseries_mutex); + out: + atomic_dec(&cop_feat_caps->nr_used_credits); + kfree(txwin); +@@ -937,14 +958,14 @@ int vas_migration_handler(int action) + struct vas_caps *vcaps; + int i, rc = 0; + ++ pr_info("VAS migration event %d\n", action); ++ + /* + * NX-GZIP is not enabled. Nothing to do for migration. + */ + if (!copypaste_feat) + return rc; + +- mutex_lock(&vas_pseries_mutex); +- + if (action == VAS_SUSPEND) + migration_in_progress = true; + else +@@ -990,12 +1011,27 @@ int vas_migration_handler(int action) + + switch (action) { + case VAS_SUSPEND: ++ mutex_lock(&vas_pseries_mutex); + rc = reconfig_close_windows(vcaps, vcaps->nr_open_windows, + true); ++ /* ++ * Windows are included in the list after successful ++ * open. So wait for closing these in-progress open ++ * windows in vas_allocate_window() which will be ++ * done if the migration_in_progress is set. ++ */ ++ while (vcaps->nr_open_wins_progress) { ++ mutex_unlock(&vas_pseries_mutex); ++ msleep(10); ++ mutex_lock(&vas_pseries_mutex); ++ } ++ mutex_unlock(&vas_pseries_mutex); + break; + case VAS_RESUME: ++ mutex_lock(&vas_pseries_mutex); + atomic_set(&caps->nr_total_credits, new_nr_creds); + rc = reconfig_open_windows(vcaps, new_nr_creds, true); ++ mutex_unlock(&vas_pseries_mutex); + break; + default: + /* should not happen */ +@@ -1011,8 +1047,9 @@ int vas_migration_handler(int action) + goto out; + } + ++ pr_info("VAS migration event (%d) successful\n", action); ++ + out: +- mutex_unlock(&vas_pseries_mutex); + return rc; + } + +diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h +index 7115043ec4883..45567cd131783 100644 +--- a/arch/powerpc/platforms/pseries/vas.h ++++ b/arch/powerpc/platforms/pseries/vas.h +@@ -91,6 +91,8 @@ struct vas_cop_feat_caps { + struct vas_caps { + struct vas_cop_feat_caps caps; + struct list_head list; /* List of open windows */ ++ int nr_open_wins_progress; /* Number of open windows in */ ++ /* progress. Used in migration */ + int nr_close_wins; /* closed windows in the hypervisor for DLPAR */ + int nr_open_windows; /* Number of successful open windows */ + u8 feat; /* Feature type */ +diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c +index 1cfbba65d11ae..e12cd22755c78 100644 +--- a/arch/riscv/kernel/cpufeature.c ++++ b/arch/riscv/kernel/cpufeature.c +@@ -568,6 +568,10 @@ void check_unaligned_access(int cpu) + void *src; + long speed = RISCV_HWPROBE_MISALIGNED_SLOW; + ++ /* We are already set since the last check */ ++ if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN) ++ return; ++ + page = alloc_pages(GFP_NOWAIT, get_order(MISALIGNED_BUFFER_SIZE)); + if (!page) { + pr_warn("Can't alloc pages to measure memcpy performance"); +diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c +index 6cf23b8adb712..e808723a85f1b 100644 +--- a/arch/riscv/kvm/aia_imsic.c ++++ b/arch/riscv/kvm/aia_imsic.c +@@ -55,6 +55,7 @@ struct imsic { + /* IMSIC SW-file */ + struct imsic_mrif *swfile; + phys_addr_t swfile_pa; ++ spinlock_t swfile_extirq_lock; + }; + + #define imsic_vs_csr_read(__c) \ +@@ -613,12 +614,23 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu) + { + struct imsic *imsic = vcpu->arch.aia_context.imsic_state; + struct imsic_mrif *mrif = imsic->swfile; ++ unsigned long flags; ++ ++ /* ++ * The critical section is necessary during external interrupt ++ * updates to avoid the risk of losing interrupts due to potential ++ * interruptions between reading topei and updating pending status. ++ */ ++ ++ spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); + + if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && + imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) + kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT); + else + kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT); ++ ++ spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); + } + + static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear, +@@ -1039,6 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu) + } + imsic->swfile = page_to_virt(swfile_page); + imsic->swfile_pa = page_to_phys(swfile_page); ++ spin_lock_init(&imsic->swfile_extirq_lock); + + /* Setup IO device */ + kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); +diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c +index 61499293c2ac3..e55f489e1fb79 100644 +--- a/arch/s390/kvm/vsie.c ++++ b/arch/s390/kvm/vsie.c +@@ -587,10 +587,6 @@ void kvm_s390_vsie_gmap_notifier(struct gmap *gmap, unsigned long start, + + if (!gmap_is_shadow(gmap)) + return; +- if (start >= 1UL << 31) +- /* We are only interested in prefix pages */ +- return; +- + /* + * Only new shadow blocks are added to the list during runtime, + * therefore we can safely reference them all the time. +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index fa355d3658a65..bc4fcf0d94056 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4062,12 +4062,17 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data) + u64 pebs_mask = cpuc->pebs_enabled & x86_pmu.pebs_capable; + int global_ctrl, pebs_enable; + ++ /* ++ * In addition to obeying exclude_guest/exclude_host, remove bits being ++ * used for PEBS when running a guest, because PEBS writes to virtual ++ * addresses (not physical addresses). ++ */ + *nr = 0; + global_ctrl = (*nr)++; + arr[global_ctrl] = (struct perf_guest_switch_msr){ + .msr = MSR_CORE_PERF_GLOBAL_CTRL, + .host = intel_ctrl & ~cpuc->intel_ctrl_guest_mask, +- .guest = intel_ctrl & (~cpuc->intel_ctrl_host_mask | ~pebs_mask), ++ .guest = intel_ctrl & ~cpuc->intel_ctrl_host_mask & ~pebs_mask, + }; + + if (!x86_pmu.pebs) +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index e8babebad7b88..a0ce46c0a2d88 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -576,7 +576,8 @@ static void kprobe_emulate_call_indirect(struct kprobe *p, struct pt_regs *regs) + { + unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg]; + +- int3_emulate_call(regs, regs_get_register(regs, offs)); ++ int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + p->ainsn.size); ++ int3_emulate_jmp(regs, regs_get_register(regs, offs)); + } + NOKPROBE_SYMBOL(kprobe_emulate_call_indirect); + +diff --git a/crypto/xts.c b/crypto/xts.c +index 548b302c6c6a0..038f60dd512d9 100644 +--- a/crypto/xts.c ++++ b/crypto/xts.c +@@ -28,7 +28,7 @@ struct xts_tfm_ctx { + + struct xts_instance_ctx { + struct crypto_skcipher_spawn spawn; +- char name[CRYPTO_MAX_ALG_NAME]; ++ struct crypto_cipher_spawn tweak_spawn; + }; + + struct xts_request_ctx { +@@ -306,7 +306,7 @@ static int xts_init_tfm(struct crypto_skcipher *tfm) + + ctx->child = child; + +- tweak = crypto_alloc_cipher(ictx->name, 0, 0); ++ tweak = crypto_spawn_cipher(&ictx->tweak_spawn); + if (IS_ERR(tweak)) { + crypto_free_skcipher(ctx->child); + return PTR_ERR(tweak); +@@ -333,11 +333,13 @@ static void xts_free_instance(struct skcipher_instance *inst) + struct xts_instance_ctx *ictx = skcipher_instance_ctx(inst); + + crypto_drop_skcipher(&ictx->spawn); ++ crypto_drop_cipher(&ictx->tweak_spawn); + kfree(inst); + } + + static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) + { ++ char name[CRYPTO_MAX_ALG_NAME]; + struct skcipher_instance *inst; + struct xts_instance_ctx *ctx; + struct skcipher_alg *alg; +@@ -363,13 +365,13 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) + cipher_name, 0, mask); + if (err == -ENOENT) { + err = -ENAMETOOLONG; +- if (snprintf(ctx->name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", ++ if (snprintf(name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", + cipher_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + + err = crypto_grab_skcipher(&ctx->spawn, + skcipher_crypto_instance(inst), +- ctx->name, 0, mask); ++ name, 0, mask); + } + + if (err) +@@ -398,23 +400,28 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) + if (!strncmp(cipher_name, "ecb(", 4)) { + int len; + +- len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); ++ len = strscpy(name, cipher_name + 4, sizeof(name)); + if (len < 2) + goto err_free_inst; + +- if (ctx->name[len - 1] != ')') ++ if (name[len - 1] != ')') + goto err_free_inst; + +- ctx->name[len - 1] = 0; ++ name[len - 1] = 0; + + if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, +- "xts(%s)", ctx->name) >= CRYPTO_MAX_ALG_NAME) { ++ "xts(%s)", name) >= CRYPTO_MAX_ALG_NAME) { + err = -ENAMETOOLONG; + goto err_free_inst; + } + } else + goto err_free_inst; + ++ err = crypto_grab_cipher(&ctx->tweak_spawn, ++ skcipher_crypto_instance(inst), name, 0, mask); ++ if (err) ++ goto err_free_inst; ++ + inst->alg.base.cra_priority = alg->base.cra_priority; + inst->alg.base.cra_blocksize = XTS_BLOCK_SIZE; + inst->alg.base.cra_alignmask = alg->base.cra_alignmask | +diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_controller.c +index 5036e58e7235b..1405623b03e4e 100644 +--- a/drivers/accel/qaic/mhi_controller.c ++++ b/drivers/accel/qaic/mhi_controller.c +@@ -404,8 +404,21 @@ static struct mhi_controller_config aic100_config = { + + static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out) + { +- u32 tmp = readl_relaxed(addr); ++ u32 tmp; + ++ /* ++ * SOC_HW_VERSION quirk ++ * The SOC_HW_VERSION register (offset 0x224) is not reliable and ++ * may contain uninitialized values, including 0xFFFFFFFF. This could ++ * cause a false positive link down error. Instead, intercept any ++ * reads and provide the correct value of the register. ++ */ ++ if (addr - mhi_cntrl->regs == 0x224) { ++ *out = 0x60110200; ++ return 0; ++ } ++ ++ tmp = readl_relaxed(addr); + if (tmp == U32_MAX) + return -EIO; + +diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c +index f4b06792c6f1c..ed1a5af434f24 100644 +--- a/drivers/accel/qaic/qaic_data.c ++++ b/drivers/accel/qaic/qaic_data.c +@@ -766,7 +766,6 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_ + struct dma_buf_attachment *attach; + struct drm_gem_object *obj; + struct qaic_bo *bo; +- size_t size; + int ret; + + bo = qaic_alloc_init_bo(); +@@ -784,13 +783,12 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_ + goto attach_fail; + } + +- size = PAGE_ALIGN(attach->dmabuf->size); +- if (size == 0) { ++ if (!attach->dmabuf->size) { + ret = -EINVAL; + goto size_align_fail; + } + +- drm_gem_private_object_init(dev, obj, size); ++ drm_gem_private_object_init(dev, obj, attach->dmabuf->size); + /* + * skipping dma_buf_map_attachment() as we do not know the direction + * just yet. Once the direction is known in the subsequent IOCTL to +diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c +index 312730f8272ee..8263508415a8d 100644 +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -778,9 +778,9 @@ free_trip_table: + + static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) + { ++ thermal_zone_device_disable(tz->thermal_zone); + acpi_thermal_zone_sysfs_remove(tz); + thermal_zone_device_unregister(tz->thermal_zone); +- kfree(tz->trip_table); + tz->thermal_zone = NULL; + } + +@@ -985,7 +985,7 @@ static void acpi_thermal_remove(struct acpi_device *device) + + flush_workqueue(acpi_thermal_pm_queue); + acpi_thermal_unregister_thermal_zone(tz); +- ++ kfree(tz->trip_table); + kfree(tz); + } + +diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c +index ef4ba467e747b..5886bc54aa0e7 100644 +--- a/drivers/clk/clk-si521xx.c ++++ b/drivers/clk/clk-si521xx.c +@@ -282,7 +282,7 @@ static int si521xx_probe(struct i2c_client *client) + const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); + const struct clk_parent_data clk_parent_data = { .index = 0 }; + const u8 data[3] = { SI521XX_REG_BC, 1, 1 }; +- unsigned char name[6] = "DIFF0"; ++ unsigned char name[16] = "DIFF0"; + struct clk_init_data init = {}; + struct si521xx *si; + int i, ret; +@@ -316,7 +316,7 @@ static int si521xx_probe(struct i2c_client *client) + /* Register clock */ + for (i = 0; i < hweight16(chip_info); i++) { + memset(&init, 0, sizeof(init)); +- snprintf(name, 6, "DIFF%d", i); ++ snprintf(name, sizeof(name), "DIFF%d", i); + init.name = name; + init.ops = &si521xx_diff_clk_ops; + init.parent_data = &clk_parent_data; +diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c +index aa53797dbfc14..22e7522360307 100644 +--- a/drivers/clk/rockchip/clk-rk3128.c ++++ b/drivers/clk/rockchip/clk-rk3128.c +@@ -138,7 +138,7 @@ PNAME(mux_pll_src_5plls_p) = { "cpll", "gpll", "gpll_div2", "gpll_div3", "usb480 + PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "gpll_div2", "usb480m" }; + PNAME(mux_pll_src_3plls_p) = { "cpll", "gpll", "gpll_div2" }; + +-PNAME(mux_aclk_peri_src_p) = { "gpll_peri", "cpll_peri", "gpll_div2_peri", "gpll_div3_peri" }; ++PNAME(mux_clk_peri_src_p) = { "gpll", "cpll", "gpll_div2", "gpll_div3" }; + PNAME(mux_mmc_src_p) = { "cpll", "gpll", "gpll_div2", "xin24m" }; + PNAME(mux_clk_cif_out_src_p) = { "clk_cif_src", "xin24m" }; + PNAME(mux_sclk_vop_src_p) = { "cpll", "gpll", "gpll_div2", "gpll_div3" }; +@@ -275,23 +275,17 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { + RK2928_CLKGATE_CON(0), 11, GFLAGS), + + /* PD_PERI */ +- GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED, ++ COMPOSITE(0, "clk_peri_src", mux_clk_peri_src_p, 0, ++ RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS, + RK2928_CLKGATE_CON(2), 0, GFLAGS), +- GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(2), 0, GFLAGS), +- GATE(0, "gpll_div2_peri", "gpll_div2", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(2), 0, GFLAGS), +- GATE(0, "gpll_div3_peri", "gpll_div3", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(2), 0, GFLAGS), +- COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0, +- RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS), +- COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, ++ ++ COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "clk_peri_src", 0, + RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK2928_CLKGATE_CON(2), 3, GFLAGS), +- COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, ++ COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "clk_peri_src", 0, + RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, + RK2928_CLKGATE_CON(2), 2, GFLAGS), +- GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, ++ GATE(ACLK_PERI, "aclk_peri", "clk_peri_src", 0, + RK2928_CLKGATE_CON(2), 1, GFLAGS), + + GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, +@@ -316,7 +310,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { + GATE(SCLK_MIPI_24M, "clk_mipi_24m", "xin24m", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(2), 15, GFLAGS), + +- COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, ++ COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, + RK2928_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK2928_CLKGATE_CON(2), 11, GFLAGS), + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 193b0b3a77cda..f1589eb3b46af 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -855,47 +855,15 @@ static void qm_poll_req_cb(struct hisi_qp *qp) + qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, qp->qp_status.cq_head, 1); + } + +-static int qm_get_complete_eqe_num(struct hisi_qm_poll_data *poll_data) +-{ +- struct hisi_qm *qm = poll_data->qm; +- struct qm_eqe *eqe = qm->eqe + qm->status.eq_head; +- u16 eq_depth = qm->eq_depth; +- int eqe_num = 0; +- u16 cqn; +- +- while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) { +- cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK; +- poll_data->qp_finish_id[eqe_num] = cqn; +- eqe_num++; +- +- if (qm->status.eq_head == eq_depth - 1) { +- qm->status.eqc_phase = !qm->status.eqc_phase; +- eqe = qm->eqe; +- qm->status.eq_head = 0; +- } else { +- eqe++; +- qm->status.eq_head++; +- } +- +- if (eqe_num == (eq_depth >> 1) - 1) +- break; +- } +- +- qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); +- +- return eqe_num; +-} +- + static void qm_work_process(struct work_struct *work) + { + struct hisi_qm_poll_data *poll_data = + container_of(work, struct hisi_qm_poll_data, work); + struct hisi_qm *qm = poll_data->qm; ++ u16 eqe_num = poll_data->eqe_num; + struct hisi_qp *qp; +- int eqe_num, i; ++ int i; + +- /* Get qp id of completed tasks and re-enable the interrupt. */ +- eqe_num = qm_get_complete_eqe_num(poll_data); + for (i = eqe_num - 1; i >= 0; i--) { + qp = &qm->qp_array[poll_data->qp_finish_id[i]]; + if (unlikely(atomic_read(&qp->qp_status.flags) == QP_STOP)) +@@ -911,39 +879,55 @@ static void qm_work_process(struct work_struct *work) + } + } + +-static bool do_qm_eq_irq(struct hisi_qm *qm) ++static void qm_get_complete_eqe_num(struct hisi_qm *qm) + { + struct qm_eqe *eqe = qm->eqe + qm->status.eq_head; +- struct hisi_qm_poll_data *poll_data; +- u16 cqn; ++ struct hisi_qm_poll_data *poll_data = NULL; ++ u16 eq_depth = qm->eq_depth; ++ u16 cqn, eqe_num = 0; + +- if (!readl(qm->io_base + QM_VF_EQ_INT_SOURCE)) +- return false; ++ if (QM_EQE_PHASE(eqe) != qm->status.eqc_phase) { ++ atomic64_inc(&qm->debug.dfx.err_irq_cnt); ++ qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); ++ return; ++ } + +- if (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) { ++ cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK; ++ if (unlikely(cqn >= qm->qp_num)) ++ return; ++ poll_data = &qm->poll_data[cqn]; ++ ++ while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) { + cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK; +- poll_data = &qm->poll_data[cqn]; +- queue_work(qm->wq, &poll_data->work); ++ poll_data->qp_finish_id[eqe_num] = cqn; ++ eqe_num++; ++ ++ if (qm->status.eq_head == eq_depth - 1) { ++ qm->status.eqc_phase = !qm->status.eqc_phase; ++ eqe = qm->eqe; ++ qm->status.eq_head = 0; ++ } else { ++ eqe++; ++ qm->status.eq_head++; ++ } + +- return true; ++ if (eqe_num == (eq_depth >> 1) - 1) ++ break; + } + +- return false; ++ poll_data->eqe_num = eqe_num; ++ queue_work(qm->wq, &poll_data->work); ++ qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); + } + + static irqreturn_t qm_eq_irq(int irq, void *data) + { + struct hisi_qm *qm = data; +- bool ret; +- +- ret = do_qm_eq_irq(qm); +- if (ret) +- return IRQ_HANDLED; + +- atomic64_inc(&qm->debug.dfx.err_irq_cnt); +- qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); ++ /* Get qp id of completed tasks and re-enable the interrupt */ ++ qm_get_complete_eqe_num(qm); + +- return IRQ_NONE; ++ return IRQ_HANDLED; + } + + static irqreturn_t qm_mb_cmd_irq(int irq, void *data) +@@ -1025,6 +1009,8 @@ static irqreturn_t qm_aeq_thread(int irq, void *data) + u16 aeq_depth = qm->aeq_depth; + u32 type, qp_id; + ++ atomic64_inc(&qm->debug.dfx.aeq_irq_cnt); ++ + while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) { + type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT; + qp_id = le32_to_cpu(aeqe->dw0) & QM_AEQE_CQN_MASK; +@@ -1062,17 +1048,6 @@ static irqreturn_t qm_aeq_thread(int irq, void *data) + return IRQ_HANDLED; + } + +-static irqreturn_t qm_aeq_irq(int irq, void *data) +-{ +- struct hisi_qm *qm = data; +- +- atomic64_inc(&qm->debug.dfx.aeq_irq_cnt); +- if (!readl(qm->io_base + QM_VF_AEQ_INT_SOURCE)) +- return IRQ_NONE; +- +- return IRQ_WAKE_THREAD; +-} +- + static void qm_init_qp_status(struct hisi_qp *qp) + { + struct hisi_qp_status *qp_status = &qp->qp_status; +@@ -5012,8 +4987,8 @@ static int qm_register_aeq_irq(struct hisi_qm *qm) + return 0; + + irq_vector = val & QM_IRQ_VECTOR_MASK; +- ret = request_threaded_irq(pci_irq_vector(pdev, irq_vector), qm_aeq_irq, +- qm_aeq_thread, 0, qm->dev_name, qm); ++ ret = request_threaded_irq(pci_irq_vector(pdev, irq_vector), NULL, ++ qm_aeq_thread, IRQF_ONESHOT, qm->dev_name, qm); + if (ret) + dev_err(&pdev->dev, "failed to request eq irq, ret = %d", ret); + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c +index 04af32a2811c8..a39e70bd4b21b 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c +@@ -92,7 +92,8 @@ static void adf_device_reset_worker(struct work_struct *work) + if (adf_dev_restart(accel_dev)) { + /* The device hanged and we can't restart it so stop here */ + dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); +- kfree(reset_data); ++ if (reset_data->mode == ADF_DEV_RESET_ASYNC) ++ kfree(reset_data); + WARN(1, "QAT: device restart failed. Device is unusable\n"); + return; + } +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index 22829267ccd86..90664659d5fab 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -634,10 +634,11 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) + if (cxld->flags & CXL_DECODER_F_ENABLE) + return 0; + +- if (port->commit_end + 1 != id) { ++ if (cxl_num_decoders_committed(port) != id) { + dev_dbg(&port->dev, + "%s: out of order commit, expected decoder%d.%d\n", +- dev_name(&cxld->dev), port->id, port->commit_end + 1); ++ dev_name(&cxld->dev), port->id, ++ cxl_num_decoders_committed(port)); + return -EBUSY; + } + +@@ -847,7 +848,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, + cxld->target_type = CXL_DECODER_HOSTONLYMEM; + else + cxld->target_type = CXL_DECODER_DEVMEM; +- if (cxld->id != port->commit_end + 1) { ++ ++ guard(rwsem_write)(&cxl_region_rwsem); ++ if (cxld->id != cxl_num_decoders_committed(port)) { + dev_warn(&port->dev, + "decoder%d.%d: Committed out of order\n", + port->id, cxld->id); +diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c +index b91bb98869917..b12986b968da4 100644 +--- a/drivers/cxl/core/mbox.c ++++ b/drivers/cxl/core/mbox.c +@@ -1200,7 +1200,7 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd) + * Require an endpoint to be safe otherwise the driver can not + * be sure that the device is unmapped. + */ +- if (endpoint && endpoint->commit_end == -1) ++ if (endpoint && cxl_num_decoders_committed(endpoint) == 0) + rc = __cxl_mem_sanitize(mds, cmd); + else + rc = -EBUSY; +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index fed9573cf355e..2f43d368ba073 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -227,11 +227,17 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd) + if (!port || !is_cxl_endpoint(port)) + return -EINVAL; + +- rc = down_read_interruptible(&cxl_dpa_rwsem); ++ rc = down_read_interruptible(&cxl_region_rwsem); + if (rc) + return rc; + +- if (port->commit_end == -1) { ++ rc = down_read_interruptible(&cxl_dpa_rwsem); ++ if (rc) { ++ up_read(&cxl_region_rwsem); ++ return rc; ++ } ++ ++ if (cxl_num_decoders_committed(port) == 0) { + /* No regions mapped to this memdev */ + rc = cxl_get_poison_by_memdev(cxlmd); + } else { +@@ -239,6 +245,7 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd) + rc = cxl_get_poison_by_endpoint(port); + } + up_read(&cxl_dpa_rwsem); ++ up_read(&cxl_region_rwsem); + + return rc; + } +@@ -282,7 +289,7 @@ static struct cxl_region *cxl_dpa_to_region(struct cxl_memdev *cxlmd, u64 dpa) + .dpa = dpa, + }; + port = cxlmd->endpoint; +- if (port && is_cxl_endpoint(port) && port->commit_end != -1) ++ if (port && is_cxl_endpoint(port) && cxl_num_decoders_committed(port)) + device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region); + + return ctx.cxlr; +@@ -324,10 +331,16 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) + return 0; + +- rc = down_read_interruptible(&cxl_dpa_rwsem); ++ rc = down_read_interruptible(&cxl_region_rwsem); + if (rc) + return rc; + ++ rc = down_read_interruptible(&cxl_dpa_rwsem); ++ if (rc) { ++ up_read(&cxl_region_rwsem); ++ return rc; ++ } ++ + rc = cxl_validate_poison_dpa(cxlmd, dpa); + if (rc) + goto out; +@@ -355,6 +368,7 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa) + trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT); + out: + up_read(&cxl_dpa_rwsem); ++ up_read(&cxl_region_rwsem); + + return rc; + } +@@ -372,10 +386,16 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) + return 0; + +- rc = down_read_interruptible(&cxl_dpa_rwsem); ++ rc = down_read_interruptible(&cxl_region_rwsem); + if (rc) + return rc; + ++ rc = down_read_interruptible(&cxl_dpa_rwsem); ++ if (rc) { ++ up_read(&cxl_region_rwsem); ++ return rc; ++ } ++ + rc = cxl_validate_poison_dpa(cxlmd, dpa); + if (rc) + goto out; +@@ -412,6 +432,7 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa) + trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR); + out: + up_read(&cxl_dpa_rwsem); ++ up_read(&cxl_region_rwsem); + + return rc; + } +diff --git a/drivers/cxl/core/pmu.c b/drivers/cxl/core/pmu.c +index 7684c843e5a59..5d8e06b0ba6e8 100644 +--- a/drivers/cxl/core/pmu.c ++++ b/drivers/cxl/core/pmu.c +@@ -23,7 +23,7 @@ const struct device_type cxl_pmu_type = { + + static void remove_dev(void *dev) + { +- device_del(dev); ++ device_unregister(dev); + } + + int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs, +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 1e0558d18b965..f430280fa6bd0 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -37,6 +37,13 @@ DECLARE_RWSEM(cxl_region_rwsem); + static DEFINE_IDA(cxl_port_ida); + static DEFINE_XARRAY(cxl_root_buses); + ++int cxl_num_decoders_committed(struct cxl_port *port) ++{ ++ lockdep_assert_held(&cxl_region_rwsem); ++ ++ return port->commit_end + 1; ++} ++ + static ssize_t devtype_show(struct device *dev, struct device_attribute *attr, + char *buf) + { +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 9d60020c5cb3b..e7206367ec669 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -2467,10 +2467,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port) + struct cxl_poison_context ctx; + int rc = 0; + +- rc = down_read_interruptible(&cxl_region_rwsem); +- if (rc) +- return rc; +- + ctx = (struct cxl_poison_context) { + .port = port + }; +@@ -2480,7 +2476,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port) + rc = cxl_get_poison_unmapped(to_cxl_memdev(port->uport_dev), + &ctx); + +- up_read(&cxl_region_rwsem); + return rc; + } + +diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h +index b5b015b661eae..6c6afda0e4c61 100644 +--- a/drivers/cxl/cxl.h ++++ b/drivers/cxl/cxl.h +@@ -679,6 +679,7 @@ static inline bool is_cxl_root(struct cxl_port *port) + return port->uport_dev == port->dev.parent; + } + ++int cxl_num_decoders_committed(struct cxl_port *port); + bool is_cxl_port(const struct device *dev); + struct cxl_port *to_cxl_port(const struct device *dev); + struct pci_bus; +diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c +index 8c4ed7012e232..00cb70aca34a3 100644 +--- a/drivers/dma/fsl-edma-main.c ++++ b/drivers/dma/fsl-edma-main.c +@@ -400,9 +400,8 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng + link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); +- if (IS_ERR(link)) { +- dev_err(dev, "Failed to add device_link to %d: %ld\n", i, +- PTR_ERR(link)); ++ if (!link) { ++ dev_err(dev, "Failed to add device_link to %d\n", i); + return -EINVAL; + } + +@@ -640,6 +639,8 @@ static int fsl_edma_suspend_late(struct device *dev) + + for (i = 0; i < fsl_edma->n_chans; i++) { + fsl_chan = &fsl_edma->chans[i]; ++ if (fsl_edma->chan_masked & BIT(i)) ++ continue; + spin_lock_irqsave(&fsl_chan->vchan.lock, flags); + /* Make sure chan is idle or will force disable. */ + if (unlikely(!fsl_chan->idle)) { +@@ -664,13 +665,16 @@ static int fsl_edma_resume_early(struct device *dev) + + for (i = 0; i < fsl_edma->n_chans; i++) { + fsl_chan = &fsl_edma->chans[i]; ++ if (fsl_edma->chan_masked & BIT(i)) ++ continue; + fsl_chan->pm_state = RUNNING; + edma_write_tcdreg(fsl_chan, 0, csr); + if (fsl_chan->slave_id != 0) + fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true); + } + +- edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr); ++ if (!(fsl_edma->drvdata->flags & FSL_EDMA_DRV_SPLIT_REG)) ++ edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr); + + return 0; + } +diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c +index c01db23e3333f..3f922518e3a52 100644 +--- a/drivers/dma/idxd/submit.c ++++ b/drivers/dma/idxd/submit.c +@@ -182,13 +182,6 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) + + portal = idxd_wq_portal_addr(wq); + +- /* +- * The wmb() flushes writes to coherent DMA data before +- * possibly triggering a DMA read. The wmb() is necessary +- * even on UP because the recipient is a device. +- */ +- wmb(); +- + /* + * Pending the descriptor to the lockless list for the irq_entry + * that we designated the descriptor to. +@@ -199,6 +192,13 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) + llist_add(&desc->llnode, &ie->pending_llist); + } + ++ /* ++ * The wmb() flushes writes to coherent DMA data before ++ * possibly triggering a DMA read. The wmb() is necessary ++ * even on UP because the recipient is a device. ++ */ ++ wmb(); ++ + if (wq_dedicated(wq)) { + iosubmit_cmds512(portal, desc->hw, 1); + } else { +diff --git a/drivers/dma/ti/k3-psil-am62.c b/drivers/dma/ti/k3-psil-am62.c +index 2b6fd6e37c610..1272b1541f61e 100644 +--- a/drivers/dma/ti/k3-psil-am62.c ++++ b/drivers/dma/ti/k3-psil-am62.c +@@ -74,7 +74,9 @@ static struct psil_ep am62_src_ep_map[] = { + PSIL_SAUL(0x7505, 21, 35, 8, 36, 0), + PSIL_SAUL(0x7506, 22, 43, 8, 43, 0), + PSIL_SAUL(0x7507, 23, 43, 8, 44, 0), +- /* PDMA_MAIN0 - SPI0-3 */ ++ /* PDMA_MAIN0 - SPI0-2 */ ++ PSIL_PDMA_XY_PKT(0x4300), ++ PSIL_PDMA_XY_PKT(0x4301), + PSIL_PDMA_XY_PKT(0x4302), + PSIL_PDMA_XY_PKT(0x4303), + PSIL_PDMA_XY_PKT(0x4304), +@@ -85,8 +87,6 @@ static struct psil_ep am62_src_ep_map[] = { + PSIL_PDMA_XY_PKT(0x4309), + PSIL_PDMA_XY_PKT(0x430a), + PSIL_PDMA_XY_PKT(0x430b), +- PSIL_PDMA_XY_PKT(0x430c), +- PSIL_PDMA_XY_PKT(0x430d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0x4400), + PSIL_PDMA_XY_PKT(0x4401), +@@ -141,7 +141,9 @@ static struct psil_ep am62_dst_ep_map[] = { + /* SAUL */ + PSIL_SAUL(0xf500, 27, 83, 8, 83, 1), + PSIL_SAUL(0xf501, 28, 91, 8, 91, 1), +- /* PDMA_MAIN0 - SPI0-3 */ ++ /* PDMA_MAIN0 - SPI0-2 */ ++ PSIL_PDMA_XY_PKT(0xc300), ++ PSIL_PDMA_XY_PKT(0xc301), + PSIL_PDMA_XY_PKT(0xc302), + PSIL_PDMA_XY_PKT(0xc303), + PSIL_PDMA_XY_PKT(0xc304), +@@ -152,8 +154,6 @@ static struct psil_ep am62_dst_ep_map[] = { + PSIL_PDMA_XY_PKT(0xc309), + PSIL_PDMA_XY_PKT(0xc30a), + PSIL_PDMA_XY_PKT(0xc30b), +- PSIL_PDMA_XY_PKT(0xc30c), +- PSIL_PDMA_XY_PKT(0xc30d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0xc400), + PSIL_PDMA_XY_PKT(0xc401), +diff --git a/drivers/dma/ti/k3-psil-am62a.c b/drivers/dma/ti/k3-psil-am62a.c +index ca9d71f914220..4cf9123b0e932 100644 +--- a/drivers/dma/ti/k3-psil-am62a.c ++++ b/drivers/dma/ti/k3-psil-am62a.c +@@ -84,7 +84,9 @@ static struct psil_ep am62a_src_ep_map[] = { + PSIL_SAUL(0x7505, 21, 35, 8, 36, 0), + PSIL_SAUL(0x7506, 22, 43, 8, 43, 0), + PSIL_SAUL(0x7507, 23, 43, 8, 44, 0), +- /* PDMA_MAIN0 - SPI0-3 */ ++ /* PDMA_MAIN0 - SPI0-2 */ ++ PSIL_PDMA_XY_PKT(0x4300), ++ PSIL_PDMA_XY_PKT(0x4301), + PSIL_PDMA_XY_PKT(0x4302), + PSIL_PDMA_XY_PKT(0x4303), + PSIL_PDMA_XY_PKT(0x4304), +@@ -95,8 +97,6 @@ static struct psil_ep am62a_src_ep_map[] = { + PSIL_PDMA_XY_PKT(0x4309), + PSIL_PDMA_XY_PKT(0x430a), + PSIL_PDMA_XY_PKT(0x430b), +- PSIL_PDMA_XY_PKT(0x430c), +- PSIL_PDMA_XY_PKT(0x430d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0x4400), + PSIL_PDMA_XY_PKT(0x4401), +@@ -151,7 +151,9 @@ static struct psil_ep am62a_dst_ep_map[] = { + /* SAUL */ + PSIL_SAUL(0xf500, 27, 83, 8, 83, 1), + PSIL_SAUL(0xf501, 28, 91, 8, 91, 1), +- /* PDMA_MAIN0 - SPI0-3 */ ++ /* PDMA_MAIN0 - SPI0-2 */ ++ PSIL_PDMA_XY_PKT(0xc300), ++ PSIL_PDMA_XY_PKT(0xc301), + PSIL_PDMA_XY_PKT(0xc302), + PSIL_PDMA_XY_PKT(0xc303), + PSIL_PDMA_XY_PKT(0xc304), +@@ -162,8 +164,6 @@ static struct psil_ep am62a_dst_ep_map[] = { + PSIL_PDMA_XY_PKT(0xc309), + PSIL_PDMA_XY_PKT(0xc30a), + PSIL_PDMA_XY_PKT(0xc30b), +- PSIL_PDMA_XY_PKT(0xc30c), +- PSIL_PDMA_XY_PKT(0xc30d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0xc400), + PSIL_PDMA_XY_PKT(0xc401), +diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c +index 7e88fd4897414..9db9290c32693 100644 +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -279,6 +279,51 @@ static char ohci_driver_name[] = KBUILD_MODNAME; + #define QUIRK_TI_SLLZ059 0x20 + #define QUIRK_IR_WAKE 0x40 + ++// On PCI Express Root Complex in any type of AMD Ryzen machine, VIA VT6306/6307/6308 with Asmedia ++// ASM1083/1085 brings an inconvenience that the read accesses to 'Isochronous Cycle Timer' register ++// (at offset 0xf0 in PCI I/O space) often causes unexpected system reboot. The mechanism is not ++// clear, since the read access to the other registers is enough safe; e.g. 'Node ID' register, ++// while it is probable due to detection of any type of PCIe error. ++#define QUIRK_REBOOT_BY_CYCLE_TIMER_READ 0x80000000 ++ ++#if IS_ENABLED(CONFIG_X86) ++ ++static bool has_reboot_by_cycle_timer_read_quirk(const struct fw_ohci *ohci) ++{ ++ return !!(ohci->quirks & QUIRK_REBOOT_BY_CYCLE_TIMER_READ); ++} ++ ++#define PCI_DEVICE_ID_ASMEDIA_ASM108X 0x1080 ++ ++static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev *pdev) ++{ ++ const struct pci_dev *pcie_to_pci_bridge; ++ ++ // Detect any type of AMD Ryzen machine. ++ if (!static_cpu_has(X86_FEATURE_ZEN)) ++ return false; ++ ++ // Detect VIA VT6306/6307/6308. ++ if (pdev->vendor != PCI_VENDOR_ID_VIA) ++ return false; ++ if (pdev->device != PCI_DEVICE_ID_VIA_VT630X) ++ return false; ++ ++ // Detect Asmedia ASM1083/1085. ++ pcie_to_pci_bridge = pdev->bus->self; ++ if (pcie_to_pci_bridge->vendor != PCI_VENDOR_ID_ASMEDIA) ++ return false; ++ if (pcie_to_pci_bridge->device != PCI_DEVICE_ID_ASMEDIA_ASM108X) ++ return false; ++ ++ return true; ++} ++ ++#else ++#define has_reboot_by_cycle_timer_read_quirk(ohci) false ++#define detect_vt630x_with_asm1083_on_amd_ryzen_machine(pdev) false ++#endif ++ + /* In case of multiple matches in ohci_quirks[], only the first one is used. */ + static const struct { + unsigned short vendor, device, revision, flags; +@@ -1724,6 +1769,9 @@ static u32 get_cycle_time(struct fw_ohci *ohci) + s32 diff01, diff12; + int i; + ++ if (has_reboot_by_cycle_timer_read_quirk(ohci)) ++ return 0; ++ + c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); + + if (ohci->quirks & QUIRK_CYCLE_TIMER) { +@@ -3630,6 +3678,9 @@ static int pci_probe(struct pci_dev *dev, + if (param_quirks) + ohci->quirks = param_quirks; + ++ if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev)) ++ ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ; ++ + /* + * Because dma_alloc_coherent() allocates at least one page, + * we save space by using a common buffer for the AR request/ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 94e91516952c4..56d99ffbba2ee 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -1896,15 +1896,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) + + adev->firmware.gpu_info_fw = NULL; + +- if (adev->mman.discovery_bin) { +- /* +- * FIXME: The bounding box is still needed by Navi12, so +- * temporarily read it from gpu_info firmware. Should be dropped +- * when DAL no longer needs it. +- */ +- if (adev->asic_type != CHIP_NAVI12) +- return 0; +- } ++ if (adev->mman.discovery_bin) ++ return 0; + + switch (adev->asic_type) { + default: +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index d63360127834b..5084833e3608f 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -6139,8 +6139,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, + + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket); +- +- if (stream->link->psr_settings.psr_feature_enabled || stream->link->replay_settings.replay_feature_enabled) { ++ else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || ++ stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || ++ stream->signal == SIGNAL_TYPE_EDP) { + // + // should decide stream support vsc sdp colorimetry capability + // before building vsc info packet +@@ -6156,8 +6157,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, + if (stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) + tf = TRANSFER_FUNC_GAMMA_22; + mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf); +- aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY; + ++ if (stream->link->psr_settings.psr_feature_enabled) ++ aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY; + } + finish: + dc_sink_release(sink); +@@ -6868,8 +6870,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, + if (IS_ERR(mst_state)) + return PTR_ERR(mst_state); + +- if (!mst_state->pbn_div) +- mst_state->pbn_div = dm_mst_get_pbn_divider(aconnector->mst_root->dc_link); ++ mst_state->pbn_div = dm_mst_get_pbn_divider(aconnector->mst_root->dc_link); + + if (!state->duplicated) { + int max_bpc = conn_state->max_requested_bpc; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile +index 77cf5545c94cc..c206812dc6897 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile +@@ -61,8 +61,12 @@ endif + endif + + ifneq ($(CONFIG_FRAME_WARN),0) ++ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y) ++frame_warn_flag := -Wframe-larger-than=3072 ++else + frame_warn_flag := -Wframe-larger-than=2048 + endif ++endif + + CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) + CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h +index 2cbdd75429ffd..6e669a2c5b2d4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h +@@ -36,7 +36,7 @@ + * Define the maximum amount of states supported by the ASIC. Every ASIC has a + * specific number of states; this macro defines the maximum number of states. + */ +-#define DC__VOLTAGE_STATES 20 ++#define DC__VOLTAGE_STATES 40 + #define DC__NUM_DPP__4 1 + #define DC__NUM_DPP__0_PRESENT 1 + #define DC__NUM_DPP__1_PRESENT 1 +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +index f2de0c7584947..8a5a038fd8557 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +@@ -438,7 +438,115 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = { + .use_urgent_burst_bw = 0 + }; + +-struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 }; ++struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { ++ .clock_limits = { ++ { ++ .state = 0, ++ .dcfclk_mhz = 560.0, ++ .fabricclk_mhz = 560.0, ++ .dispclk_mhz = 513.0, ++ .dppclk_mhz = 513.0, ++ .phyclk_mhz = 540.0, ++ .socclk_mhz = 560.0, ++ .dscclk_mhz = 171.0, ++ .dram_speed_mts = 1069.0, ++ }, ++ { ++ .state = 1, ++ .dcfclk_mhz = 694.0, ++ .fabricclk_mhz = 694.0, ++ .dispclk_mhz = 642.0, ++ .dppclk_mhz = 642.0, ++ .phyclk_mhz = 600.0, ++ .socclk_mhz = 694.0, ++ .dscclk_mhz = 214.0, ++ .dram_speed_mts = 1324.0, ++ }, ++ { ++ .state = 2, ++ .dcfclk_mhz = 875.0, ++ .fabricclk_mhz = 875.0, ++ .dispclk_mhz = 734.0, ++ .dppclk_mhz = 734.0, ++ .phyclk_mhz = 810.0, ++ .socclk_mhz = 875.0, ++ .dscclk_mhz = 245.0, ++ .dram_speed_mts = 1670.0, ++ }, ++ { ++ .state = 3, ++ .dcfclk_mhz = 1000.0, ++ .fabricclk_mhz = 1000.0, ++ .dispclk_mhz = 1100.0, ++ .dppclk_mhz = 1100.0, ++ .phyclk_mhz = 810.0, ++ .socclk_mhz = 1000.0, ++ .dscclk_mhz = 367.0, ++ .dram_speed_mts = 2000.0, ++ }, ++ { ++ .state = 4, ++ .dcfclk_mhz = 1200.0, ++ .fabricclk_mhz = 1200.0, ++ .dispclk_mhz = 1284.0, ++ .dppclk_mhz = 1284.0, ++ .phyclk_mhz = 810.0, ++ .socclk_mhz = 1200.0, ++ .dscclk_mhz = 428.0, ++ .dram_speed_mts = 2000.0, ++ }, ++ { ++ .state = 5, ++ .dcfclk_mhz = 1200.0, ++ .fabricclk_mhz = 1200.0, ++ .dispclk_mhz = 1284.0, ++ .dppclk_mhz = 1284.0, ++ .phyclk_mhz = 810.0, ++ .socclk_mhz = 1200.0, ++ .dscclk_mhz = 428.0, ++ .dram_speed_mts = 2000.0, ++ }, ++ }, ++ ++ .num_states = 5, ++ .sr_exit_time_us = 1.9, ++ .sr_enter_plus_exit_time_us = 4.4, ++ .urgent_latency_us = 3.0, ++ .urgent_latency_pixel_data_only_us = 4.0, ++ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, ++ .urgent_latency_vm_data_only_us = 4.0, ++ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, ++ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, ++ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, ++ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0, ++ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0, ++ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, ++ .max_avg_sdp_bw_use_normal_percent = 40.0, ++ .max_avg_dram_bw_use_normal_percent = 40.0, ++ .writeback_latency_us = 12.0, ++ .ideal_dram_bw_after_urgent_percent = 40.0, ++ .max_request_size_bytes = 256, ++ .dram_channel_width_bytes = 16, ++ .fabric_datapath_to_dcn_data_return_bytes = 64, ++ .dcn_downspread_percent = 0.5, ++ .downspread_percent = 0.5, ++ .dram_page_open_time_ns = 50.0, ++ .dram_rw_turnaround_time_ns = 17.5, ++ .dram_return_buffer_per_channel_bytes = 8192, ++ .round_trip_ping_latency_dcfclk_cycles = 131, ++ .urgent_out_of_order_return_per_channel_bytes = 4096, ++ .channel_interleave_bytes = 256, ++ .num_banks = 8, ++ .num_chans = 16, ++ .vmm_page_size_bytes = 4096, ++ .dram_clock_change_latency_us = 45.0, ++ .writeback_dram_clock_change_latency_us = 23.0, ++ .return_bus_width_bytes = 64, ++ .dispclk_dppclk_vco_speed_mhz = 3850, ++ .xfc_bus_transport_time_us = 20, ++ .xfc_xbuf_latency_tolerance_us = 50, ++ .use_urgent_burst_bw = 0, ++}; + + struct _vcs_dpi_ip_params_st dcn2_1_ip = { + .odm_capable = 1, +diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +index 84f9b412a4f11..738ee763f24a5 100644 +--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c ++++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +@@ -147,12 +147,15 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, + } + + /* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */ +- if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) +- vsc_packet_revision = vsc_packet_rev4; +- else if (stream->link->replay_settings.config.replay_supported) ++ if (stream->link->psr_settings.psr_feature_enabled) { ++ if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) ++ vsc_packet_revision = vsc_packet_rev4; ++ else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) ++ vsc_packet_revision = vsc_packet_rev2; ++ } ++ ++ if (stream->link->replay_settings.config.replay_supported) + vsc_packet_revision = vsc_packet_rev4; +- else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) +- vsc_packet_revision = vsc_packet_rev2; + + /* Update to revision 5 for extended colorimetry support */ + if (stream->use_vsc_sdp_for_colorimetry) +diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c +index 8161b1a1a4b12..541e4f5afc4c8 100644 +--- a/drivers/gpu/drm/bridge/parade-ps8640.c ++++ b/drivers/gpu/drm/bridge/parade-ps8640.c +@@ -210,7 +210,7 @@ static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux, + struct ps8640 *ps_bridge = aux_to_ps8640(aux); + struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL]; + struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; +- unsigned int len = msg->size; ++ size_t len = msg->size; + unsigned int data; + unsigned int base; + int ret; +@@ -330,11 +330,12 @@ static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux, + return ret; + } + +- buf[i] = data; ++ if (i < msg->size) ++ buf[i] = data; + } + } + +- return len; ++ return min(len, msg->size); + } + + static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux, +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index 84148a79414b7..3309c01fa7153 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -527,6 +527,7 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux, + u32 request_val = AUX_CMD_REQ(msg->request); + u8 *buf = msg->buffer; + unsigned int len = msg->size; ++ unsigned int short_len; + unsigned int val; + int ret; + u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG]; +@@ -600,7 +601,8 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux, + } + + if (val & AUX_IRQ_STATUS_AUX_SHORT) { +- ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len); ++ ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &short_len); ++ len = min(len, short_len); + if (ret) + goto exit; + } else if (val & AUX_IRQ_STATUS_NAT_I2C_FAIL) { +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index 2e0daad23aa61..a072fbb9872aa 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -6670,10 +6670,11 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) + if (!intel_crtc_needs_modeset(new_crtc_state)) + continue; + ++ intel_pre_plane_update(state, crtc); ++ + if (!old_crtc_state->hw.active) + continue; + +- intel_pre_plane_update(state, crtc); + intel_crtc_disable_planes(state, crtc); + } + +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index b4fb7ce39d06f..18ee4f2a87f9e 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -3987,7 +3987,7 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, + intel_dp->train_set, crtc_state->lane_count); + + drm_dp_set_phy_test_pattern(&intel_dp->aux, data, +- link_status[DP_DPCD_REV]); ++ intel_dp->dpcd[DP_DPCD_REV]); + } + + static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) +diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c +index 109135fcfca28..8f4a25d2cfc24 100644 +--- a/drivers/gpu/drm/i915/i915_perf.c ++++ b/drivers/gpu/drm/i915/i915_perf.c +@@ -785,10 +785,6 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream, + * The reason field includes flags identifying what + * triggered this specific report (mostly timer + * triggered or e.g. due to a context switch). +- * +- * In MMIO triggered reports, some platforms do not set the +- * reason bit in this field and it is valid to have a reason +- * field of zero. + */ + reason = oa_report_reason(stream, report); + ctx_id = oa_context_id(stream, report32); +@@ -800,8 +796,41 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream, + * + * Note: that we don't clear the valid_ctx_bit so userspace can + * understand that the ID has been squashed by the kernel. ++ * ++ * Update: ++ * ++ * On XEHP platforms the behavior of context id valid bit has ++ * changed compared to prior platforms. To describe this, we ++ * define a few terms: ++ * ++ * context-switch-report: This is a report with the reason type ++ * being context-switch. It is generated when a context switches ++ * out. ++ * ++ * context-valid-bit: A bit that is set in the report ID field ++ * to indicate that a valid context has been loaded. ++ * ++ * gpu-idle: A condition characterized by a ++ * context-switch-report with context-valid-bit set to 0. ++ * ++ * On prior platforms, context-id-valid bit is set to 0 only ++ * when GPU goes idle. In all other reports, it is set to 1. ++ * ++ * On XEHP platforms, context-valid-bit is set to 1 in a context ++ * switch report if a new context switched in. For all other ++ * reports it is set to 0. ++ * ++ * This change in behavior causes an issue with MMIO triggered ++ * reports. MMIO triggered reports have the markers in the ++ * context ID field and the context-valid-bit is 0. The logic ++ * below to squash the context ID would render the report ++ * useless since the user will not be able to find it in the OA ++ * buffer. Since MMIO triggered reports exist only on XEHP, ++ * we should avoid squashing these for XEHP platforms. + */ +- if (oa_report_ctx_invalid(stream, report)) { ++ ++ if (oa_report_ctx_invalid(stream, report) && ++ GRAPHICS_VER_FULL(stream->engine->i915) < IP_VER(12, 50)) { + ctx_id = INVALID_CTX_ID; + oa_context_id_squash(stream, report32); + } +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h +index 57c7edcab6029..765e49fd89111 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.h ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.h +@@ -392,6 +392,11 @@ void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane, + .destroy = drm_plane_cleanup, \ + DRM_GEM_SHADOW_PLANE_FUNCS + ++void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, const struct drm_format_info *format); ++void mgag200_crtc_set_gamma(struct mga_device *mdev, ++ const struct drm_format_info *format, ++ struct drm_color_lut *lut); ++ + enum drm_mode_status mgag200_crtc_helper_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode); + int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state); +diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c +index bce267e0f7de3..8d4538b710477 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c ++++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c +@@ -202,6 +202,11 @@ static void mgag200_g200er_crtc_helper_atomic_enable(struct drm_crtc *crtc, + + mgag200_g200er_reset_tagfifo(mdev); + ++ if (crtc_state->gamma_lut) ++ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); ++ else ++ mgag200_crtc_set_gamma_linear(mdev, format); ++ + mgag200_enable_display(mdev); + + if (funcs->enable_vidrst) +diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c +index ac957f42abe18..56e6f986bff31 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c ++++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c +@@ -203,6 +203,11 @@ static void mgag200_g200ev_crtc_helper_atomic_enable(struct drm_crtc *crtc, + + mgag200_g200ev_set_hiprilvl(mdev); + ++ if (crtc_state->gamma_lut) ++ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); ++ else ++ mgag200_crtc_set_gamma_linear(mdev, format); ++ + mgag200_enable_display(mdev); + + if (funcs->enable_vidrst) +diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c +index bd6e573c9a1a3..ff2b3c6622e7a 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c ++++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c +@@ -334,6 +334,11 @@ static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc, + + mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, format); + ++ if (crtc_state->gamma_lut) ++ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); ++ else ++ mgag200_crtc_set_gamma_linear(mdev, format); ++ + mgag200_enable_display(mdev); + + if (funcs->enable_vidrst) +diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c +index af3ce5a6a636a..0f0d59938c3a0 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_mode.c ++++ b/drivers/gpu/drm/mgag200/mgag200_mode.c +@@ -28,8 +28,8 @@ + * This file contains setup code for the CRTC. + */ + +-static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, +- const struct drm_format_info *format) ++void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, ++ const struct drm_format_info *format) + { + int i; + +@@ -65,9 +65,9 @@ static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, + } + } + +-static void mgag200_crtc_set_gamma(struct mga_device *mdev, +- const struct drm_format_info *format, +- struct drm_color_lut *lut) ++void mgag200_crtc_set_gamma(struct mga_device *mdev, ++ const struct drm_format_info *format, ++ struct drm_color_lut *lut) + { + int i; + +diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h +index 05b8b8dfa9bdd..36587f38dff3d 100644 +--- a/drivers/i2c/i2c-core.h ++++ b/drivers/i2c/i2c-core.h +@@ -3,6 +3,7 @@ + * i2c-core.h - interfaces internal to the I2C framework + */ + ++#include <linux/kconfig.h> + #include <linux/rwsem.h> + + struct i2c_devinfo { +@@ -29,7 +30,8 @@ int i2c_dev_irq_from_resources(const struct resource *resources, + */ + static inline bool i2c_in_atomic_xfer_mode(void) + { +- return system_state > SYSTEM_RUNNING && !preemptible(); ++ return system_state > SYSTEM_RUNNING && ++ (IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled()); + } + + static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) +diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c +index 0a9951a502101..6c81dc5bf2c7a 100644 +--- a/drivers/iio/imu/adis16475.c ++++ b/drivers/iio/imu/adis16475.c +@@ -63,8 +63,8 @@ + #define ADIS16475_MAX_SCAN_DATA 20 + /* spi max speed in brust mode */ + #define ADIS16475_BURST_MAX_SPEED 1000000 +-#define ADIS16475_LSB_DEC_MASK BIT(0) +-#define ADIS16475_LSB_FIR_MASK BIT(1) ++#define ADIS16475_LSB_DEC_MASK 0 ++#define ADIS16475_LSB_FIR_MASK 1 + + enum { + ADIS16475_SYNC_DIRECT = 1, +diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c +index 8a3762d9ff58c..e0629898c3c06 100644 +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -1026,11 +1026,13 @@ void mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev) + return; + + mutex_lock(&dev->cache.rb_lock); ++ cancel_delayed_work(&dev->cache.remove_ent_dwork); + for (node = rb_first(root); node; node = rb_next(node)) { + ent = rb_entry(node, struct mlx5_cache_ent, node); + xa_lock_irq(&ent->mkeys); + ent->disabled = true; + xa_unlock_irq(&ent->mkeys); ++ cancel_delayed_work(&ent->dwork); + } + mutex_unlock(&dev->cache.rb_lock); + +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index 4c3707384bd92..744e4e6b8d72d 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -2204,6 +2204,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, + attr |= DMA_FL_PTE_DIRTY; + } + ++ domain->has_mappings = true; ++ + pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr; + + while (nr_pages > 0) { +@@ -4309,7 +4311,8 @@ static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain) + return true; + + spin_lock_irqsave(&dmar_domain->lock, flags); +- if (!domain_support_force_snooping(dmar_domain)) { ++ if (!domain_support_force_snooping(dmar_domain) || ++ (!dmar_domain->use_first_level && dmar_domain->has_mappings)) { + spin_unlock_irqrestore(&dmar_domain->lock, flags); + return false; + } +diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h +index 7dac94f62b4ec..e6a3e70656166 100644 +--- a/drivers/iommu/intel/iommu.h ++++ b/drivers/iommu/intel/iommu.h +@@ -592,6 +592,9 @@ struct dmar_domain { + * otherwise, goes through the second + * level. + */ ++ u8 has_mappings:1; /* Has mappings configured through ++ * iommu_map() interface. ++ */ + + spinlock_t lock; /* Protect device tracking lists */ + struct list_head devices; /* all devices' list */ +diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c +index 23acc387be5f0..0147cc062e1ae 100644 +--- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c ++++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c +@@ -352,7 +352,19 @@ static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc) + phy_sel = csid->phy.csiphy_id; + + if (enable) { +- u8 dt_id = vc; ++ /* ++ * DT_ID is a two bit bitfield that is concatenated with ++ * the four least significant bits of the five bit VC ++ * bitfield to generate an internal CID value. ++ * ++ * CSID_RDI_CFG0(vc) ++ * DT_ID : 28:27 ++ * VC : 26:22 ++ * DT : 21:16 ++ * ++ * CID : VC 3:0 << 2 | DT_ID 1:0 ++ */ ++ u8 dt_id = vc & 0x03; + + if (tg->enabled) { + /* configure one DT, infinite frames */ +diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c +index 75991d849b571..c6df862c79e39 100644 +--- a/drivers/media/platform/qcom/camss/camss.c ++++ b/drivers/media/platform/qcom/camss/camss.c +@@ -1538,6 +1538,20 @@ static int camss_icc_get(struct camss *camss) + return 0; + } + ++static void camss_genpd_cleanup(struct camss *camss) ++{ ++ int i; ++ ++ if (camss->genpd_num == 1) ++ return; ++ ++ if (camss->genpd_num > camss->vfe_num) ++ device_link_del(camss->genpd_link[camss->genpd_num - 1]); ++ ++ for (i = 0; i < camss->genpd_num; i++) ++ dev_pm_domain_detach(camss->genpd[i], true); ++} ++ + /* + * camss_probe - Probe CAMSS platform device + * @pdev: Pointer to CAMSS platform device +@@ -1617,21 +1631,21 @@ static int camss_probe(struct platform_device *pdev) + + ret = camss_icc_get(camss); + if (ret < 0) +- goto err_cleanup; ++ return ret; + + ret = camss_configure_pd(camss); + if (ret < 0) { + dev_err(dev, "Failed to configure power domains: %d\n", ret); +- goto err_cleanup; ++ return ret; + } + + ret = camss_init_subdevices(camss); + if (ret < 0) +- goto err_cleanup; ++ goto err_genpd_cleanup; + + ret = dma_set_mask_and_coherent(dev, 0xffffffff); + if (ret) +- goto err_cleanup; ++ goto err_genpd_cleanup; + + camss->media_dev.dev = camss->dev; + strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", +@@ -1643,7 +1657,7 @@ static int camss_probe(struct platform_device *pdev) + ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); + if (ret < 0) { + dev_err(dev, "Failed to register V4L2 device: %d\n", ret); +- goto err_cleanup; ++ goto err_genpd_cleanup; + } + + v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); +@@ -1651,12 +1665,12 @@ static int camss_probe(struct platform_device *pdev) + num_subdevs = camss_of_parse_ports(camss); + if (num_subdevs < 0) { + ret = num_subdevs; +- goto err_cleanup; ++ goto err_v4l2_device_unregister; + } + + ret = camss_register_entities(camss); + if (ret < 0) +- goto err_cleanup; ++ goto err_v4l2_device_unregister; + + if (num_subdevs) { + camss->notifier.ops = &camss_subdev_notifier_ops; +@@ -1690,31 +1704,22 @@ static int camss_probe(struct platform_device *pdev) + + err_register_subdevs: + camss_unregister_entities(camss); +-err_cleanup: ++err_v4l2_device_unregister: + v4l2_device_unregister(&camss->v4l2_dev); + v4l2_async_nf_cleanup(&camss->notifier); ++err_genpd_cleanup: ++ camss_genpd_cleanup(camss); + + return ret; + } + + void camss_delete(struct camss *camss) + { +- int i; +- + v4l2_device_unregister(&camss->v4l2_dev); + media_device_unregister(&camss->media_dev); + media_device_cleanup(&camss->media_dev); + + pm_runtime_disable(camss->dev); +- +- if (camss->genpd_num == 1) +- return; +- +- if (camss->genpd_num > camss->vfe_num) +- device_link_del(camss->genpd_link[camss->genpd_num - 1]); +- +- for (i = 0; i < camss->genpd_num; i++) +- dev_pm_domain_detach(camss->genpd[i], true); + } + + /* +@@ -1733,6 +1738,8 @@ static void camss_remove(struct platform_device *pdev) + + if (atomic_read(&camss->ref_count) == 0) + camss_delete(camss); ++ ++ camss_genpd_cleanup(camss); + } + + static const struct of_device_id camss_dt_match[] = { +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index f9a5cffa64b1f..134c36edb6cf7 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -851,9 +851,10 @@ static const struct block_device_operations mmc_bdops = { + static int mmc_blk_part_switch_pre(struct mmc_card *card, + unsigned int part_type) + { ++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; + int ret = 0; + +- if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { ++ if ((part_type & mask) == mask) { + if (card->ext_csd.cmdq_en) { + ret = mmc_cmdq_disable(card); + if (ret) +@@ -868,9 +869,10 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card, + static int mmc_blk_part_switch_post(struct mmc_card *card, + unsigned int part_type) + { ++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; + int ret = 0; + +- if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { ++ if ((part_type & mask) == mask) { + mmc_retune_unpause(card->host); + if (card->reenable_cmdq && !card->ext_csd.cmdq_en) + ret = mmc_cmdq_enable(card); +@@ -3145,4 +3147,3 @@ module_exit(mmc_blk_exit); + + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); +- +diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c +index 096093f7be006..2f51db4df1a85 100644 +--- a/drivers/mmc/core/host.c ++++ b/drivers/mmc/core/host.c +@@ -692,6 +692,7 @@ EXPORT_SYMBOL(mmc_remove_host); + */ + void mmc_free_host(struct mmc_host *host) + { ++ cancel_delayed_work_sync(&host->detect); + mmc_pwrseq_free(host); + put_device(&host->class_dev); + } +diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c +index 528ec8166e7c3..1ed9731e77ef5 100644 +--- a/drivers/mmc/host/meson-mx-sdhc-mmc.c ++++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c +@@ -269,7 +269,7 @@ static int meson_mx_sdhc_enable_clks(struct mmc_host *mmc) + static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct meson_mx_sdhc_host *host = mmc_priv(mmc); +- u32 rx_clk_phase; ++ u32 val, rx_clk_phase; + int ret; + + meson_mx_sdhc_disable_clks(mmc); +@@ -290,27 +290,11 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) + mmc->actual_clock = clk_get_rate(host->sd_clk); + + /* +- * according to Amlogic the following latching points are +- * selected with empirical values, there is no (known) formula +- * to calculate these. ++ * Phase 90 should work in most cases. For data transmission, ++ * meson_mx_sdhc_execute_tuning() will find a accurate value + */ +- if (mmc->actual_clock > 100000000) { +- rx_clk_phase = 1; +- } else if (mmc->actual_clock > 45000000) { +- if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) +- rx_clk_phase = 15; +- else +- rx_clk_phase = 11; +- } else if (mmc->actual_clock >= 25000000) { +- rx_clk_phase = 15; +- } else if (mmc->actual_clock > 5000000) { +- rx_clk_phase = 23; +- } else if (mmc->actual_clock > 1000000) { +- rx_clk_phase = 55; +- } else { +- rx_clk_phase = 1061; +- } +- ++ regmap_read(host->regmap, MESON_SDHC_CLKC, &val); ++ rx_clk_phase = FIELD_GET(MESON_SDHC_CLKC_CLK_DIV, val) / 4; + regmap_update_bits(host->regmap, MESON_SDHC_CLK2, + MESON_SDHC_CLK2_RX_CLK_PHASE, + FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE, +diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c +index 6b8a57e2d20f0..bed57a1c64b52 100644 +--- a/drivers/mmc/host/sdhci-sprd.c ++++ b/drivers/mmc/host/sdhci-sprd.c +@@ -239,15 +239,19 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host, + div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8); + sdhci_enable_clk(host, div); + ++ val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); ++ mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; + /* Enable CLK_AUTO when the clock is greater than 400K. */ + if (clk > 400000) { +- val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); +- mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | +- SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; + if (mask != (val & mask)) { + val |= mask; + sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); + } ++ } else { ++ if (val & mask) { ++ val &= ~mask; ++ sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); ++ } + } + } + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index f811d59fd71fd..6039886a8544f 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -12073,6 +12073,8 @@ static void bnxt_sp_task(struct work_struct *work) + bnxt_cfg_ntp_filters(bp); + if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_exec_fwd_req(bp); ++ if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) ++ netdev_info(bp->dev, "Receive PF driver unload event!\n"); + if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) { + bnxt_hwrm_port_qstats(bp, 0); + bnxt_hwrm_port_qstats_ext(bp, 0); +@@ -13052,8 +13054,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) + } + } + } +- if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) +- netdev_info(bp->dev, "Receive PF driver unload event!\n"); + } + + #else +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 24bade875ca6a..89c8ddc6565ae 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2132,8 +2132,10 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) + /* Note: if we ever change from DMA_TX_APPEND_CRC below we + * will need to restore software padding of "runt" packets + */ ++ len_stat |= DMA_TX_APPEND_CRC; ++ + if (!i) { +- len_stat |= DMA_TX_APPEND_CRC | DMA_SOP; ++ len_stat |= DMA_SOP; + if (skb->ip_summed == CHECKSUM_PARTIAL) + len_stat |= DMA_TX_DO_CSUM; + } +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index a9f5a8a7d3f05..5b20eba93d048 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -104,12 +104,18 @@ static struct workqueue_struct *i40e_wq; + static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f, + struct net_device *netdev, int delta) + { ++ struct netdev_hw_addr_list *ha_list; + struct netdev_hw_addr *ha; + + if (!f || !netdev) + return; + +- netdev_for_each_mc_addr(ha, netdev) { ++ if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr)) ++ ha_list = &netdev->uc; ++ else ++ ha_list = &netdev->mc; ++ ++ netdev_hw_addr_list_for_each(ha, ha_list) { + if (ether_addr_equal(ha->addr, f->macaddr)) { + ha->refcount += delta; + if (ha->refcount <= 0) +@@ -16479,6 +16485,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev) + return; + + i40e_reset_and_rebuild(pf, false, false); ++#ifdef CONFIG_PCI_IOV ++ i40e_restore_all_vfs_msi_state(pdev); ++#endif /* CONFIG_PCI_IOV */ + } + + /** +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 4441b00297f47..a97ca2224da0e 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -152,6 +152,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) + (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); + } + ++#ifdef CONFIG_PCI_IOV ++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev) ++{ ++ u16 vf_id; ++ u16 pos; ++ ++ /* Continue only if this is a PF */ ++ if (!pdev->is_physfn) ++ return; ++ ++ if (!pci_num_vf(pdev)) ++ return; ++ ++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); ++ if (pos) { ++ struct pci_dev *vf_dev = NULL; ++ ++ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id); ++ while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) { ++ if (vf_dev->is_virtfn && vf_dev->physfn == pdev) ++ pci_restore_msi_state(vf_dev); ++ } ++ } ++} ++#endif /* CONFIG_PCI_IOV */ ++ + /** + * i40e_vc_notify_vf_reset + * @vf: pointer to the VF structure +@@ -3519,16 +3545,16 @@ static int i40e_validate_cloud_filter(struct i40e_vf *vf, + bool found = false; + int bkt; + +- if (!tc_filter->action) { ++ if (tc_filter->action != VIRTCHNL_ACTION_TC_REDIRECT) { + dev_info(&pf->pdev->dev, +- "VF %d: Currently ADq doesn't support Drop Action\n", +- vf->vf_id); ++ "VF %d: ADQ doesn't support this action (%d)\n", ++ vf->vf_id, tc_filter->action); + goto err; + } + + /* action_meta is TC number here to which the filter is applied */ + if (!tc_filter->action_meta || +- tc_filter->action_meta > I40E_MAX_VF_VSI) { ++ tc_filter->action_meta > vf->num_tc) { + dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n", + vf->vf_id, tc_filter->action_meta); + goto err; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +index 895b8feb2567c..bda9ba668c41e 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +@@ -135,6 +135,9 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); + + void i40e_vc_notify_link_state(struct i40e_pf *pf); + void i40e_vc_notify_reset(struct i40e_pf *pf); ++#ifdef CONFIG_PCI_IOV ++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev); ++#endif /* CONFIG_PCI_IOV */ + int i40e_get_vf_stats(struct net_device *netdev, int vf_id, + struct ifla_vf_stats *vf_stats); + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 7784135160fd2..d8d2aa4c0216a 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -2146,7 +2146,7 @@ static int ice_configure_phy(struct ice_vsi *vsi) + + /* Ensure we have media as we cannot configure a medialess port */ + if (!(phy->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE)) +- return -EPERM; ++ return -ENOMEDIUM; + + ice_print_topo_conflict(vsi); + +@@ -9173,8 +9173,14 @@ int ice_stop(struct net_device *netdev) + int link_err = ice_force_phys_link_state(vsi, false); + + if (link_err) { +- netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", +- vsi->vsi_num, link_err); ++ if (link_err == -ENOMEDIUM) ++ netdev_info(vsi->netdev, "Skipping link reconfig - no media attached, VSI %d\n", ++ vsi->vsi_num); ++ else ++ netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", ++ vsi->vsi_num, link_err); ++ ++ ice_vsi_close(vsi); + return -EIO; + } + } +diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h +index f48f82d5e274b..85cc163965062 100644 +--- a/drivers/net/ethernet/intel/igc/igc.h ++++ b/drivers/net/ethernet/intel/igc/igc.h +@@ -568,6 +568,7 @@ struct igc_nfc_filter { + u16 etype; + __be16 vlan_etype; + u16 vlan_tci; ++ u16 vlan_tci_mask; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; + u8 user_data[8]; +diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c +index dd8a9d27a1670..f7284fa4324a4 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -957,6 +957,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, + } + + #define ETHER_TYPE_FULL_MASK ((__force __be16)~0) ++#define VLAN_TCI_FULL_MASK ((__force __be16)~0) + static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, + struct ethtool_rxnfc *cmd) + { +@@ -979,10 +980,16 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, + fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK; + } + ++ if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) { ++ fsp->flow_type |= FLOW_EXT; ++ fsp->h_ext.vlan_etype = rule->filter.vlan_etype; ++ fsp->m_ext.vlan_etype = ETHER_TYPE_FULL_MASK; ++ } ++ + if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { + fsp->flow_type |= FLOW_EXT; + fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci); +- fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK); ++ fsp->m_ext.vlan_tci = htons(rule->filter.vlan_tci_mask); + } + + if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { +@@ -1217,6 +1224,7 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, + + if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { + rule->filter.vlan_tci = ntohs(fsp->h_ext.vlan_tci); ++ rule->filter.vlan_tci_mask = ntohs(fsp->m_ext.vlan_tci); + rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI; + } + +@@ -1254,11 +1262,19 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, + memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data)); + } + +- /* When multiple filter options or user data or vlan etype is set, use a +- * flex filter. ++ /* The i225/i226 has various different filters. Flex filters provide a ++ * way to match up to the first 128 bytes of a packet. Use them for: ++ * a) For specific user data ++ * b) For VLAN EtherType ++ * c) For full TCI match ++ * d) Or in case multiple filter criteria are set ++ * ++ * Otherwise, use the simple MAC, VLAN PRIO or EtherType filters. + */ + if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) || + (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) || ++ ((rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) && ++ rule->filter.vlan_tci_mask == ntohs(VLAN_TCI_FULL_MASK)) || + (rule->filter.match_flags & (rule->filter.match_flags - 1))) + rule->flex = true; + else +@@ -1328,6 +1344,26 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter, + return -EINVAL; + } + ++ /* There are two ways to match the VLAN TCI: ++ * 1. Match on PCP field and use vlan prio filter for it ++ * 2. Match on complete TCI field and use flex filter for it ++ */ ++ if ((fsp->flow_type & FLOW_EXT) && ++ fsp->m_ext.vlan_tci && ++ fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK) && ++ fsp->m_ext.vlan_tci != VLAN_TCI_FULL_MASK) { ++ netdev_dbg(netdev, "VLAN mask not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ /* VLAN EtherType can only be matched by full mask. */ ++ if ((fsp->flow_type & FLOW_EXT) && ++ fsp->m_ext.vlan_etype && ++ fsp->m_ext.vlan_etype != ETHER_TYPE_FULL_MASK) { ++ netdev_dbg(netdev, "VLAN EtherType mask not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ + if (fsp->location >= IGC_MAX_RXNFC_RULES) { + netdev_dbg(netdev, "Invalid location\n"); + return -EINVAL; +diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c +index a9c08321aca90..22cefb1eeedfa 100644 +--- a/drivers/net/ethernet/intel/igc/igc_tsn.c ++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c +@@ -227,7 +227,7 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter) + wr32(IGC_TQAVCC(i), tqavcc); + + wr32(IGC_TQAVHC(i), +- 0x80000000 + ring->hicredit * 0x7735); ++ 0x80000000 + ring->hicredit * 0x7736); + } else { + /* Disable any CBS for the queue */ + txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK); +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h +index de9fbd98dfb76..c92c3f4631d54 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h +@@ -520,7 +520,7 @@ struct npc_lt_def { + u8 ltype_mask; + u8 ltype_match; + u8 lid; +-}; ++} __packed; + + struct npc_lt_def_ipsec { + u8 ltype_mask; +@@ -528,7 +528,7 @@ struct npc_lt_def_ipsec { + u8 lid; + u8 spi_offset; + u8 spi_nz; +-}; ++} __packed; + + struct npc_lt_def_apad { + u8 ltype_mask; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +index cce2806aaa50c..8802961b8889f 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +@@ -905,6 +905,7 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu); + void *rvu_first_cgx_pdata(struct rvu *rvu); + int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id); + int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable); ++int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable); + int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause, + u16 pfc_en); + int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause); +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +index f2b1edf1bb43c..ce987ccd43e29 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +@@ -465,6 +465,23 @@ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start) + return mac_ops->mac_rx_tx_enable(cgxd, lmac_id, start); + } + ++int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable) ++{ ++ int pf = rvu_get_pf(pcifunc); ++ struct mac_ops *mac_ops; ++ u8 cgx_id, lmac_id; ++ void *cgxd; ++ ++ if (!is_cgx_config_permitted(rvu, pcifunc)) ++ return LMAC_AF_ERR_PERM_DENIED; ++ ++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); ++ cgxd = rvu_cgx_pdata(cgx_id, rvu); ++ mac_ops = get_mac_ops(cgxd); ++ ++ return mac_ops->mac_tx_enable(cgxd, lmac_id, enable); ++} ++ + int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable) + { + struct mac_ops *mac_ops; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +index 4227ebb4a758d..58744313f0eb6 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +@@ -4143,90 +4143,18 @@ static void nix_find_link_frs(struct rvu *rvu, + req->minlen = minlen; + } + +-static int +-nix_config_link_credits(struct rvu *rvu, int blkaddr, int link, +- u16 pcifunc, u64 tx_credits) +-{ +- struct rvu_hwinfo *hw = rvu->hw; +- int pf = rvu_get_pf(pcifunc); +- u8 cgx_id = 0, lmac_id = 0; +- unsigned long poll_tmo; +- bool restore_tx_en = 0; +- struct nix_hw *nix_hw; +- u64 cfg, sw_xoff = 0; +- u32 schq = 0; +- u32 credits; +- int rc; +- +- nix_hw = get_nix_hw(rvu->hw, blkaddr); +- if (!nix_hw) +- return NIX_AF_ERR_INVALID_NIXBLK; +- +- if (tx_credits == nix_hw->tx_credits[link]) +- return 0; +- +- /* Enable cgx tx if disabled for credits to be back */ +- if (is_pf_cgxmapped(rvu, pf)) { +- rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); +- restore_tx_en = !rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), +- lmac_id, true); +- } +- +- mutex_lock(&rvu->rsrc_lock); +- /* Disable new traffic to link */ +- if (hw->cap.nix_shaping) { +- schq = nix_get_tx_link(rvu, pcifunc); +- sw_xoff = rvu_read64(rvu, blkaddr, NIX_AF_TL1X_SW_XOFF(schq)); +- rvu_write64(rvu, blkaddr, +- NIX_AF_TL1X_SW_XOFF(schq), BIT_ULL(0)); +- } +- +- rc = NIX_AF_ERR_LINK_CREDITS; +- poll_tmo = jiffies + usecs_to_jiffies(200000); +- /* Wait for credits to return */ +- do { +- if (time_after(jiffies, poll_tmo)) +- goto exit; +- usleep_range(100, 200); +- +- cfg = rvu_read64(rvu, blkaddr, +- NIX_AF_TX_LINKX_NORM_CREDIT(link)); +- credits = (cfg >> 12) & 0xFFFFFULL; +- } while (credits != nix_hw->tx_credits[link]); +- +- cfg &= ~(0xFFFFFULL << 12); +- cfg |= (tx_credits << 12); +- rvu_write64(rvu, blkaddr, NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg); +- rc = 0; +- +- nix_hw->tx_credits[link] = tx_credits; +- +-exit: +- /* Enable traffic back */ +- if (hw->cap.nix_shaping && !sw_xoff) +- rvu_write64(rvu, blkaddr, NIX_AF_TL1X_SW_XOFF(schq), 0); +- +- /* Restore state of cgx tx */ +- if (restore_tx_en) +- rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); +- +- mutex_unlock(&rvu->rsrc_lock); +- return rc; +-} +- + int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req, + struct msg_rsp *rsp) + { + struct rvu_hwinfo *hw = rvu->hw; + u16 pcifunc = req->hdr.pcifunc; + int pf = rvu_get_pf(pcifunc); +- int blkaddr, schq, link = -1; +- struct nix_txsch *txsch; +- u64 cfg, lmac_fifo_len; ++ int blkaddr, link = -1; + struct nix_hw *nix_hw; + struct rvu_pfvf *pfvf; + u8 cgx = 0, lmac = 0; + u16 max_mtu; ++ u64 cfg; + + blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc); + if (blkaddr < 0) +@@ -4247,25 +4175,6 @@ int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req, + if (req->update_minlen && req->minlen < NIC_HW_MIN_FRS) + return NIX_AF_ERR_FRS_INVALID; + +- /* Check if requester wants to update SMQ's */ +- if (!req->update_smq) +- goto rx_frscfg; +- +- /* Update min/maxlen in each of the SMQ attached to this PF/VF */ +- txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ]; +- mutex_lock(&rvu->rsrc_lock); +- for (schq = 0; schq < txsch->schq.max; schq++) { +- if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc) +- continue; +- cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq)); +- cfg = (cfg & ~(0xFFFFULL << 8)) | ((u64)req->maxlen << 8); +- if (req->update_minlen) +- cfg = (cfg & ~0x7FULL) | ((u64)req->minlen & 0x7F); +- rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq), cfg); +- } +- mutex_unlock(&rvu->rsrc_lock); +- +-rx_frscfg: + /* Check if config is for SDP link */ + if (req->sdp_link) { + if (!hw->sdp_links) +@@ -4288,7 +4197,6 @@ rx_frscfg: + if (link < 0) + return NIX_AF_ERR_RX_LINK_INVALID; + +- + linkcfg: + nix_find_link_frs(rvu, req, pcifunc); + +@@ -4298,19 +4206,7 @@ linkcfg: + cfg = (cfg & ~0xFFFFULL) | req->minlen; + rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link), cfg); + +- if (req->sdp_link || pf == 0) +- return 0; +- +- /* Update transmit credits for CGX links */ +- lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, lmac); +- if (!lmac_fifo_len) { +- dev_err(rvu->dev, +- "%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n", +- __func__, cgx, lmac); +- return 0; +- } +- return nix_config_link_credits(rvu, blkaddr, link, pcifunc, +- (lmac_fifo_len - req->maxlen) / 16); ++ return 0; + } + + int rvu_mbox_handler_nix_set_rx_cfg(struct rvu *rvu, struct nix_rx_cfg *req, +@@ -4841,7 +4737,13 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req, + pfvf = rvu_get_pfvf(rvu, pcifunc); + clear_bit(NIXLF_INITIALIZED, &pfvf->flags); + +- return rvu_cgx_start_stop_io(rvu, pcifunc, false); ++ err = rvu_cgx_start_stop_io(rvu, pcifunc, false); ++ if (err) ++ return err; ++ ++ rvu_cgx_tx_enable(rvu, pcifunc, true); ++ ++ return 0; + } + + #define RX_SA_BASE GENMASK_ULL(52, 7) +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +index 0d5a41a2ae010..227d01cace3f0 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +@@ -267,6 +267,13 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts) + priv->stats.rx_truncate_errors++; + } + ++ /* Read receive consumer index before replenish so that this routine ++ * returns accurate return value even if packet is received into ++ * just-replenished buffer prior to exiting this routine. ++ */ ++ rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI); ++ rx_ci_rem = rx_ci % priv->rx_q_entries; ++ + /* Let hardware know we've replenished one buffer */ + rx_pi++; + +@@ -279,8 +286,6 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts) + rx_pi_rem = rx_pi % priv->rx_q_entries; + if (rx_pi_rem == 0) + priv->valid_polarity ^= 1; +- rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI); +- rx_ci_rem = rx_ci % priv->rx_q_entries; + + if (skb) + netif_receive_skb(skb); +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index 0d57ffcedf0c6..fc78bc959ded8 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -2591,6 +2591,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + + if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { + netdev_err(qdev->ndev, "lBufQ failed\n"); ++ kfree(qdev->lrg_buf); + return -ENOMEM; + } + qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; +@@ -2615,6 +2616,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) + qdev->lrg_buf_q_alloc_size, + qdev->lrg_buf_q_alloc_virt_addr, + qdev->lrg_buf_q_alloc_phy_addr); ++ kfree(qdev->lrg_buf); + return -ENOMEM; + } + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index bb787a52bc754..81fd31f6fac46 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -1211,7 +1211,7 @@ static void rtl8168ep_driver_start(struct rtl8169_private *tp) + { + r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); + r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); +- rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10); ++ rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30); + } + + static void rtl8168_driver_start(struct rtl8169_private *tp) +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index bb56cf4090423..3c2a6b23c202a 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -66,16 +66,27 @@ int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value) + return -ETIMEDOUT; + } + +-static int ravb_config(struct net_device *ndev) ++static int ravb_set_opmode(struct net_device *ndev, u32 opmode) + { ++ u32 csr_ops = 1U << (opmode & CCC_OPC); ++ u32 ccc_mask = CCC_OPC; + int error; + +- /* Set config mode */ +- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); +- /* Check if the operating mode is changed to the config mode */ +- error = ravb_wait(ndev, CSR, CSR_OPS, CSR_OPS_CONFIG); +- if (error) +- netdev_err(ndev, "failed to switch device to config mode\n"); ++ /* If gPTP active in config mode is supported it needs to be configured ++ * along with CSEL and operating mode in the same access. This is a ++ * hardware limitation. ++ */ ++ if (opmode & CCC_GAC) ++ ccc_mask |= CCC_GAC | CCC_CSEL; ++ ++ /* Set operating mode */ ++ ravb_modify(ndev, CCC, ccc_mask, opmode); ++ /* Check if the operating mode is changed to the requested one */ ++ error = ravb_wait(ndev, CSR, CSR_OPS, csr_ops); ++ if (error) { ++ netdev_err(ndev, "failed to switch device to requested mode (%u)\n", ++ opmode & CCC_OPC); ++ } + + return error; + } +@@ -673,7 +684,7 @@ static int ravb_dmac_init(struct net_device *ndev) + int error; + + /* Set CONFIG mode */ +- error = ravb_config(ndev); ++ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); + if (error) + return error; + +@@ -682,9 +693,7 @@ static int ravb_dmac_init(struct net_device *ndev) + return error; + + /* Setting the control will start the AVB-DMAC process. */ +- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION); +- +- return 0; ++ return ravb_set_opmode(ndev, CCC_OPC_OPERATION); + } + + static void ravb_get_tx_tstamp(struct net_device *ndev) +@@ -1046,7 +1055,7 @@ static int ravb_stop_dma(struct net_device *ndev) + return error; + + /* Stop AVB-DMAC process */ +- return ravb_config(ndev); ++ return ravb_set_opmode(ndev, CCC_OPC_CONFIG); + } + + /* E-MAC interrupt handler */ +@@ -2560,21 +2569,25 @@ static int ravb_set_gti(struct net_device *ndev) + return 0; + } + +-static void ravb_set_config_mode(struct net_device *ndev) ++static int ravb_set_config_mode(struct net_device *ndev) + { + struct ravb_private *priv = netdev_priv(ndev); + const struct ravb_hw_info *info = priv->info; ++ int error; + + if (info->gptp) { +- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); ++ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); ++ if (error) ++ return error; + /* Set CSEL value */ + ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); + } else if (info->ccc_gac) { +- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG | +- CCC_GAC | CCC_CSEL_HPB); ++ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB); + } else { +- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); ++ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); + } ++ ++ return error; + } + + /* Set tx and rx clock internal delay modes */ +@@ -2794,7 +2807,9 @@ static int ravb_probe(struct platform_device *pdev) + ndev->ethtool_ops = &ravb_ethtool_ops; + + /* Set AVB config mode */ +- ravb_set_config_mode(ndev); ++ error = ravb_set_config_mode(ndev); ++ if (error) ++ goto out_disable_gptp_clk; + + if (info->gptp || info->ccc_gac) { + /* Set GTI value */ +@@ -2917,8 +2932,7 @@ static int ravb_remove(struct platform_device *pdev) + dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, + priv->desc_bat_dma); + +- /* Set reset mode */ +- ravb_write(ndev, CCC_OPC_RESET, CCC); ++ ravb_set_opmode(ndev, CCC_OPC_RESET); + + clk_disable_unprepare(priv->gptp_clk); + clk_disable_unprepare(priv->refclk); +@@ -3002,8 +3016,11 @@ static int __maybe_unused ravb_resume(struct device *dev) + int ret = 0; + + /* If WoL is enabled set reset mode to rearm the WoL logic */ +- if (priv->wol_enabled) +- ravb_write(ndev, CCC_OPC_RESET, CCC); ++ if (priv->wol_enabled) { ++ ret = ravb_set_opmode(ndev, CCC_OPC_RESET); ++ if (ret) ++ return ret; ++ } + + /* All register have been reset to default values. + * Restore all registers which where setup at probe time and +@@ -3011,7 +3028,9 @@ static int __maybe_unused ravb_resume(struct device *dev) + */ + + /* Set AVB config mode */ +- ravb_set_config_mode(ndev); ++ ret = ravb_set_config_mode(ndev); ++ if (ret) ++ return ret; + + if (info->gptp || info->ccc_gac) { + /* Set GTI value */ +diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c +index d2f35ee15effe..fac227d372db4 100644 +--- a/drivers/net/ethernet/sfc/rx_common.c ++++ b/drivers/net/ethernet/sfc/rx_common.c +@@ -823,8 +823,10 @@ int efx_probe_filters(struct efx_nic *efx) + } + + if (!success) { +- efx_for_each_channel(channel, efx) ++ efx_for_each_channel(channel, efx) { + kfree(channel->rps_flow_id); ++ channel->rps_flow_id = NULL; ++ } + efx->type->filter_table_remove(efx); + rc = -ENOMEM; + goto out_unlock; +diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c +index 21505920136c6..e078f4071dc23 100644 +--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c ++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c +@@ -160,60 +160,6 @@ static __le32 wx_test_staterr(union wx_rx_desc *rx_desc, + return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits); + } + +-static bool wx_can_reuse_rx_page(struct wx_rx_buffer *rx_buffer, +- int rx_buffer_pgcnt) +-{ +- unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; +- struct page *page = rx_buffer->page; +- +- /* avoid re-using remote and pfmemalloc pages */ +- if (!dev_page_is_reusable(page)) +- return false; +- +-#if (PAGE_SIZE < 8192) +- /* if we are only owner of page we can reuse it */ +- if (unlikely((rx_buffer_pgcnt - pagecnt_bias) > 1)) +- return false; +-#endif +- +- /* If we have drained the page fragment pool we need to update +- * the pagecnt_bias and page count so that we fully restock the +- * number of references the driver holds. +- */ +- if (unlikely(pagecnt_bias == 1)) { +- page_ref_add(page, USHRT_MAX - 1); +- rx_buffer->pagecnt_bias = USHRT_MAX; +- } +- +- return true; +-} +- +-/** +- * wx_reuse_rx_page - page flip buffer and store it back on the ring +- * @rx_ring: rx descriptor ring to store buffers on +- * @old_buff: donor buffer to have page reused +- * +- * Synchronizes page for reuse by the adapter +- **/ +-static void wx_reuse_rx_page(struct wx_ring *rx_ring, +- struct wx_rx_buffer *old_buff) +-{ +- u16 nta = rx_ring->next_to_alloc; +- struct wx_rx_buffer *new_buff; +- +- new_buff = &rx_ring->rx_buffer_info[nta]; +- +- /* update, and store next to alloc */ +- nta++; +- rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; +- +- /* transfer page from old buffer to new buffer */ +- new_buff->page = old_buff->page; +- new_buff->page_dma = old_buff->page_dma; +- new_buff->page_offset = old_buff->page_offset; +- new_buff->pagecnt_bias = old_buff->pagecnt_bias; +-} +- + static void wx_dma_sync_frag(struct wx_ring *rx_ring, + struct wx_rx_buffer *rx_buffer) + { +@@ -270,8 +216,6 @@ static struct wx_rx_buffer *wx_get_rx_buffer(struct wx_ring *rx_ring, + size, + DMA_FROM_DEVICE); + skip_sync: +- rx_buffer->pagecnt_bias--; +- + return rx_buffer; + } + +@@ -280,19 +224,9 @@ static void wx_put_rx_buffer(struct wx_ring *rx_ring, + struct sk_buff *skb, + int rx_buffer_pgcnt) + { +- if (wx_can_reuse_rx_page(rx_buffer, rx_buffer_pgcnt)) { +- /* hand second half of page back to the ring */ +- wx_reuse_rx_page(rx_ring, rx_buffer); +- } else { +- if (!IS_ERR(skb) && WX_CB(skb)->dma == rx_buffer->dma) +- /* the page has been released from the ring */ +- WX_CB(skb)->page_released = true; +- else +- page_pool_put_full_page(rx_ring->page_pool, rx_buffer->page, false); +- +- __page_frag_cache_drain(rx_buffer->page, +- rx_buffer->pagecnt_bias); +- } ++ if (!IS_ERR(skb) && WX_CB(skb)->dma == rx_buffer->dma) ++ /* the page has been released from the ring */ ++ WX_CB(skb)->page_released = true; + + /* clear contents of rx_buffer */ + rx_buffer->page = NULL; +@@ -335,11 +269,12 @@ static struct sk_buff *wx_build_skb(struct wx_ring *rx_ring, + if (size <= WX_RXBUFFER_256) { + memcpy(__skb_put(skb, size), page_addr, + ALIGN(size, sizeof(long))); +- rx_buffer->pagecnt_bias++; +- ++ page_pool_put_full_page(rx_ring->page_pool, rx_buffer->page, true); + return skb; + } + ++ skb_mark_for_recycle(skb); ++ + if (!wx_test_staterr(rx_desc, WX_RXD_STAT_EOP)) + WX_CB(skb)->dma = rx_buffer->dma; + +@@ -382,8 +317,6 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring, + bi->page_dma = dma; + bi->page = page; + bi->page_offset = 0; +- page_ref_add(page, USHRT_MAX - 1); +- bi->pagecnt_bias = USHRT_MAX; + + return true; + } +@@ -721,7 +654,6 @@ static int wx_clean_rx_irq(struct wx_q_vector *q_vector, + + /* exit if we failed to retrieve a buffer */ + if (!skb) { +- rx_buffer->pagecnt_bias++; + break; + } + +@@ -2241,8 +2173,6 @@ static void wx_clean_rx_ring(struct wx_ring *rx_ring) + + /* free resources associated with mapping */ + page_pool_put_full_page(rx_ring->page_pool, rx_buffer->page, false); +- __page_frag_cache_drain(rx_buffer->page, +- rx_buffer->pagecnt_bias); + + i++; + rx_buffer++; +diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h +index c5cbd177ef627..c555af9ed51b2 100644 +--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h ++++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h +@@ -759,7 +759,6 @@ struct wx_rx_buffer { + dma_addr_t page_dma; + struct page *page; + unsigned int page_offset; +- u16 pagecnt_bias; + }; + + struct wx_queue_stats { +diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c +index 3777c7e2e6fc0..e47bb125048d4 100644 +--- a/drivers/net/usb/ax88172a.c ++++ b/drivers/net/usb/ax88172a.c +@@ -161,7 +161,9 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) + u8 buf[ETH_ALEN]; + struct ax88172a_private *priv; + +- usbnet_get_endpoints(dev, intf); ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret) ++ return ret; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 0c0be6b872c6a..deb2229ab4d82 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -334,7 +334,6 @@ struct virtio_net_common_hdr { + }; + }; + +-static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf); + static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf); + + static bool is_xdp_frame(void *ptr) +@@ -408,6 +407,17 @@ static struct page *get_a_page(struct receive_queue *rq, gfp_t gfp_mask) + return p; + } + ++static void virtnet_rq_free_buf(struct virtnet_info *vi, ++ struct receive_queue *rq, void *buf) ++{ ++ if (vi->mergeable_rx_bufs) ++ put_page(virt_to_head_page(buf)); ++ else if (vi->big_packets) ++ give_pages(rq, buf); ++ else ++ put_page(virt_to_head_page(buf)); ++} ++ + static void enable_delayed_refill(struct virtnet_info *vi) + { + spin_lock_bh(&vi->refill_lock); +@@ -634,17 +644,6 @@ static void *virtnet_rq_get_buf(struct receive_queue *rq, u32 *len, void **ctx) + return buf; + } + +-static void *virtnet_rq_detach_unused_buf(struct receive_queue *rq) +-{ +- void *buf; +- +- buf = virtqueue_detach_unused_buf(rq->vq); +- if (buf && rq->do_dma) +- virtnet_rq_unmap(rq, buf, 0); +- +- return buf; +-} +- + static void virtnet_rq_init_one_sg(struct receive_queue *rq, void *buf, u32 len) + { + struct virtnet_rq_dma *dma; +@@ -744,6 +743,20 @@ static void virtnet_rq_set_premapped(struct virtnet_info *vi) + } + } + ++static void virtnet_rq_unmap_free_buf(struct virtqueue *vq, void *buf) ++{ ++ struct virtnet_info *vi = vq->vdev->priv; ++ struct receive_queue *rq; ++ int i = vq2rxq(vq); ++ ++ rq = &vi->rq[i]; ++ ++ if (rq->do_dma) ++ virtnet_rq_unmap(rq, buf, 0); ++ ++ virtnet_rq_free_buf(vi, rq, buf); ++} ++ + static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi) + { + unsigned int len; +@@ -1258,7 +1271,7 @@ static struct sk_buff *receive_small(struct net_device *dev, + if (unlikely(len > GOOD_PACKET_LEN)) { + pr_debug("%s: rx error: len %u exceeds max size %d\n", + dev->name, len, GOOD_PACKET_LEN); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err; + } + +@@ -1323,7 +1336,7 @@ static void mergeable_buf_free(struct receive_queue *rq, int num_buf, + if (unlikely(!buf)) { + pr_debug("%s: rx error: %d buffers missing\n", + dev->name, num_buf); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + break; + } + u64_stats_add(&stats->bytes, len); +@@ -1432,7 +1445,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev, + pr_debug("%s: rx error: %d buffers out of %d missing\n", + dev->name, *num_buf, + virtio16_to_cpu(vi->vdev, hdr->num_buffers)); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err; + } + +@@ -1451,7 +1464,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev, + put_page(page); + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)(truesize - room)); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err; + } + +@@ -1630,7 +1643,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + if (unlikely(len > truesize - room)) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)(truesize - room)); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err_skb; + } + +@@ -1662,7 +1675,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + dev->name, num_buf, + virtio16_to_cpu(vi->vdev, + hdr->num_buffers)); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err_buf; + } + +@@ -1676,7 +1689,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + if (unlikely(len > truesize - room)) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)(truesize - room)); +- dev->stats.rx_length_errors++; ++ DEV_STATS_INC(dev, rx_length_errors); + goto err_skb; + } + +@@ -1763,8 +1776,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, + + if (unlikely(len < vi->hdr_len + ETH_HLEN)) { + pr_debug("%s: short packet %i\n", dev->name, len); +- dev->stats.rx_length_errors++; +- virtnet_rq_free_unused_buf(rq->vq, buf); ++ DEV_STATS_INC(dev, rx_length_errors); ++ virtnet_rq_free_buf(vi, rq, buf); + return; + } + +@@ -1803,7 +1816,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, + return; + + frame_err: +- dev->stats.rx_frame_errors++; ++ DEV_STATS_INC(dev, rx_frame_errors); + dev_kfree_skb(skb); + } + +@@ -2352,12 +2365,12 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) + + /* This should not happen! */ + if (unlikely(err)) { +- dev->stats.tx_fifo_errors++; ++ DEV_STATS_INC(dev, tx_fifo_errors); + if (net_ratelimit()) + dev_warn(&dev->dev, + "Unexpected TXQ (%d) queue failure: %d\n", + qnum, err); +- dev->stats.tx_dropped++; ++ DEV_STATS_INC(dev, tx_dropped); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } +@@ -2392,7 +2405,7 @@ static int virtnet_rx_resize(struct virtnet_info *vi, + if (running) + napi_disable(&rq->napi); + +- err = virtqueue_resize(rq->vq, ring_num, virtnet_rq_free_unused_buf); ++ err = virtqueue_resize(rq->vq, ring_num, virtnet_rq_unmap_free_buf); + if (err) + netdev_err(vi->dev, "resize rx fail: rx queue index: %d err: %d\n", qindex, err); + +@@ -2576,10 +2589,10 @@ static void virtnet_stats(struct net_device *dev, + tot->tx_errors += terrors; + } + +- tot->tx_dropped = dev->stats.tx_dropped; +- tot->tx_fifo_errors = dev->stats.tx_fifo_errors; +- tot->rx_length_errors = dev->stats.rx_length_errors; +- tot->rx_frame_errors = dev->stats.rx_frame_errors; ++ tot->tx_dropped = DEV_STATS_READ(dev, tx_dropped); ++ tot->tx_fifo_errors = DEV_STATS_READ(dev, tx_fifo_errors); ++ tot->rx_length_errors = DEV_STATS_READ(dev, rx_length_errors); ++ tot->rx_frame_errors = DEV_STATS_READ(dev, rx_frame_errors); + } + + static void virtnet_ack_link_announce(struct virtnet_info *vi) +@@ -4031,19 +4044,6 @@ static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf) + xdp_return_frame(ptr_to_xdp(buf)); + } + +-static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf) +-{ +- struct virtnet_info *vi = vq->vdev->priv; +- int i = vq2rxq(vq); +- +- if (vi->mergeable_rx_bufs) +- put_page(virt_to_head_page(buf)); +- else if (vi->big_packets) +- give_pages(&vi->rq[i], buf); +- else +- put_page(virt_to_head_page(buf)); +-} +- + static void free_unused_bufs(struct virtnet_info *vi) + { + void *buf; +@@ -4057,10 +4057,10 @@ static void free_unused_bufs(struct virtnet_info *vi) + } + + for (i = 0; i < vi->max_queue_pairs; i++) { +- struct receive_queue *rq = &vi->rq[i]; ++ struct virtqueue *vq = vi->rq[i].vq; + +- while ((buf = virtnet_rq_detach_unused_buf(rq)) != NULL) +- virtnet_rq_free_unused_buf(rq->vq, buf); ++ while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) ++ virtnet_rq_unmap_free_buf(vq, buf); + cond_resched(); + } + } +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +index 0f6493dab8cbd..5602441df2b7e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +@@ -749,7 +749,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) + } + } + +-void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans); ++void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq); + + static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) + { +@@ -796,7 +796,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) + return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans)); + } + +-void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); ++void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq); + void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); + + #ifdef CONFIG_IWLWIFI_DEBUGFS +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +index 4614acee9f7ba..a9415d333490c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +@@ -1785,7 +1785,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans) + return inta; + } + +-void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) ++void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct isr_statistics *isr_stats = &trans_pcie->isr_stats; +@@ -1809,7 +1809,7 @@ void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) + isr_stats->rfkill++; + + if (prev != report) +- iwl_trans_pcie_rf_kill(trans, report); ++ iwl_trans_pcie_rf_kill(trans, report, from_irq); + mutex_unlock(&trans_pcie->mutex); + + if (hw_rfkill) { +@@ -1949,7 +1949,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) + + /* HW RF KILL switch toggled */ + if (inta & CSR_INT_BIT_RF_KILL) { +- iwl_pcie_handle_rfkill_irq(trans); ++ iwl_pcie_handle_rfkill_irq(trans, true); + handled |= CSR_INT_BIT_RF_KILL; + } + +@@ -2366,7 +2366,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) + + /* HW RF KILL switch toggled */ + if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) +- iwl_pcie_handle_rfkill_irq(trans); ++ iwl_pcie_handle_rfkill_irq(trans, true); + + if (inta_hw & MSIX_HW_INT_CAUSES_REG_HW_ERR) { + IWL_ERR(trans, +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index 2e23ccd7d7938..1bc4a0089c6ff 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -1082,7 +1082,7 @@ bool iwl_pcie_check_hw_rf_kill(struct iwl_trans *trans) + report = test_bit(STATUS_RFKILL_OPMODE, &trans->status); + + if (prev != report) +- iwl_trans_pcie_rf_kill(trans, report); ++ iwl_trans_pcie_rf_kill(trans, report, false); + + return hw_rfkill; + } +@@ -1236,7 +1236,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie) + trans_pcie->hw_mask = trans_pcie->hw_init_mask; + } + +-static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) ++static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool from_irq) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + +@@ -1263,7 +1263,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) + if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { + IWL_DEBUG_INFO(trans, + "DEVICE_ENABLED bit was set and is now cleared\n"); +- iwl_pcie_synchronize_irqs(trans); ++ if (!from_irq) ++ iwl_pcie_synchronize_irqs(trans); + iwl_pcie_rx_napi_sync(trans); + iwl_pcie_tx_stop(trans); + iwl_pcie_rx_stop(trans); +@@ -1453,7 +1454,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans, + clear_bit(STATUS_RFKILL_OPMODE, &trans->status); + } + if (hw_rfkill != was_in_rfkill) +- iwl_trans_pcie_rf_kill(trans, hw_rfkill); ++ iwl_trans_pcie_rf_kill(trans, hw_rfkill, false); + } + + static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) +@@ -1468,12 +1469,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) + mutex_lock(&trans_pcie->mutex); + trans_pcie->opmode_down = true; + was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); +- _iwl_trans_pcie_stop_device(trans); ++ _iwl_trans_pcie_stop_device(trans, false); + iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); + mutex_unlock(&trans_pcie->mutex); + } + +-void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) ++void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq) + { + struct iwl_trans_pcie __maybe_unused *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); +@@ -1486,7 +1487,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) + if (trans->trans_cfg->gen2) + _iwl_trans_pcie_gen2_stop_device(trans); + else +- _iwl_trans_pcie_stop_device(trans); ++ _iwl_trans_pcie_stop_device(trans, from_irq); + } + } + +@@ -2869,7 +2870,7 @@ static ssize_t iwl_dbgfs_rfkill_write(struct file *file, + IWL_WARN(trans, "changing debug rfkill %d->%d\n", + trans_pcie->debug_rfkill, new_value); + trans_pcie->debug_rfkill = new_value; +- iwl_pcie_handle_rfkill_irq(trans); ++ iwl_pcie_handle_rfkill_irq(trans, false); + + return count; + } +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index a607f277ccf10..59d6cb1a3a9d5 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1335,6 +1335,9 @@ static int pci_set_full_power_state(struct pci_dev *dev) + pci_restore_bars(dev); + } + ++ if (dev->bus->self) ++ pcie_aspm_pm_state_change(dev->bus->self); ++ + return 0; + } + +@@ -1429,6 +1432,9 @@ static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state) + pci_power_name(dev->current_state), + pci_power_name(state)); + ++ if (dev->bus->self) ++ pcie_aspm_pm_state_change(dev->bus->self); ++ + return 0; + } + +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index 39a8932dc340c..5484048f457d1 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -566,10 +566,12 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt); + #ifdef CONFIG_PCIEASPM + void pcie_aspm_init_link_state(struct pci_dev *pdev); + void pcie_aspm_exit_link_state(struct pci_dev *pdev); ++void pcie_aspm_pm_state_change(struct pci_dev *pdev); + void pcie_aspm_powersave_config_link(struct pci_dev *pdev); + #else + static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } + static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } ++static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } + static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } + #endif + +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index 67b13f26ba7c7..7e3b342215e5b 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -1001,6 +1001,25 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) + up_read(&pci_bus_sem); + } + ++/* @pdev: the root port or switch downstream port */ ++void pcie_aspm_pm_state_change(struct pci_dev *pdev) ++{ ++ struct pcie_link_state *link = pdev->link_state; ++ ++ if (aspm_disabled || !link) ++ return; ++ /* ++ * Devices changed PM state, we should recheck if latency ++ * meets all functions' requirement ++ */ ++ down_read(&pci_bus_sem); ++ mutex_lock(&aspm_lock); ++ pcie_update_aspm_capable(link->root); ++ pcie_config_aspm_path(link); ++ mutex_unlock(&aspm_lock); ++ up_read(&pci_bus_sem); ++} ++ + void pcie_aspm_powersave_config_link(struct pci_dev *pdev) + { + struct pcie_link_state *link = pdev->link_state; +diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c +index f021ec5a70e5c..553725e1269c9 100644 +--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c ++++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c +@@ -100,7 +100,7 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw) + static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) + { +- return clamp_val(rate, 50000000, 1600000000); ++ return clamp_val(rate, 125000000, 1600000000); + } + + static const struct clk_ops mtk_mipi_tx_pll_ops = { +diff --git a/drivers/phy/sunplus/phy-sunplus-usb2.c b/drivers/phy/sunplus/phy-sunplus-usb2.c +index 0efe74ac9c6af..637a5fbae6d9a 100644 +--- a/drivers/phy/sunplus/phy-sunplus-usb2.c ++++ b/drivers/phy/sunplus/phy-sunplus-usb2.c +@@ -275,7 +275,7 @@ static int sp_usb_phy_probe(struct platform_device *pdev) + + phy = devm_phy_create(&pdev->dev, NULL, &sp_uphy_ops); + if (IS_ERR(phy)) { +- ret = -PTR_ERR(phy); ++ ret = PTR_ERR(phy); + return ret; + } + +diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c +index 555b323f45da1..bc847d3879f79 100644 +--- a/drivers/phy/ti/phy-gmii-sel.c ++++ b/drivers/phy/ti/phy-gmii-sel.c +@@ -64,6 +64,7 @@ struct phy_gmii_sel_priv { + u32 num_ports; + u32 reg_offset; + u32 qsgmii_main_ports; ++ bool no_offset; + }; + + static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode) +@@ -402,7 +403,8 @@ static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv) + priv->num_ports = size / sizeof(u32); + if (!priv->num_ports) + return -EINVAL; +- priv->reg_offset = __be32_to_cpu(*offset); ++ if (!priv->no_offset) ++ priv->reg_offset = __be32_to_cpu(*offset); + } + + if_phys = devm_kcalloc(dev, priv->num_ports, +@@ -471,6 +473,7 @@ static int phy_gmii_sel_probe(struct platform_device *pdev) + dev_err(dev, "Failed to get syscon %d\n", ret); + return ret; + } ++ priv->no_offset = true; + } + + ret = phy_gmii_sel_init_ports(priv); +diff --git a/fs/dax.c b/fs/dax.c +index 8fafecbe42b15..3380b43cb6bbb 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -412,23 +412,23 @@ static struct page *dax_busy_page(void *entry) + return NULL; + } + +-/* +- * dax_lock_page - Lock the DAX entry corresponding to a page +- * @page: The page whose entry we want to lock ++/** ++ * dax_lock_folio - Lock the DAX entry corresponding to a folio ++ * @folio: The folio whose entry we want to lock + * + * Context: Process context. +- * Return: A cookie to pass to dax_unlock_page() or 0 if the entry could ++ * Return: A cookie to pass to dax_unlock_folio() or 0 if the entry could + * not be locked. + */ +-dax_entry_t dax_lock_page(struct page *page) ++dax_entry_t dax_lock_folio(struct folio *folio) + { + XA_STATE(xas, NULL, 0); + void *entry; + +- /* Ensure page->mapping isn't freed while we look at it */ ++ /* Ensure folio->mapping isn't freed while we look at it */ + rcu_read_lock(); + for (;;) { +- struct address_space *mapping = READ_ONCE(page->mapping); ++ struct address_space *mapping = READ_ONCE(folio->mapping); + + entry = NULL; + if (!mapping || !dax_mapping(mapping)) +@@ -447,11 +447,11 @@ dax_entry_t dax_lock_page(struct page *page) + + xas.xa = &mapping->i_pages; + xas_lock_irq(&xas); +- if (mapping != page->mapping) { ++ if (mapping != folio->mapping) { + xas_unlock_irq(&xas); + continue; + } +- xas_set(&xas, page->index); ++ xas_set(&xas, folio->index); + entry = xas_load(&xas); + if (dax_is_locked(entry)) { + rcu_read_unlock(); +@@ -467,10 +467,10 @@ dax_entry_t dax_lock_page(struct page *page) + return (dax_entry_t)entry; + } + +-void dax_unlock_page(struct page *page, dax_entry_t cookie) ++void dax_unlock_folio(struct folio *folio, dax_entry_t cookie) + { +- struct address_space *mapping = page->mapping; +- XA_STATE(xas, &mapping->i_pages, page->index); ++ struct address_space *mapping = folio->mapping; ++ XA_STATE(xas, &mapping->i_pages, folio->index); + + if (S_ISCHR(mapping->host->i_mode)) + return; +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 4eac7dcb82f94..ec1e5e20a36be 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -993,7 +993,6 @@ release_iface(struct kref *ref) + struct cifs_server_iface *iface = container_of(ref, + struct cifs_server_iface, + refcount); +- list_del_init(&iface->iface_head); + kfree(iface); + } + +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 76ccbdba58558..b82f60d6f47ee 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -209,10 +209,13 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { + /* check if iface is still active */ +- if (!cifs_chan_is_iface_active(ses, server)) ++ spin_lock(&ses->chan_lock); ++ if (!cifs_chan_is_iface_active(ses, server)) { ++ spin_unlock(&ses->chan_lock); + cifs_chan_update_iface(ses, server); ++ spin_lock(&ses->chan_lock); ++ } + +- spin_lock(&ses->chan_lock); + if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) { + spin_unlock(&ses->chan_lock); + continue; +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index e917eeba9c772..94e4af4128f1d 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -593,16 +593,12 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, + } + + /* +- * Go through iface_list and do kref_put to remove +- * any unused ifaces. ifaces in use will be removed +- * when the last user calls a kref_put on it ++ * Go through iface_list and mark them as inactive + */ + list_for_each_entry_safe(iface, niface, &ses->iface_list, +- iface_head) { ++ iface_head) + iface->is_active = 0; +- kref_put(&iface->refcount, release_iface); +- ses->iface_count--; +- } ++ + spin_unlock(&ses->iface_lock); + + /* +@@ -676,10 +672,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, + iface_head) { + ret = iface_cmp(iface, &tmp_iface); + if (!ret) { +- /* just get a ref so that it doesn't get picked/freed */ + iface->is_active = 1; +- kref_get(&iface->refcount); +- ses->iface_count++; + spin_unlock(&ses->iface_lock); + goto next_iface; + } else if (ret < 0) { +@@ -746,6 +739,20 @@ next_iface: + } + + out: ++ /* ++ * Go through the list again and put the inactive entries ++ */ ++ spin_lock(&ses->iface_lock); ++ list_for_each_entry_safe(iface, niface, &ses->iface_list, ++ iface_head) { ++ if (!iface->is_active) { ++ list_del(&iface->iface_head); ++ kref_put(&iface->refcount, release_iface); ++ ses->iface_count--; ++ } ++ } ++ spin_unlock(&ses->iface_lock); ++ + return rc; + } + +@@ -782,9 +789,14 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_ + goto out; + + /* check if iface is still active */ ++ spin_lock(&ses->chan_lock); + pserver = ses->chans[0].server; +- if (pserver && !cifs_chan_is_iface_active(ses, pserver)) ++ if (pserver && !cifs_chan_is_iface_active(ses, pserver)) { ++ spin_unlock(&ses->chan_lock); + cifs_chan_update_iface(ses, pserver); ++ spin_lock(&ses->chan_lock); ++ } ++ spin_unlock(&ses->chan_lock); + + out: + kfree(out_buf); +diff --git a/include/linux/dax.h b/include/linux/dax.h +index 22cd9902345d7..b463502b16e17 100644 +--- a/include/linux/dax.h ++++ b/include/linux/dax.h +@@ -159,8 +159,8 @@ int dax_writeback_mapping_range(struct address_space *mapping, + + struct page *dax_layout_busy_page(struct address_space *mapping); + struct page *dax_layout_busy_page_range(struct address_space *mapping, loff_t start, loff_t end); +-dax_entry_t dax_lock_page(struct page *page); +-void dax_unlock_page(struct page *page, dax_entry_t cookie); ++dax_entry_t dax_lock_folio(struct folio *folio); ++void dax_unlock_folio(struct folio *folio, dax_entry_t cookie); + dax_entry_t dax_lock_mapping_entry(struct address_space *mapping, + unsigned long index, struct page **page); + void dax_unlock_mapping_entry(struct address_space *mapping, +@@ -182,14 +182,14 @@ static inline int dax_writeback_mapping_range(struct address_space *mapping, + return -EOPNOTSUPP; + } + +-static inline dax_entry_t dax_lock_page(struct page *page) ++static inline dax_entry_t dax_lock_folio(struct folio *folio) + { +- if (IS_DAX(page->mapping->host)) ++ if (IS_DAX(folio->mapping->host)) + return ~0UL; + return 0; + } + +-static inline void dax_unlock_page(struct page *page, dax_entry_t cookie) ++static inline void dax_unlock_folio(struct folio *folio, dax_entry_t cookie) + { + } + +diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h +index 9da4f3f1e6d61..7262c9993c39c 100644 +--- a/include/linux/hisi_acc_qm.h ++++ b/include/linux/hisi_acc_qm.h +@@ -276,6 +276,7 @@ struct hisi_qm_poll_data { + struct hisi_qm *qm; + struct work_struct work; + u16 *qp_finish_id; ++ u16 eqe_num; + }; + + /** +diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h +index 947973623dc77..60a7d0ce30804 100644 +--- a/include/net/netfilter/nf_tables_ipv4.h ++++ b/include/net/netfilter/nf_tables_ipv4.h +@@ -30,7 +30,7 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt) + return -1; + + len = iph_totlen(pkt->skb, iph); +- thoff = iph->ihl * 4; ++ thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4); + if (pkt->skb->len < len) + return -1; + else if (len < thoff) +diff --git a/include/net/sock.h b/include/net/sock.h +index 1b7ca8f35dd60..70a771d964676 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2152,14 +2152,14 @@ static inline bool sk_rethink_txhash(struct sock *sk) + } + + static inline struct dst_entry * +-__sk_dst_get(struct sock *sk) ++__sk_dst_get(const struct sock *sk) + { + return rcu_dereference_check(sk->sk_dst_cache, + lockdep_sock_is_held(sk)); + } + + static inline struct dst_entry * +-sk_dst_get(struct sock *sk) ++sk_dst_get(const struct sock *sk) + { + struct dst_entry *dst; + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index a88bf8f6db235..9cbcfb3c95dac 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -723,6 +723,8 @@ static inline void tcp_fast_path_check(struct sock *sk) + tcp_fast_path_on(tp); + } + ++u32 tcp_delack_max(const struct sock *sk); ++ + /* Compute the actual rto_min value */ + static inline u32 tcp_rto_min(struct sock *sk) + { +diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h +index 1617af3801620..69b472604b86f 100644 +--- a/include/net/xdp_sock.h ++++ b/include/net/xdp_sock.h +@@ -14,6 +14,8 @@ + #include <linux/mm.h> + #include <net/sock.h> + ++#define XDP_UMEM_SG_FLAG (1 << 1) ++ + struct net_device; + struct xsk_queue; + struct xdp_buff; +diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h +index 98e13be411afd..3d1851f82dbb6 100644 +--- a/kernel/rcu/rcu.h ++++ b/kernel/rcu/rcu.h +@@ -493,6 +493,7 @@ static inline void rcu_expedite_gp(void) { } + static inline void rcu_unexpedite_gp(void) { } + static inline void rcu_async_hurry(void) { } + static inline void rcu_async_relax(void) { } ++static inline bool rcu_cpu_online(int cpu) { return true; } + #else /* #ifdef CONFIG_TINY_RCU */ + bool rcu_gp_is_normal(void); /* Internal RCU use. */ + bool rcu_gp_is_expedited(void); /* Internal RCU use. */ +@@ -502,6 +503,7 @@ void rcu_unexpedite_gp(void); + void rcu_async_hurry(void); + void rcu_async_relax(void); + void rcupdate_announce_bootup_oddness(void); ++bool rcu_cpu_online(int cpu); + #ifdef CONFIG_TASKS_RCU_GENERIC + void show_rcu_tasks_gp_kthreads(void); + #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ +diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h +index 8d65f7d576a34..65e000ca332cc 100644 +--- a/kernel/rcu/tasks.h ++++ b/kernel/rcu/tasks.h +@@ -892,10 +892,36 @@ static void rcu_tasks_pregp_step(struct list_head *hop) + synchronize_rcu(); + } + ++/* Check for quiescent states since the pregp's synchronize_rcu() */ ++static bool rcu_tasks_is_holdout(struct task_struct *t) ++{ ++ int cpu; ++ ++ /* Has the task been seen voluntarily sleeping? */ ++ if (!READ_ONCE(t->on_rq)) ++ return false; ++ ++ /* ++ * Idle tasks (or idle injection) within the idle loop are RCU-tasks ++ * quiescent states. But CPU boot code performed by the idle task ++ * isn't a quiescent state. ++ */ ++ if (is_idle_task(t)) ++ return false; ++ ++ cpu = task_cpu(t); ++ ++ /* Idle tasks on offline CPUs are RCU-tasks quiescent states. */ ++ if (t == idle_task(cpu) && !rcu_cpu_online(cpu)) ++ return false; ++ ++ return true; ++} ++ + /* Per-task initial processing. */ + static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop) + { +- if (t != current && READ_ONCE(t->on_rq) && !is_idle_task(t)) { ++ if (t != current && rcu_tasks_is_holdout(t)) { + get_task_struct(t); + t->rcu_tasks_nvcsw = READ_ONCE(t->nvcsw); + WRITE_ONCE(t->rcu_tasks_holdout, true); +@@ -944,7 +970,7 @@ static void check_holdout_task(struct task_struct *t, + + if (!READ_ONCE(t->rcu_tasks_holdout) || + t->rcu_tasks_nvcsw != READ_ONCE(t->nvcsw) || +- !READ_ONCE(t->on_rq) || ++ !rcu_tasks_is_holdout(t) || + (IS_ENABLED(CONFIG_NO_HZ_FULL) && + !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) { + WRITE_ONCE(t->rcu_tasks_holdout, false); +@@ -1522,7 +1548,7 @@ static int trc_inspect_reader(struct task_struct *t, void *bhp_in) + } else { + // The task is not running, so C-language access is safe. + nesting = t->trc_reader_nesting; +- WARN_ON_ONCE(ofl && task_curr(t) && !is_idle_task(t)); ++ WARN_ON_ONCE(ofl && task_curr(t) && (t != idle_task(task_cpu(t)))); + if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB) && ofl) + n_heavy_reader_ofl_updates++; + } +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 7b4517dc46579..9af42eae1ba38 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -755,14 +755,19 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp) + } + + /* +- * Return true if the specified CPU has passed through a quiescent +- * state by virtue of being in or having passed through an dynticks +- * idle state since the last call to dyntick_save_progress_counter() +- * for this same CPU, or by virtue of having been offline. ++ * Returns positive if the specified CPU has passed through a quiescent state ++ * by virtue of being in or having passed through an dynticks idle state since ++ * the last call to dyntick_save_progress_counter() for this same CPU, or by ++ * virtue of having been offline. ++ * ++ * Returns negative if the specified CPU needs a force resched. ++ * ++ * Returns zero otherwise. + */ + static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) + { + unsigned long jtsq; ++ int ret = 0; + struct rcu_node *rnp = rdp->mynode; + + /* +@@ -848,8 +853,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) + (time_after(jiffies, READ_ONCE(rdp->last_fqs_resched) + jtsq * 3) || + rcu_state.cbovld)) { + WRITE_ONCE(rdp->rcu_urgent_qs, true); +- resched_cpu(rdp->cpu); + WRITE_ONCE(rdp->last_fqs_resched, jiffies); ++ ret = -1; + } + + /* +@@ -862,8 +867,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) + if (time_after(jiffies, rcu_state.jiffies_resched)) { + if (time_after(jiffies, + READ_ONCE(rdp->last_fqs_resched) + jtsq)) { +- resched_cpu(rdp->cpu); + WRITE_ONCE(rdp->last_fqs_resched, jiffies); ++ ret = -1; + } + if (IS_ENABLED(CONFIG_IRQ_WORK) && + !rdp->rcu_iw_pending && rdp->rcu_iw_gp_seq != rnp->gp_seq && +@@ -892,7 +897,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) + } + } + +- return 0; ++ return ret; + } + + /* Trace-event wrapper function for trace_rcu_future_grace_period. */ +@@ -2270,15 +2275,15 @@ static void force_qs_rnp(int (*f)(struct rcu_data *rdp)) + { + int cpu; + unsigned long flags; +- unsigned long mask; +- struct rcu_data *rdp; + struct rcu_node *rnp; + + rcu_state.cbovld = rcu_state.cbovldnext; + rcu_state.cbovldnext = false; + rcu_for_each_leaf_node(rnp) { ++ unsigned long mask = 0; ++ unsigned long rsmask = 0; ++ + cond_resched_tasks_rcu_qs(); +- mask = 0; + raw_spin_lock_irqsave_rcu_node(rnp, flags); + rcu_state.cbovldnext |= !!rnp->cbovldmask; + if (rnp->qsmask == 0) { +@@ -2296,11 +2301,17 @@ static void force_qs_rnp(int (*f)(struct rcu_data *rdp)) + continue; + } + for_each_leaf_node_cpu_mask(rnp, cpu, rnp->qsmask) { ++ struct rcu_data *rdp; ++ int ret; ++ + rdp = per_cpu_ptr(&rcu_data, cpu); +- if (f(rdp)) { ++ ret = f(rdp); ++ if (ret > 0) { + mask |= rdp->grpmask; + rcu_disable_urgency_upon_qs(rdp); + } ++ if (ret < 0) ++ rsmask |= rdp->grpmask; + } + if (mask != 0) { + /* Idle/offline CPUs, report (releases rnp->lock). */ +@@ -2309,6 +2320,9 @@ static void force_qs_rnp(int (*f)(struct rcu_data *rdp)) + /* Nothing to do here, so just drop the lock. */ + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + } ++ ++ for_each_leaf_node_cpu_mask(rnp, cpu, rsmask) ++ resched_cpu(cpu); + } + } + +@@ -4125,6 +4139,13 @@ static bool rcu_rdp_cpu_online(struct rcu_data *rdp) + return !!(rdp->grpmask & rcu_rnp_online_cpus(rdp->mynode)); + } + ++bool rcu_cpu_online(int cpu) ++{ ++ struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); ++ ++ return rcu_rdp_cpu_online(rdp); ++} ++ + #if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU) + + /* +diff --git a/kernel/resource.c b/kernel/resource.c +index b1763b2fd7ef3..e3f5680a564cf 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -1847,8 +1847,8 @@ get_free_mem_region(struct device *dev, struct resource *base, + + write_lock(&resource_lock); + for (addr = gfr_start(base, size, align, flags); +- gfr_continue(base, addr, size, flags); +- addr = gfr_next(addr, size, flags)) { ++ gfr_continue(base, addr, align, flags); ++ addr = gfr_next(addr, align, flags)) { + if (__region_intersects(base, addr, size, 0, IORES_DESC_NONE) != + REGION_DISJOINT) + continue; +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 16e002e08cf8f..455093f73a70c 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -595,10 +595,9 @@ struct task_struct *task_early_kill(struct task_struct *tsk, int force_early) + /* + * Collect processes when the error hit an anonymous page. + */ +-static void collect_procs_anon(struct page *page, struct list_head *to_kill, +- int force_early) ++static void collect_procs_anon(struct folio *folio, struct page *page, ++ struct list_head *to_kill, int force_early) + { +- struct folio *folio = page_folio(page); + struct vm_area_struct *vma; + struct task_struct *tsk; + struct anon_vma *av; +@@ -633,12 +632,12 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, + /* + * Collect processes when the error hit a file mapped page. + */ +-static void collect_procs_file(struct page *page, struct list_head *to_kill, +- int force_early) ++static void collect_procs_file(struct folio *folio, struct page *page, ++ struct list_head *to_kill, int force_early) + { + struct vm_area_struct *vma; + struct task_struct *tsk; +- struct address_space *mapping = page->mapping; ++ struct address_space *mapping = folio->mapping; + pgoff_t pgoff; + + i_mmap_lock_read(mapping); +@@ -704,17 +703,17 @@ static void collect_procs_fsdax(struct page *page, + /* + * Collect the processes who have the corrupted page mapped to kill. + */ +-static void collect_procs(struct page *page, struct list_head *tokill, +- int force_early) ++static void collect_procs(struct folio *folio, struct page *page, ++ struct list_head *tokill, int force_early) + { +- if (!page->mapping) ++ if (!folio->mapping) + return; + if (unlikely(PageKsm(page))) + collect_procs_ksm(page, tokill, force_early); + else if (PageAnon(page)) +- collect_procs_anon(page, tokill, force_early); ++ collect_procs_anon(folio, page, tokill, force_early); + else +- collect_procs_file(page, tokill, force_early); ++ collect_procs_file(folio, page, tokill, force_early); + } + + struct hwpoison_walk { +@@ -1602,7 +1601,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, + * mapped in dirty form. This has to be done before try_to_unmap, + * because ttu takes the rmap data structures down. + */ +- collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); ++ collect_procs(folio, p, &tokill, flags & MF_ACTION_REQUIRED); + + if (PageHuge(hpage) && !PageAnon(hpage)) { + /* +@@ -1713,20 +1712,23 @@ static void unmap_and_kill(struct list_head *to_kill, unsigned long pfn, + kill_procs(to_kill, flags & MF_MUST_KILL, false, pfn, flags); + } + ++/* ++ * Only dev_pagemap pages get here, such as fsdax when the filesystem ++ * either do not claim or fails to claim a hwpoison event, or devdax. ++ * The fsdax pages are initialized per base page, and the devdax pages ++ * could be initialized either as base pages, or as compound pages with ++ * vmemmap optimization enabled. Devdax is simplistic in its dealing with ++ * hwpoison, such that, if a subpage of a compound page is poisoned, ++ * simply mark the compound head page is by far sufficient. ++ */ + static int mf_generic_kill_procs(unsigned long long pfn, int flags, + struct dev_pagemap *pgmap) + { +- struct page *page = pfn_to_page(pfn); ++ struct folio *folio = pfn_folio(pfn); + LIST_HEAD(to_kill); + dax_entry_t cookie; + int rc = 0; + +- /* +- * Pages instantiated by device-dax (not filesystem-dax) +- * may be compound pages. +- */ +- page = compound_head(page); +- + /* + * Prevent the inode from being freed while we are interrogating + * the address_space, typically this would be handled by +@@ -1734,11 +1736,11 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags, + * also prevents changes to the mapping of this pfn until + * poison signaling is complete. + */ +- cookie = dax_lock_page(page); ++ cookie = dax_lock_folio(folio); + if (!cookie) + return -EBUSY; + +- if (hwpoison_filter(page)) { ++ if (hwpoison_filter(&folio->page)) { + rc = -EOPNOTSUPP; + goto unlock; + } +@@ -1760,7 +1762,7 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags, + * Use this flag as an indication that the dax page has been + * remapped UC to prevent speculative consumption of poison. + */ +- SetPageHWPoison(page); ++ SetPageHWPoison(&folio->page); + + /* + * Unlike System-RAM there is no possibility to swap in a +@@ -1769,11 +1771,11 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags, + * SIGBUS (i.e. MF_MUST_KILL) + */ + flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; +- collect_procs(page, &to_kill, true); ++ collect_procs(folio, &folio->page, &to_kill, true); + +- unmap_and_kill(&to_kill, pfn, page->mapping, page->index, flags); ++ unmap_and_kill(&to_kill, pfn, folio->mapping, folio->index, flags); + unlock: +- dax_unlock_page(page, cookie); ++ dax_unlock_folio(folio, cookie); + return rc; + } + +diff --git a/mm/memory.c b/mm/memory.c +index 517221f013035..dccf9203dd536 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -3565,8 +3565,8 @@ EXPORT_SYMBOL_GPL(unmap_mapping_pages); + void unmap_mapping_range(struct address_space *mapping, + loff_t const holebegin, loff_t const holelen, int even_cows) + { +- pgoff_t hba = holebegin >> PAGE_SHIFT; +- pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ pgoff_t hba = (pgoff_t)(holebegin) >> PAGE_SHIFT; ++ pgoff_t hlen = ((pgoff_t)(holelen) + PAGE_SIZE - 1) >> PAGE_SHIFT; + + /* Check for overflow. */ + if (sizeof(holelen) > sizeof(hlen)) { +diff --git a/mm/vmscan.c b/mm/vmscan.c +index dcc264d3c92f2..0dfb9a75dfa6d 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4656,6 +4656,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) + int young = 0; + pte_t *pte = pvmw->pte; + unsigned long addr = pvmw->address; ++ struct vm_area_struct *vma = pvmw->vma; + struct folio *folio = pfn_folio(pvmw->pfn); + bool can_swap = !folio_is_file_lru(folio); + struct mem_cgroup *memcg = folio_memcg(folio); +@@ -4670,11 +4671,15 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) + if (spin_is_contended(pvmw->ptl)) + return; + ++ /* exclude special VMAs containing anon pages from COW */ ++ if (vma->vm_flags & VM_SPECIAL) ++ return; ++ + /* avoid taking the LRU lock under the PTL when possible */ + walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; + +- start = max(addr & PMD_MASK, pvmw->vma->vm_start); +- end = min(addr | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; ++ start = max(addr & PMD_MASK, vma->vm_start); ++ end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1; + + if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { + if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2) +@@ -4699,7 +4704,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) + unsigned long pfn; + pte_t ptent = ptep_get(pte + i); + +- pfn = get_pte_pfn(ptent, pvmw->vma, addr); ++ pfn = get_pte_pfn(ptent, vma, addr); + if (pfn == -1) + continue; + +@@ -4710,7 +4715,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) + if (!folio) + continue; + +- if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) ++ if (!ptep_test_and_clear_young(vma, addr, pte + i)) + VM_WARN_ON_ONCE(true); + + young++; +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 6d204cf54c574..011d69029112a 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -4508,8 +4508,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, + /* GSO partial only requires that we trim off any excess that + * doesn't fit into an MSS sized block, so take care of that + * now. ++ * Cap len to not accidentally hit GSO_BY_FRAGS. + */ +- partial_segs = len / mss; ++ partial_segs = min(len, GSO_BY_FRAGS - 1U) / mss; + if (partial_segs > 1) + mss *= partial_segs; + else +diff --git a/net/core/sock.c b/net/core/sock.c +index bfaf47b3f3c7c..5cd21e699f2d6 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1718,9 +1718,16 @@ int sk_getsockopt(struct sock *sk, int level, int optname, + break; + + case SO_TIMESTAMPING_OLD: ++ case SO_TIMESTAMPING_NEW: + lv = sizeof(v.timestamping); +- v.timestamping.flags = READ_ONCE(sk->sk_tsflags); +- v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc); ++ /* For the later-added case SO_TIMESTAMPING_NEW: Be strict about only ++ * returning the flags when they were set through the same option. ++ * Don't change the beviour for the old case SO_TIMESTAMPING_OLD. ++ */ ++ if (optname == SO_TIMESTAMPING_OLD || sock_flag(sk, SOCK_TSTAMP_NEW)) { ++ v.timestamping.flags = READ_ONCE(sk->sk_tsflags); ++ v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc); ++ } + break; + + case SO_RCVTIMEO_OLD: +@@ -2821,6 +2828,7 @@ int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg, + sockc->mark = *(u32 *)CMSG_DATA(cmsg); + break; + case SO_TIMESTAMPING_OLD: ++ case SO_TIMESTAMPING_NEW: + if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32))) + return -EINVAL; + +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index 2a6d363763a2b..f18ca02aa95a6 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -91,8 +91,6 @@ const struct cred *dns_resolver_cache; + static int + dns_resolver_preparse(struct key_preparsed_payload *prep) + { +- const struct dns_server_list_v1_header *v1; +- const struct dns_payload_header *bin; + struct user_key_payload *upayload; + unsigned long derrno; + int ret; +@@ -103,27 +101,28 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) + return -EINVAL; + + if (data[0] == 0) { ++ const struct dns_server_list_v1_header *v1; ++ + /* It may be a server list. */ +- if (datalen <= sizeof(*bin)) ++ if (datalen <= sizeof(*v1)) + return -EINVAL; + +- bin = (const struct dns_payload_header *)data; +- kenter("[%u,%u],%u", bin->content, bin->version, datalen); +- if (bin->content != DNS_PAYLOAD_IS_SERVER_LIST) { ++ v1 = (const struct dns_server_list_v1_header *)data; ++ kenter("[%u,%u],%u", v1->hdr.content, v1->hdr.version, datalen); ++ if (v1->hdr.content != DNS_PAYLOAD_IS_SERVER_LIST) { + pr_warn_ratelimited( + "dns_resolver: Unsupported content type (%u)\n", +- bin->content); ++ v1->hdr.content); + return -EINVAL; + } + +- if (bin->version != 1) { ++ if (v1->hdr.version != 1) { + pr_warn_ratelimited( + "dns_resolver: Unsupported server list version (%u)\n", +- bin->version); ++ v1->hdr.version); + return -EINVAL; + } + +- v1 = (const struct dns_server_list_v1_header *)bin; + if ((v1->status != DNS_LOOKUP_GOOD && + v1->status != DNS_LOOKUP_GOOD_WITH_BAD)) { + if (prep->expiry == TIME64_MAX) +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index ec46d74c20938..f124f6c639157 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3774,7 +3774,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) + info->tcpi_options |= TCPI_OPT_SYN_DATA; + + info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); +- info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); ++ info->tcpi_ato = jiffies_to_usecs(min(icsk->icsk_ack.ato, ++ tcp_delack_max(sk))); + info->tcpi_snd_mss = tp->mss_cache; + info->tcpi_rcv_mss = icsk->icsk_ack.rcv_mss; + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index cab3c1162c3a6..ab3b7b4b4429b 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -4003,6 +4003,20 @@ int tcp_connect(struct sock *sk) + } + EXPORT_SYMBOL(tcp_connect); + ++u32 tcp_delack_max(const struct sock *sk) ++{ ++ const struct dst_entry *dst = __sk_dst_get(sk); ++ u32 delack_max = inet_csk(sk)->icsk_delack_max; ++ ++ if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) { ++ u32 rto_min = dst_metric_rtt(dst, RTAX_RTO_MIN); ++ u32 delack_from_rto_min = max_t(int, 1, rto_min - 1); ++ ++ delack_max = min_t(u32, delack_max, delack_from_rto_min); ++ } ++ return delack_max; ++} ++ + /* Send out a delayed ack, the caller does the policy checking + * to see if we should even be here. See tcp_input.c:tcp_ack_snd_check() + * for details. +@@ -4038,7 +4052,7 @@ void tcp_send_delayed_ack(struct sock *sk) + ato = min(ato, max_ato); + } + +- ato = min_t(u32, ato, inet_csk(sk)->icsk_delack_max); ++ ato = min_t(u32, ato, tcp_delack_max(sk)); + + /* Stay within the limit we were given */ + timeout = jiffies + ato; +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index f3a1e4aa0e5eb..45b8115b363bc 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -1974,6 +1974,17 @@ static void tcp_release_cb_override(struct sock *ssk) + tcp_release_cb(ssk); + } + ++static int tcp_abort_override(struct sock *ssk, int err) ++{ ++ /* closing a listener subflow requires a great deal of care. ++ * keep it simple and just prevent such operation ++ */ ++ if (inet_sk_state_load(ssk) == TCP_LISTEN) ++ return -EINVAL; ++ ++ return tcp_abort(ssk, err); ++} ++ + static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = { + .name = "mptcp", + .owner = THIS_MODULE, +@@ -2018,6 +2029,7 @@ void __init mptcp_subflow_init(void) + + tcp_prot_override = tcp_prot; + tcp_prot_override.release_cb = tcp_release_cb_override; ++ tcp_prot_override.diag_destroy = tcp_abort_override; + + #if IS_ENABLED(CONFIG_MPTCP_IPV6) + /* In struct mptcp_subflow_request_sock, we assume the TCP request sock +@@ -2054,6 +2066,7 @@ void __init mptcp_subflow_init(void) + + tcpv6_prot_override = tcpv6_prot; + tcpv6_prot_override.release_cb = tcp_release_cb_override; ++ tcpv6_prot_override.diag_destroy = tcp_abort_override; + #endif + + mptcp_diag_subflow_init(&subflow_ulp_ops); +diff --git a/net/netfilter/nf_nat_ovs.c b/net/netfilter/nf_nat_ovs.c +index 551abd2da6143..0f9a559f62079 100644 +--- a/net/netfilter/nf_nat_ovs.c ++++ b/net/netfilter/nf_nat_ovs.c +@@ -75,9 +75,10 @@ static int nf_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, + } + + err = nf_nat_packet(ct, ctinfo, hooknum, skb); ++out: + if (err == NF_ACCEPT) + *action |= BIT(maniptype); +-out: ++ + return err; + } + +diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c +index 4d0ce12221f66..711c22ab701dd 100644 +--- a/net/netfilter/nf_tables_core.c ++++ b/net/netfilter/nf_tables_core.c +@@ -158,7 +158,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr, + else { + if (!(pkt->flags & NFT_PKTINFO_L4PROTO)) + return false; +- ptr = skb_network_header(skb) + nft_thoff(pkt); ++ ptr = skb->data + nft_thoff(pkt); + } + + ptr += priv->offset; +diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c +index fccb3cf7749c1..6475c7abc1fe3 100644 +--- a/net/netfilter/nft_immediate.c ++++ b/net/netfilter/nft_immediate.c +@@ -78,7 +78,7 @@ static int nft_immediate_init(const struct nft_ctx *ctx, + case NFT_GOTO: + err = nf_tables_bind_chain(ctx, chain); + if (err < 0) +- return err; ++ goto err1; + break; + default: + break; +diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c +index 1dac28136e6a3..18be13fb9b75a 100644 +--- a/net/nfc/llcp_core.c ++++ b/net/nfc/llcp_core.c +@@ -145,6 +145,13 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, + + static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) + { ++ /* Since using nfc_llcp_local may result in usage of nfc_dev, whenever ++ * we hold a reference to local, we also need to hold a reference to ++ * the device to avoid UAF. ++ */ ++ if (!nfc_get_device(local->dev->idx)) ++ return NULL; ++ + kref_get(&local->ref); + + return local; +@@ -177,10 +184,18 @@ static void local_release(struct kref *ref) + + int nfc_llcp_local_put(struct nfc_llcp_local *local) + { ++ struct nfc_dev *dev; ++ int ret; ++ + if (local == NULL) + return 0; + +- return kref_put(&local->ref, local_release); ++ dev = local->dev; ++ ++ ret = kref_put(&local->ref, local_release); ++ nfc_put_device(dev); ++ ++ return ret; + } + + static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, +@@ -959,8 +974,17 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, + } + + new_sock = nfc_llcp_sock(new_sk); +- new_sock->dev = local->dev; ++ + new_sock->local = nfc_llcp_local_get(local); ++ if (!new_sock->local) { ++ reason = LLCP_DM_REJ; ++ sock_put(&new_sock->sk); ++ release_sock(&sock->sk); ++ sock_put(&sock->sk); ++ goto fail; ++ } ++ ++ new_sock->dev = local->dev; + new_sock->rw = sock->rw; + new_sock->miux = sock->miux; + new_sock->nfc_protocol = sock->nfc_protocol; +@@ -1597,7 +1621,16 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) + if (local == NULL) + return -ENOMEM; + +- local->dev = ndev; ++ /* As we are going to initialize local's refcount, we need to get the ++ * nfc_dev to avoid UAF, otherwise there is no point in continuing. ++ * See nfc_llcp_local_get(). ++ */ ++ local->dev = nfc_get_device(ndev->idx); ++ if (!local->dev) { ++ kfree(local); ++ return -ENODEV; ++ } ++ + INIT_LIST_HEAD(&local->list); + kref_init(&local->ref); + mutex_init(&local->sdp_lock); +diff --git a/net/sched/em_text.c b/net/sched/em_text.c +index 6f3c1fb2fb44c..f176afb70559e 100644 +--- a/net/sched/em_text.c ++++ b/net/sched/em_text.c +@@ -97,8 +97,10 @@ retry: + + static void em_text_destroy(struct tcf_ematch *m) + { +- if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) ++ if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) { + textsearch_destroy(EM_TEXT_PRIV(m)->config); ++ kfree(EM_TEXT_PRIV(m)); ++ } + } + + static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) +diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c +index 7ff2152971a5b..2c464d76b06ce 100644 +--- a/net/smc/smc_diag.c ++++ b/net/smc/smc_diag.c +@@ -153,8 +153,7 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb, + .lnk[0].link_id = link->link_id, + }; + +- memcpy(linfo.lnk[0].ibname, +- smc->conn.lgr->lnk[0].smcibdev->ibdev->name, ++ memcpy(linfo.lnk[0].ibname, link->smcibdev->ibdev->name, + sizeof(link->smcibdev->ibdev->name)); + smc_gid_be16_convert(linfo.lnk[0].gid, link->gid); + smc_gid_be16_convert(linfo.lnk[0].peer_gid, link->peer_gid); +diff --git a/net/socket.c b/net/socket.c +index c4a6f55329552..8d83c4bb163b4 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -757,6 +757,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) + { + struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; + struct sockaddr_storage address; ++ int save_len = msg->msg_namelen; + int ret; + + if (msg->msg_name) { +@@ -766,6 +767,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) + + ret = __sock_sendmsg(sock, msg); + msg->msg_name = save_addr; ++ msg->msg_namelen = save_len; + + return ret; + } +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index 3515e19852d88..774a6d1916e40 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -1227,7 +1227,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) + + xs->dev = dev; + xs->zc = xs->umem->zc; +- xs->sg = !!(flags & XDP_USE_SG); ++ xs->sg = !!(xs->umem->flags & XDP_UMEM_SG_FLAG); + xs->queue_id = qid; + xp_add_xsk(xs->pool, xs); + +diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c +index b3f7b310811ed..49cb9f9a09bee 100644 +--- a/net/xdp/xsk_buff_pool.c ++++ b/net/xdp/xsk_buff_pool.c +@@ -170,6 +170,9 @@ int xp_assign_dev(struct xsk_buff_pool *pool, + if (err) + return err; + ++ if (flags & XDP_USE_SG) ++ pool->umem->flags |= XDP_UMEM_SG_FLAG; ++ + if (flags & XDP_USE_NEED_WAKEUP) + pool->uses_need_wakeup = true; + /* Tx needs to be explicitly woken up the first time. Also +diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c +index 5af00387c519e..245db52bedf29 100644 +--- a/samples/vfio-mdev/mtty.c ++++ b/samples/vfio-mdev/mtty.c +@@ -127,7 +127,6 @@ struct serial_port { + /* State of each mdev device */ + struct mdev_state { + struct vfio_device vdev; +- int irq_fd; + struct eventfd_ctx *intx_evtfd; + struct eventfd_ctx *msi_evtfd; + int irq_index; +@@ -141,6 +140,7 @@ struct mdev_state { + struct mutex rxtx_lock; + struct vfio_device_info dev_info; + int nr_ports; ++ u8 intx_mask:1; + }; + + static struct mtty_type { +@@ -166,10 +166,6 @@ static const struct file_operations vd_fops = { + + static const struct vfio_device_ops mtty_dev_ops; + +-/* function prototypes */ +- +-static int mtty_trigger_interrupt(struct mdev_state *mdev_state); +- + /* Helper functions */ + + static void dump_buffer(u8 *buf, uint32_t count) +@@ -186,6 +182,36 @@ static void dump_buffer(u8 *buf, uint32_t count) + #endif + } + ++static bool is_intx(struct mdev_state *mdev_state) ++{ ++ return mdev_state->irq_index == VFIO_PCI_INTX_IRQ_INDEX; ++} ++ ++static bool is_msi(struct mdev_state *mdev_state) ++{ ++ return mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX; ++} ++ ++static bool is_noirq(struct mdev_state *mdev_state) ++{ ++ return !is_intx(mdev_state) && !is_msi(mdev_state); ++} ++ ++static void mtty_trigger_interrupt(struct mdev_state *mdev_state) ++{ ++ lockdep_assert_held(&mdev_state->ops_lock); ++ ++ if (is_msi(mdev_state)) { ++ if (mdev_state->msi_evtfd) ++ eventfd_signal(mdev_state->msi_evtfd, 1); ++ } else if (is_intx(mdev_state)) { ++ if (mdev_state->intx_evtfd && !mdev_state->intx_mask) { ++ eventfd_signal(mdev_state->intx_evtfd, 1); ++ mdev_state->intx_mask = true; ++ } ++ } ++} ++ + static void mtty_create_config_space(struct mdev_state *mdev_state) + { + /* PCI dev ID */ +@@ -921,6 +947,25 @@ write_err: + return -EFAULT; + } + ++static void mtty_disable_intx(struct mdev_state *mdev_state) ++{ ++ if (mdev_state->intx_evtfd) { ++ eventfd_ctx_put(mdev_state->intx_evtfd); ++ mdev_state->intx_evtfd = NULL; ++ mdev_state->intx_mask = false; ++ mdev_state->irq_index = -1; ++ } ++} ++ ++static void mtty_disable_msi(struct mdev_state *mdev_state) ++{ ++ if (mdev_state->msi_evtfd) { ++ eventfd_ctx_put(mdev_state->msi_evtfd); ++ mdev_state->msi_evtfd = NULL; ++ mdev_state->irq_index = -1; ++ } ++} ++ + static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags, + unsigned int index, unsigned int start, + unsigned int count, void *data) +@@ -932,59 +977,113 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags, + case VFIO_PCI_INTX_IRQ_INDEX: + switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) { + case VFIO_IRQ_SET_ACTION_MASK: ++ if (!is_intx(mdev_state) || start != 0 || count != 1) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (flags & VFIO_IRQ_SET_DATA_NONE) { ++ mdev_state->intx_mask = true; ++ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { ++ uint8_t mask = *(uint8_t *)data; ++ ++ if (mask) ++ mdev_state->intx_mask = true; ++ } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { ++ ret = -ENOTTY; /* No support for mask fd */ ++ } ++ break; + case VFIO_IRQ_SET_ACTION_UNMASK: ++ if (!is_intx(mdev_state) || start != 0 || count != 1) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (flags & VFIO_IRQ_SET_DATA_NONE) { ++ mdev_state->intx_mask = false; ++ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { ++ uint8_t mask = *(uint8_t *)data; ++ ++ if (mask) ++ mdev_state->intx_mask = false; ++ } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { ++ ret = -ENOTTY; /* No support for unmask fd */ ++ } + break; + case VFIO_IRQ_SET_ACTION_TRIGGER: +- { +- if (flags & VFIO_IRQ_SET_DATA_NONE) { +- pr_info("%s: disable INTx\n", __func__); +- if (mdev_state->intx_evtfd) +- eventfd_ctx_put(mdev_state->intx_evtfd); ++ if (is_intx(mdev_state) && !count && ++ (flags & VFIO_IRQ_SET_DATA_NONE)) { ++ mtty_disable_intx(mdev_state); ++ break; ++ } ++ ++ if (!(is_intx(mdev_state) || is_noirq(mdev_state)) || ++ start != 0 || count != 1) { ++ ret = -EINVAL; + break; + } + + if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { + int fd = *(int *)data; ++ struct eventfd_ctx *evt; ++ ++ mtty_disable_intx(mdev_state); ++ ++ if (fd < 0) ++ break; + +- if (fd > 0) { +- struct eventfd_ctx *evt; +- +- evt = eventfd_ctx_fdget(fd); +- if (IS_ERR(evt)) { +- ret = PTR_ERR(evt); +- break; +- } +- mdev_state->intx_evtfd = evt; +- mdev_state->irq_fd = fd; +- mdev_state->irq_index = index; ++ evt = eventfd_ctx_fdget(fd); ++ if (IS_ERR(evt)) { ++ ret = PTR_ERR(evt); + break; + } ++ mdev_state->intx_evtfd = evt; ++ mdev_state->irq_index = index; ++ break; ++ } ++ ++ if (!is_intx(mdev_state)) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (flags & VFIO_IRQ_SET_DATA_NONE) { ++ mtty_trigger_interrupt(mdev_state); ++ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { ++ uint8_t trigger = *(uint8_t *)data; ++ ++ if (trigger) ++ mtty_trigger_interrupt(mdev_state); + } + break; + } +- } + break; + case VFIO_PCI_MSI_IRQ_INDEX: + switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) { + case VFIO_IRQ_SET_ACTION_MASK: + case VFIO_IRQ_SET_ACTION_UNMASK: ++ ret = -ENOTTY; + break; + case VFIO_IRQ_SET_ACTION_TRIGGER: +- if (flags & VFIO_IRQ_SET_DATA_NONE) { +- if (mdev_state->msi_evtfd) +- eventfd_ctx_put(mdev_state->msi_evtfd); +- pr_info("%s: disable MSI\n", __func__); +- mdev_state->irq_index = VFIO_PCI_INTX_IRQ_INDEX; ++ if (is_msi(mdev_state) && !count && ++ (flags & VFIO_IRQ_SET_DATA_NONE)) { ++ mtty_disable_msi(mdev_state); + break; + } ++ ++ if (!(is_msi(mdev_state) || is_noirq(mdev_state)) || ++ start != 0 || count != 1) { ++ ret = -EINVAL; ++ break; ++ } ++ + if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { + int fd = *(int *)data; + struct eventfd_ctx *evt; + +- if (fd <= 0) +- break; ++ mtty_disable_msi(mdev_state); + +- if (mdev_state->msi_evtfd) ++ if (fd < 0) + break; + + evt = eventfd_ctx_fdget(fd); +@@ -993,20 +1092,37 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags, + break; + } + mdev_state->msi_evtfd = evt; +- mdev_state->irq_fd = fd; + mdev_state->irq_index = index; ++ break; ++ } ++ ++ if (!is_msi(mdev_state)) { ++ ret = -EINVAL; ++ break; ++ } ++ ++ if (flags & VFIO_IRQ_SET_DATA_NONE) { ++ mtty_trigger_interrupt(mdev_state); ++ } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { ++ uint8_t trigger = *(uint8_t *)data; ++ ++ if (trigger) ++ mtty_trigger_interrupt(mdev_state); + } + break; +- } +- break; ++ } ++ break; + case VFIO_PCI_MSIX_IRQ_INDEX: +- pr_info("%s: MSIX_IRQ\n", __func__); ++ dev_dbg(mdev_state->vdev.dev, "%s: MSIX_IRQ\n", __func__); ++ ret = -ENOTTY; + break; + case VFIO_PCI_ERR_IRQ_INDEX: +- pr_info("%s: ERR_IRQ\n", __func__); ++ dev_dbg(mdev_state->vdev.dev, "%s: ERR_IRQ\n", __func__); ++ ret = -ENOTTY; + break; + case VFIO_PCI_REQ_IRQ_INDEX: +- pr_info("%s: REQ_IRQ\n", __func__); ++ dev_dbg(mdev_state->vdev.dev, "%s: REQ_IRQ\n", __func__); ++ ret = -ENOTTY; + break; + } + +@@ -1014,33 +1130,6 @@ static int mtty_set_irqs(struct mdev_state *mdev_state, uint32_t flags, + return ret; + } + +-static int mtty_trigger_interrupt(struct mdev_state *mdev_state) +-{ +- int ret = -1; +- +- if ((mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX) && +- (!mdev_state->msi_evtfd)) +- return -EINVAL; +- else if ((mdev_state->irq_index == VFIO_PCI_INTX_IRQ_INDEX) && +- (!mdev_state->intx_evtfd)) { +- pr_info("%s: Intr eventfd not found\n", __func__); +- return -EINVAL; +- } +- +- if (mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX) +- ret = eventfd_signal(mdev_state->msi_evtfd, 1); +- else +- ret = eventfd_signal(mdev_state->intx_evtfd, 1); +- +-#if defined(DEBUG_INTR) +- pr_info("Intx triggered\n"); +-#endif +- if (ret != 1) +- pr_err("%s: eventfd signal failed (%d)\n", __func__, ret); +- +- return ret; +-} +- + static int mtty_get_region_info(struct mdev_state *mdev_state, + struct vfio_region_info *region_info, + u16 *cap_type_id, void **cap_type) +@@ -1084,22 +1173,16 @@ static int mtty_get_region_info(struct mdev_state *mdev_state, + + static int mtty_get_irq_info(struct vfio_irq_info *irq_info) + { +- switch (irq_info->index) { +- case VFIO_PCI_INTX_IRQ_INDEX: +- case VFIO_PCI_MSI_IRQ_INDEX: +- case VFIO_PCI_REQ_IRQ_INDEX: +- break; +- +- default: ++ if (irq_info->index != VFIO_PCI_INTX_IRQ_INDEX && ++ irq_info->index != VFIO_PCI_MSI_IRQ_INDEX) + return -EINVAL; +- } + + irq_info->flags = VFIO_IRQ_INFO_EVENTFD; + irq_info->count = 1; + + if (irq_info->index == VFIO_PCI_INTX_IRQ_INDEX) +- irq_info->flags |= (VFIO_IRQ_INFO_MASKABLE | +- VFIO_IRQ_INFO_AUTOMASKED); ++ irq_info->flags |= VFIO_IRQ_INFO_MASKABLE | ++ VFIO_IRQ_INFO_AUTOMASKED; + else + irq_info->flags |= VFIO_IRQ_INFO_NORESIZE; + +@@ -1262,6 +1345,15 @@ static unsigned int mtty_get_available(struct mdev_type *mtype) + return atomic_read(&mdev_avail_ports) / type->nr_ports; + } + ++static void mtty_close(struct vfio_device *vdev) ++{ ++ struct mdev_state *mdev_state = ++ container_of(vdev, struct mdev_state, vdev); ++ ++ mtty_disable_intx(mdev_state); ++ mtty_disable_msi(mdev_state); ++} ++ + static const struct vfio_device_ops mtty_dev_ops = { + .name = "vfio-mtty", + .init = mtty_init_dev, +@@ -1273,6 +1365,7 @@ static const struct vfio_device_ops mtty_dev_ops = { + .unbind_iommufd = vfio_iommufd_emulated_unbind, + .attach_ioas = vfio_iommufd_emulated_attach_ioas, + .detach_ioas = vfio_iommufd_emulated_detach_ioas, ++ .close_device = mtty_close, + }; + + static struct mdev_driver mtty_driver = { +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index 261cef4c622fb..63ddefb6ddd1c 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -2364,6 +2364,7 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = { + + static struct aa_sfs_entry aa_sfs_entry_mount[] = { + AA_SFS_FILE_STRING("mask", "mount umount pivot_root"), ++ AA_SFS_FILE_STRING("move_mount", "detached"), + { } + }; + +diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c +index f2a114e540079..cb0fdbdb82d94 100644 +--- a/security/apparmor/mount.c ++++ b/security/apparmor/mount.c +@@ -499,6 +499,10 @@ int aa_move_mount(const struct cred *subj_cred, + error = -ENOMEM; + if (!to_buffer || !from_buffer) + goto out; ++ ++ if (!our_mnt(from_path->mnt)) ++ /* moving a mount detached from the namespace */ ++ from_path = NULL; + error = fn_for_each_confined(label, profile, + match_mnt(subj_cred, profile, to_path, to_buffer, + from_path, from_buffer, +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 343732c062c70..a9822d731ae0c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9709,6 +9709,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), ++ SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), +@@ -9791,6 +9792,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), +@@ -9835,6 +9837,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), +diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c +index 2fb1a7037c82c..731664fc8b217 100644 +--- a/sound/pci/hda/tas2781_hda_i2c.c ++++ b/sound/pci/hda/tas2781_hda_i2c.c +@@ -65,6 +65,15 @@ enum calib_data { + CALIB_MAX + }; + ++struct tas2781_hda { ++ struct device *dev; ++ struct tasdevice_priv *priv; ++ struct snd_kcontrol *dsp_prog_ctl; ++ struct snd_kcontrol *dsp_conf_ctl; ++ struct snd_kcontrol *prof_ctl; ++ struct snd_kcontrol *snd_ctls[3]; ++}; ++ + static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data) + { + struct tasdevice_priv *tas_priv = data; +@@ -125,26 +134,26 @@ err: + + static void tas2781_hda_playback_hook(struct device *dev, int action) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + +- dev_dbg(tas_priv->dev, "%s: action = %d\n", __func__, action); ++ dev_dbg(tas_hda->dev, "%s: action = %d\n", __func__, action); + switch (action) { + case HDA_GEN_PCM_ACT_OPEN: + pm_runtime_get_sync(dev); +- mutex_lock(&tas_priv->codec_lock); +- tasdevice_tuning_switch(tas_priv, 0); +- mutex_unlock(&tas_priv->codec_lock); ++ mutex_lock(&tas_hda->priv->codec_lock); ++ tasdevice_tuning_switch(tas_hda->priv, 0); ++ mutex_unlock(&tas_hda->priv->codec_lock); + break; + case HDA_GEN_PCM_ACT_CLOSE: +- mutex_lock(&tas_priv->codec_lock); +- tasdevice_tuning_switch(tas_priv, 1); +- mutex_unlock(&tas_priv->codec_lock); ++ mutex_lock(&tas_hda->priv->codec_lock); ++ tasdevice_tuning_switch(tas_hda->priv, 1); ++ mutex_unlock(&tas_hda->priv->codec_lock); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + break; + default: +- dev_dbg(tas_priv->dev, "Playback action not supported: %d\n", ++ dev_dbg(tas_hda->dev, "Playback action not supported: %d\n", + action); + break; + } +@@ -477,9 +486,28 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) + return 0; + } + ++static void tas2781_hda_remove_controls(struct tas2781_hda *tas_hda) ++{ ++ struct hda_codec *codec = tas_hda->priv->codec; ++ ++ if (tas_hda->dsp_prog_ctl) ++ snd_ctl_remove(codec->card, tas_hda->dsp_prog_ctl); ++ ++ if (tas_hda->dsp_conf_ctl) ++ snd_ctl_remove(codec->card, tas_hda->dsp_conf_ctl); ++ ++ for (int i = ARRAY_SIZE(tas_hda->snd_ctls) - 1; i >= 0; i--) ++ if (tas_hda->snd_ctls[i]) ++ snd_ctl_remove(codec->card, tas_hda->snd_ctls[i]); ++ ++ if (tas_hda->prof_ctl) ++ snd_ctl_remove(codec->card, tas_hda->prof_ctl); ++} ++ + static void tasdev_fw_ready(const struct firmware *fmw, void *context) + { + struct tasdevice_priv *tas_priv = context; ++ struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev); + struct hda_codec *codec = tas_priv->codec; + int i, ret; + +@@ -490,8 +518,8 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) + if (ret) + goto out; + +- ret = snd_ctl_add(codec->card, +- snd_ctl_new1(&tas2781_prof_ctrl, tas_priv)); ++ tas_hda->prof_ctl = snd_ctl_new1(&tas2781_prof_ctrl, tas_priv); ++ ret = snd_ctl_add(codec->card, tas_hda->prof_ctl); + if (ret) { + dev_err(tas_priv->dev, + "Failed to add KControl %s = %d\n", +@@ -500,8 +528,9 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) + } + + for (i = 0; i < ARRAY_SIZE(tas2781_snd_controls); i++) { +- ret = snd_ctl_add(codec->card, +- snd_ctl_new1(&tas2781_snd_controls[i], tas_priv)); ++ tas_hda->snd_ctls[i] = snd_ctl_new1(&tas2781_snd_controls[i], ++ tas_priv); ++ ret = snd_ctl_add(codec->card, tas_hda->snd_ctls[i]); + if (ret) { + dev_err(tas_priv->dev, + "Failed to add KControl %s = %d\n", +@@ -523,8 +552,9 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) + goto out; + } + +- ret = snd_ctl_add(codec->card, +- snd_ctl_new1(&tas2781_dsp_prog_ctrl, tas_priv)); ++ tas_hda->dsp_prog_ctl = snd_ctl_new1(&tas2781_dsp_prog_ctrl, ++ tas_priv); ++ ret = snd_ctl_add(codec->card, tas_hda->dsp_prog_ctl); + if (ret) { + dev_err(tas_priv->dev, + "Failed to add KControl %s = %d\n", +@@ -532,8 +562,9 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) + goto out; + } + +- ret = snd_ctl_add(codec->card, +- snd_ctl_new1(&tas2781_dsp_conf_ctrl, tas_priv)); ++ tas_hda->dsp_conf_ctl = snd_ctl_new1(&tas2781_dsp_conf_ctrl, ++ tas_priv); ++ ret = snd_ctl_add(codec->card, tas_hda->dsp_conf_ctl); + if (ret) { + dev_err(tas_priv->dev, + "Failed to add KControl %s = %d\n", +@@ -554,27 +585,27 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) + tas2781_save_calibration(tas_priv); + + out: +- mutex_unlock(&tas_priv->codec_lock); ++ mutex_unlock(&tas_hda->priv->codec_lock); + if (fmw) + release_firmware(fmw); +- pm_runtime_mark_last_busy(tas_priv->dev); +- pm_runtime_put_autosuspend(tas_priv->dev); ++ pm_runtime_mark_last_busy(tas_hda->dev); ++ pm_runtime_put_autosuspend(tas_hda->dev); + } + + static int tas2781_hda_bind(struct device *dev, struct device *master, + void *master_data) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + struct hda_component *comps = master_data; + struct hda_codec *codec; + unsigned int subid; + int ret; + +- if (!comps || tas_priv->index < 0 || +- tas_priv->index >= HDA_MAX_COMPONENTS) ++ if (!comps || tas_hda->priv->index < 0 || ++ tas_hda->priv->index >= HDA_MAX_COMPONENTS) + return -EINVAL; + +- comps = &comps[tas_priv->index]; ++ comps = &comps[tas_hda->priv->index]; + if (comps->dev) + return -EBUSY; + +@@ -583,10 +614,10 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, + + switch (subid) { + case 0x17aa: +- tas_priv->catlog_id = LENOVO; ++ tas_hda->priv->catlog_id = LENOVO; + break; + default: +- tas_priv->catlog_id = OTHERS; ++ tas_hda->priv->catlog_id = OTHERS; + break; + } + +@@ -596,7 +627,7 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, + + strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + +- ret = tascodec_init(tas_priv, codec, tasdev_fw_ready); ++ ret = tascodec_init(tas_hda->priv, codec, tasdev_fw_ready); + if (!ret) + comps->playback_hook = tas2781_hda_playback_hook; + +@@ -609,9 +640,9 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, + static void tas2781_hda_unbind(struct device *dev, + struct device *master, void *master_data) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + struct hda_component *comps = master_data; +- comps = &comps[tas_priv->index]; ++ comps = &comps[tas_hda->priv->index]; + + if (comps->dev == dev) { + comps->dev = NULL; +@@ -619,10 +650,12 @@ static void tas2781_hda_unbind(struct device *dev, + comps->playback_hook = NULL; + } + +- tasdevice_config_info_remove(tas_priv); +- tasdevice_dsp_remove(tas_priv); ++ tas2781_hda_remove_controls(tas_hda); + +- tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; ++ tasdevice_config_info_remove(tas_hda->priv); ++ tasdevice_dsp_remove(tas_hda->priv); ++ ++ tas_hda->priv->fw_state = TASDEVICE_DSP_FW_PENDING; + } + + static const struct component_ops tas2781_hda_comp_ops = { +@@ -632,21 +665,21 @@ static const struct component_ops tas2781_hda_comp_ops = { + + static void tas2781_hda_remove(struct device *dev) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + +- pm_runtime_get_sync(tas_priv->dev); +- pm_runtime_disable(tas_priv->dev); ++ pm_runtime_get_sync(tas_hda->dev); ++ pm_runtime_disable(tas_hda->dev); + +- component_del(tas_priv->dev, &tas2781_hda_comp_ops); ++ component_del(tas_hda->dev, &tas2781_hda_comp_ops); + +- pm_runtime_put_noidle(tas_priv->dev); ++ pm_runtime_put_noidle(tas_hda->dev); + +- tasdevice_remove(tas_priv); ++ tasdevice_remove(tas_hda->priv); + } + + static int tas2781_hda_i2c_probe(struct i2c_client *clt) + { +- struct tasdevice_priv *tas_priv; ++ struct tas2781_hda *tas_hda; + const char *device_name; + int ret; + +@@ -655,35 +688,42 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) + else + return -ENODEV; + +- tas_priv = tasdevice_kzalloc(clt); +- if (!tas_priv) ++ tas_hda = devm_kzalloc(&clt->dev, sizeof(*tas_hda), GFP_KERNEL); ++ if (!tas_hda) + return -ENOMEM; + +- tas_priv->irq_info.irq = clt->irq; +- ret = tas2781_read_acpi(tas_priv, device_name); ++ dev_set_drvdata(&clt->dev, tas_hda); ++ tas_hda->dev = &clt->dev; ++ ++ tas_hda->priv = tasdevice_kzalloc(clt); ++ if (!tas_hda->priv) ++ return -ENOMEM; ++ ++ tas_hda->priv->irq_info.irq = clt->irq; ++ ret = tas2781_read_acpi(tas_hda->priv, device_name); + if (ret) +- return dev_err_probe(tas_priv->dev, ret, ++ return dev_err_probe(tas_hda->dev, ret, + "Platform not supported\n"); + +- ret = tasdevice_init(tas_priv); ++ ret = tasdevice_init(tas_hda->priv); + if (ret) + goto err; + +- pm_runtime_set_autosuspend_delay(tas_priv->dev, 3000); +- pm_runtime_use_autosuspend(tas_priv->dev); +- pm_runtime_mark_last_busy(tas_priv->dev); +- pm_runtime_set_active(tas_priv->dev); +- pm_runtime_get_noresume(tas_priv->dev); +- pm_runtime_enable(tas_priv->dev); ++ pm_runtime_set_autosuspend_delay(tas_hda->dev, 3000); ++ pm_runtime_use_autosuspend(tas_hda->dev); ++ pm_runtime_mark_last_busy(tas_hda->dev); ++ pm_runtime_set_active(tas_hda->dev); ++ pm_runtime_get_noresume(tas_hda->dev); ++ pm_runtime_enable(tas_hda->dev); + +- pm_runtime_put_autosuspend(tas_priv->dev); ++ pm_runtime_put_autosuspend(tas_hda->dev); + +- tas2781_reset(tas_priv); ++ tas2781_reset(tas_hda->priv); + +- ret = component_add(tas_priv->dev, &tas2781_hda_comp_ops); ++ ret = component_add(tas_hda->dev, &tas2781_hda_comp_ops); + if (ret) { +- dev_err(tas_priv->dev, "Register component failed: %d\n", ret); +- pm_runtime_disable(tas_priv->dev); ++ dev_err(tas_hda->dev, "Register component failed: %d\n", ret); ++ pm_runtime_disable(tas_hda->dev); + } + + err: +@@ -699,81 +739,65 @@ static void tas2781_hda_i2c_remove(struct i2c_client *clt) + + static int tas2781_runtime_suspend(struct device *dev) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + int i; + +- dev_dbg(tas_priv->dev, "Runtime Suspend\n"); ++ dev_dbg(tas_hda->dev, "Runtime Suspend\n"); + +- mutex_lock(&tas_priv->codec_lock); ++ mutex_lock(&tas_hda->priv->codec_lock); + +- if (tas_priv->playback_started) { +- tasdevice_tuning_switch(tas_priv, 1); +- tas_priv->playback_started = false; ++ if (tas_hda->priv->playback_started) { ++ tasdevice_tuning_switch(tas_hda->priv, 1); ++ tas_hda->priv->playback_started = false; + } + +- for (i = 0; i < tas_priv->ndev; i++) { +- tas_priv->tasdevice[i].cur_book = -1; +- tas_priv->tasdevice[i].cur_prog = -1; +- tas_priv->tasdevice[i].cur_conf = -1; ++ for (i = 0; i < tas_hda->priv->ndev; i++) { ++ tas_hda->priv->tasdevice[i].cur_book = -1; ++ tas_hda->priv->tasdevice[i].cur_prog = -1; ++ tas_hda->priv->tasdevice[i].cur_conf = -1; + } + +- regcache_cache_only(tas_priv->regmap, true); +- regcache_mark_dirty(tas_priv->regmap); +- +- mutex_unlock(&tas_priv->codec_lock); ++ mutex_unlock(&tas_hda->priv->codec_lock); + + return 0; + } + + static int tas2781_runtime_resume(struct device *dev) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + unsigned long calib_data_sz = +- tas_priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE; +- int ret; +- +- dev_dbg(tas_priv->dev, "Runtime Resume\n"); ++ tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE; + +- mutex_lock(&tas_priv->codec_lock); ++ dev_dbg(tas_hda->dev, "Runtime Resume\n"); + +- regcache_cache_only(tas_priv->regmap, false); +- ret = regcache_sync(tas_priv->regmap); +- if (ret) { +- dev_err(tas_priv->dev, +- "Failed to restore register cache: %d\n", ret); +- goto out; +- } ++ mutex_lock(&tas_hda->priv->codec_lock); + +- tasdevice_prmg_load(tas_priv, tas_priv->cur_prog); ++ tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog); + + /* If calibrated data occurs error, dsp will still works with default + * calibrated data inside algo. + */ +- if (tas_priv->cali_data.total_sz > calib_data_sz) +- tas2781_apply_calib(tas_priv); ++ if (tas_hda->priv->cali_data.total_sz > calib_data_sz) ++ tas2781_apply_calib(tas_hda->priv); + +-out: +- mutex_unlock(&tas_priv->codec_lock); ++ mutex_unlock(&tas_hda->priv->codec_lock); + +- return ret; ++ return 0; + } + + static int tas2781_system_suspend(struct device *dev) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + int ret; + +- dev_dbg(tas_priv->dev, "System Suspend\n"); ++ dev_dbg(tas_hda->priv->dev, "System Suspend\n"); + + ret = pm_runtime_force_suspend(dev); + if (ret) + return ret; + + /* Shutdown chip before system suspend */ +- regcache_cache_only(tas_priv->regmap, false); +- tasdevice_tuning_switch(tas_priv, 1); +- regcache_cache_only(tas_priv->regmap, true); +- regcache_mark_dirty(tas_priv->regmap); ++ tasdevice_tuning_switch(tas_hda->priv, 1); + + /* + * Reset GPIO may be shared, so cannot reset here. +@@ -784,33 +808,33 @@ static int tas2781_system_suspend(struct device *dev) + + static int tas2781_system_resume(struct device *dev) + { +- struct tasdevice_priv *tas_priv = dev_get_drvdata(dev); ++ struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + unsigned long calib_data_sz = +- tas_priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE; ++ tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE; + int i, ret; + +- dev_dbg(tas_priv->dev, "System Resume\n"); ++ dev_info(tas_hda->priv->dev, "System Resume\n"); + + ret = pm_runtime_force_resume(dev); + if (ret) + return ret; + +- mutex_lock(&tas_priv->codec_lock); ++ mutex_lock(&tas_hda->priv->codec_lock); + +- for (i = 0; i < tas_priv->ndev; i++) { +- tas_priv->tasdevice[i].cur_book = -1; +- tas_priv->tasdevice[i].cur_prog = -1; +- tas_priv->tasdevice[i].cur_conf = -1; ++ for (i = 0; i < tas_hda->priv->ndev; i++) { ++ tas_hda->priv->tasdevice[i].cur_book = -1; ++ tas_hda->priv->tasdevice[i].cur_prog = -1; ++ tas_hda->priv->tasdevice[i].cur_conf = -1; + } +- tas2781_reset(tas_priv); +- tasdevice_prmg_load(tas_priv, tas_priv->cur_prog); ++ tas2781_reset(tas_hda->priv); ++ tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog); + + /* If calibrated data occurs error, dsp will still work with default + * calibrated data inside algo. + */ +- if (tas_priv->cali_data.total_sz > calib_data_sz) +- tas2781_apply_calib(tas_priv); +- mutex_unlock(&tas_priv->codec_lock); ++ if (tas_hda->priv->cali_data.total_sz > calib_data_sz) ++ tas2781_apply_calib(tas_hda->priv); ++ mutex_unlock(&tas_hda->priv->codec_lock); + + return 0; + } +diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c +index ffb26e4a7e2f0..00e35169ae495 100644 +--- a/sound/soc/codecs/tas2781-comlib.c ++++ b/sound/soc/codecs/tas2781-comlib.c +@@ -39,7 +39,7 @@ static const struct regmap_range_cfg tasdevice_ranges[] = { + static const struct regmap_config tasdevice_regmap = { + .reg_bits = 8, + .val_bits = 8, +- .cache_type = REGCACHE_RBTREE, ++ .cache_type = REGCACHE_NONE, + .ranges = tasdevice_ranges, + .num_ranges = ARRAY_SIZE(tasdevice_ranges), + .max_register = 256 * 128, +@@ -316,8 +316,6 @@ int tasdevice_init(struct tasdevice_priv *tas_priv) + tas_priv->tasdevice[i].cur_conf = -1; + } + +- dev_set_drvdata(tas_priv->dev, tas_priv); +- + mutex_init(&tas_priv->codec_lock); + + out: +diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c +index 55cd5e3c23a5d..917b1c15f71d4 100644 +--- a/sound/soc/codecs/tas2781-i2c.c ++++ b/sound/soc/codecs/tas2781-i2c.c +@@ -689,6 +689,8 @@ static int tasdevice_i2c_probe(struct i2c_client *i2c) + if (!tas_priv) + return -ENOMEM; + ++ dev_set_drvdata(&i2c->dev, tas_priv); ++ + if (ACPI_HANDLE(&i2c->dev)) { + acpi_id = acpi_match_device(i2c->dev.driver->acpi_match_table, + &i2c->dev); +diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c +index abe19a8a7aa72..f7180f1959dd0 100644 +--- a/sound/soc/fsl/fsl_rpmsg.c ++++ b/sound/soc/fsl/fsl_rpmsg.c +@@ -239,7 +239,7 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, + &fsl_rpmsg_dai, 1); + if (ret) +- return ret; ++ goto err_pm_disable; + + rpmsg->card_pdev = platform_device_register_data(&pdev->dev, + "imx-audio-rpmsg", +@@ -249,16 +249,22 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) + if (IS_ERR(rpmsg->card_pdev)) { + dev_err(&pdev->dev, "failed to register rpmsg card\n"); + ret = PTR_ERR(rpmsg->card_pdev); +- return ret; ++ goto err_pm_disable; + } + + return 0; ++ ++err_pm_disable: ++ pm_runtime_disable(&pdev->dev); ++ return ret; + } + + static void fsl_rpmsg_remove(struct platform_device *pdev) + { + struct fsl_rpmsg *rpmsg = platform_get_drvdata(pdev); + ++ pm_runtime_disable(&pdev->dev); ++ + if (rpmsg->card_pdev) + platform_device_unregister(rpmsg->card_pdev); + } +diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c +index 247ab8df941f7..ab61e597c9a0f 100644 +--- a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c ++++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c +@@ -499,7 +499,7 @@ static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, +- 0, 0, 0, ++ AFE_AUD_PAD_TOP, RG_RX_FIFO_ON_SFT, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, +diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c +index 6c4503766fdca..531bb8707a3ec 100644 +--- a/sound/soc/meson/g12a-toacodec.c ++++ b/sound/soc/meson/g12a-toacodec.c +@@ -71,6 +71,9 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int mux, reg; + ++ if (ucontrol->value.enumerated.item[0] >= e->items) ++ return -EINVAL; ++ + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); + regmap_field_read(priv->field_dat_sel, ®); + +@@ -101,7 +104,7 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, + + snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); + +- return 0; ++ return 1; + } + + static SOC_ENUM_SINGLE_DECL(g12a_toacodec_mux_enum, TOACODEC_CTRL0, +diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c +index f7ef9aa1eed8d..b92434125face 100644 +--- a/sound/soc/meson/g12a-tohdmitx.c ++++ b/sound/soc/meson/g12a-tohdmitx.c +@@ -45,6 +45,9 @@ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol, + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int mux, changed; + ++ if (ucontrol->value.enumerated.item[0] >= e->items) ++ return -EINVAL; ++ + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); + changed = snd_soc_component_test_bits(component, e->reg, + CTRL0_I2S_DAT_SEL, +@@ -93,6 +96,9 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int mux, changed; + ++ if (ucontrol->value.enumerated.item[0] >= e->items) ++ return -EINVAL; ++ + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); + changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0, + CTRL0_SPDIF_SEL, +@@ -112,7 +118,7 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, + + snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); + +- return 0; ++ return 1; + } + + static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0, +diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c +index 2883660d6b672..882bf8e6e70e4 100644 +--- a/tools/bpf/bpftool/gen.c ++++ b/tools/bpf/bpftool/gen.c +@@ -1209,7 +1209,7 @@ static int do_skeleton(int argc, char **argv) + codegen("\ + \n\ + \n\ +- s->data = (void *)%2$s__elf_bytes(&s->data_sz); \n\ ++ s->data = %1$s__elf_bytes(&s->data_sz); \n\ + \n\ + obj->skeleton = s; \n\ + return 0; \n\ +@@ -1218,12 +1218,12 @@ static int do_skeleton(int argc, char **argv) + return err; \n\ + } \n\ + \n\ +- static inline const void *%2$s__elf_bytes(size_t *sz) \n\ ++ static inline const void *%1$s__elf_bytes(size_t *sz) \n\ + { \n\ +- *sz = %1$d; \n\ +- return (const void *)\"\\ \n\ +- " +- , file_sz, obj_name); ++ static const char data[] __attribute__((__aligned__(8))) = \"\\\n\ ++ ", ++ obj_name ++ ); + + /* embed contents of BPF object file */ + print_hex(obj_data, file_sz); +@@ -1231,6 +1231,9 @@ static int do_skeleton(int argc, char **argv) + codegen("\ + \n\ + \"; \n\ ++ \n\ ++ *sz = sizeof(data) - 1; \n\ ++ return (const void *)data; \n\ + } \n\ + \n\ + #ifdef __cplusplus \n\ +diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild +index 90f3c9802ffb8..95dc58b94178b 100644 +--- a/tools/testing/cxl/Kbuild ++++ b/tools/testing/cxl/Kbuild +@@ -62,5 +62,6 @@ cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o + cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o + cxl_core-y += config_check.o + cxl_core-y += cxl_core_test.o ++cxl_core-y += cxl_core_exports.o + + obj-m += test/ +diff --git a/tools/testing/cxl/cxl_core_exports.c b/tools/testing/cxl/cxl_core_exports.c +new file mode 100644 +index 0000000000000..077e6883921df +--- /dev/null ++++ b/tools/testing/cxl/cxl_core_exports.c +@@ -0,0 +1,7 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ ++ ++#include "cxl.h" ++ ++/* Exporting of cxl_core symbols that are only used by cxl_test */ ++EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, CXL); +diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c +index b885462999022..f4e517a0c7740 100644 +--- a/tools/testing/cxl/test/cxl.c ++++ b/tools/testing/cxl/test/cxl.c +@@ -669,10 +669,11 @@ static int mock_decoder_commit(struct cxl_decoder *cxld) + return 0; + + dev_dbg(&port->dev, "%s commit\n", dev_name(&cxld->dev)); +- if (port->commit_end + 1 != id) { ++ if (cxl_num_decoders_committed(port) != id) { + dev_dbg(&port->dev, + "%s: out of order commit, expected decoder%d.%d\n", +- dev_name(&cxld->dev), port->id, port->commit_end + 1); ++ dev_name(&cxld->dev), port->id, ++ cxl_num_decoders_committed(port)); + return -EBUSY; + } + +diff --git a/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh b/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh +index 4917dbb35a44d..5667febee3286 100755 +--- a/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh ++++ b/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh +@@ -30,16 +30,16 @@ ip netns exec server ip addr add ${server_ip4}/24 dev eth0 + + ip netns exec client ip link add dev bond0 down type bond mode 1 \ + miimon 100 all_slaves_active 1 +-ip netns exec client ip link set dev eth0 down master bond0 ++ip netns exec client ip link set dev eth0 master bond0 + ip netns exec client ip link set dev bond0 up + ip netns exec client ip addr add ${client_ip4}/24 dev bond0 + ip netns exec client ping -c 5 $server_ip4 >/dev/null + +-ip netns exec client ip link set dev eth0 down nomaster ++ip netns exec client ip link set dev eth0 nomaster + ip netns exec client ip link set dev bond0 down + ip netns exec client ip link set dev bond0 type bond mode 0 \ + arp_interval 1000 arp_ip_target "+${server_ip4}" +-ip netns exec client ip link set dev eth0 down master bond0 ++ip netns exec client ip link set dev eth0 master bond0 + ip netns exec client ip link set dev bond0 up + ip netns exec client ping -c 5 $server_ip4 >/dev/null + |