diff --git a/config/sources/families/odroidxu4.conf b/config/sources/families/odroidxu4.conf index 337132728a..30554b3e84 100644 --- a/config/sources/families/odroidxu4.conf +++ b/config/sources/families/odroidxu4.conf @@ -19,9 +19,9 @@ case $BRANCH in current) KERNELSOURCE='https://github.com/hardkernel/linux' - declare -g KERNEL_MAJOR_MINOR="6.1" # Major and minor versions of this kernel. + declare -g KERNEL_MAJOR_MINOR="6.6" # Major and minor versions of this kernel. declare -g KERNEL_SKIP_MAKEFILE_VERSION="yes" # Armbian patches change the version here, so no use having it in the version string. - KERNELBRANCH='branch:odroidxu4-6.1.y' + KERNELBRANCH='branch:odroid-6.6.y' KERNELPATCHDIR=odroidxu4-current KERNEL_DRIVERS_SKIP+=(driver_rtl8811CU_rtl8821C) # rtl8821 is already shipped with hardkernel's source ;; diff --git a/patch/kernel/odroidxu4-current/patch-6.1.77-78.patch b/patch/kernel/odroidxu4-current/patch-6.1.77-78.patch deleted file mode 100644 index d0f0c09765..0000000000 --- a/patch/kernel/odroidxu4-current/patch-6.1.77-78.patch +++ /dev/null @@ -1,2252 +0,0 @@ -diff --git a/Makefile b/Makefile -index f5598d90093f5..e93554269e474 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 77 -+SUBLEVEL = 78 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/block/blk-core.c b/block/blk-core.c -index 6eaf2b0ad7cca..aefdf07bdc2cf 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -864,7 +864,16 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags) - */ - blk_flush_plug(current->plug, false); - -- if (bio_queue_enter(bio)) -+ /* -+ * We need to be able to enter a frozen queue, similar to how -+ * timeouts also need to do that. If that is blocked, then we can -+ * have pending IO when a queue freeze is started, and then the -+ * wait for the freeze to finish will wait for polled requests to -+ * timeout as the poller is preventer from entering the queue and -+ * completing them. As long as we prevent new IO from being queued, -+ * that should be all that matters. -+ */ -+ if (!percpu_ref_tryget(&q->q_usage_counter)) - return 0; - if (queue_is_mq(q)) { - ret = blk_mq_poll(q, cookie, iob, flags); -diff --git a/block/blk-iocost.c b/block/blk-iocost.c -index 7dd6a33e1d6a8..e6557024e3da8 100644 ---- a/block/blk-iocost.c -+++ b/block/blk-iocost.c -@@ -1337,6 +1337,13 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now) - - lockdep_assert_held(&iocg->waitq.lock); - -+ /* -+ * If the delay is set by another CPU, we may be in the past. No need to -+ * change anything if so. This avoids decay calculation underflow. -+ */ -+ if (time_before64(now->now, iocg->delay_at)) -+ return false; -+ - /* calculate the current delay in effect - 1/2 every second */ - tdelta = now->now - iocg->delay_at; - if (iocg->delay) -diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c -index 49cb4537344aa..2daf50d4cd47a 100644 ---- a/drivers/atm/idt77252.c -+++ b/drivers/atm/idt77252.c -@@ -2930,6 +2930,8 @@ open_card_ubr0(struct idt77252_dev *card) - vc->scq = alloc_scq(card, vc->class); - if (!vc->scq) { - printk("%s: can't get SCQ.\n", card->name); -+ kfree(card->vcs[0]); -+ card->vcs[0] = NULL; - return -ENOMEM; - } - -diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c -index 8dd40d00a672a..6b829d347417a 100644 ---- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c -+++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c -@@ -38,15 +38,17 @@ static int dpaa2_qdma_alloc_chan_resources(struct dma_chan *chan) - if (!dpaa2_chan->fd_pool) - goto err; - -- dpaa2_chan->fl_pool = dma_pool_create("fl_pool", dev, -- sizeof(struct dpaa2_fl_entry), -- sizeof(struct dpaa2_fl_entry), 0); -+ dpaa2_chan->fl_pool = -+ dma_pool_create("fl_pool", dev, -+ sizeof(struct dpaa2_fl_entry) * 3, -+ sizeof(struct dpaa2_fl_entry), 0); -+ - if (!dpaa2_chan->fl_pool) - goto err_fd; - - dpaa2_chan->sdd_pool = - dma_pool_create("sdd_pool", dev, -- sizeof(struct dpaa2_qdma_sd_d), -+ sizeof(struct dpaa2_qdma_sd_d) * 2, - sizeof(struct dpaa2_qdma_sd_d), 0); - if (!dpaa2_chan->sdd_pool) - goto err_fl; -diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c -index 045ead46ec8fc..69385f32e2756 100644 ---- a/drivers/dma/fsl-qdma.c -+++ b/drivers/dma/fsl-qdma.c -@@ -514,11 +514,11 @@ static struct fsl_qdma_queue - queue_temp = queue_head + i + (j * queue_num); - - queue_temp->cq = -- dma_alloc_coherent(&pdev->dev, -- sizeof(struct fsl_qdma_format) * -- queue_size[i], -- &queue_temp->bus_addr, -- GFP_KERNEL); -+ dmam_alloc_coherent(&pdev->dev, -+ sizeof(struct fsl_qdma_format) * -+ queue_size[i], -+ &queue_temp->bus_addr, -+ GFP_KERNEL); - if (!queue_temp->cq) - return NULL; - queue_temp->block_base = fsl_qdma->block_base + -@@ -563,11 +563,11 @@ static struct fsl_qdma_queue - /* - * Buffer for queue command - */ -- status_head->cq = dma_alloc_coherent(&pdev->dev, -- sizeof(struct fsl_qdma_format) * -- status_size, -- &status_head->bus_addr, -- GFP_KERNEL); -+ status_head->cq = dmam_alloc_coherent(&pdev->dev, -+ sizeof(struct fsl_qdma_format) * -+ status_size, -+ &status_head->bus_addr, -+ GFP_KERNEL); - if (!status_head->cq) { - devm_kfree(&pdev->dev, status_head); - return NULL; -@@ -1272,8 +1272,6 @@ static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev) - - static int fsl_qdma_remove(struct platform_device *pdev) - { -- int i; -- struct fsl_qdma_queue *status; - struct device_node *np = pdev->dev.of_node; - struct fsl_qdma_engine *fsl_qdma = platform_get_drvdata(pdev); - -@@ -1282,11 +1280,6 @@ static int fsl_qdma_remove(struct platform_device *pdev) - of_dma_controller_free(np); - dma_async_device_unregister(&fsl_qdma->dma_dev); - -- for (i = 0; i < fsl_qdma->block_number; i++) { -- status = fsl_qdma->status[i]; -- dma_free_coherent(&pdev->dev, sizeof(struct fsl_qdma_format) * -- status->n_cq, status->cq, status->bus_addr); -- } - return 0; - } - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index b86b809eb1f7e..82e7acfda6ed0 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -3963,6 +3963,7 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, - { - struct udma_chan *uc = to_udma_chan(&vc->chan); - struct udma_desc *d; -+ u8 status; - - if (!vd) - return; -@@ -3972,12 +3973,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, - if (d->metadata_size) - udma_fetch_epib(uc, d); - -- /* Provide residue information for the client */ - if (result) { - void *desc_vaddr = udma_curr_cppi5_desc_vaddr(d, d->desc_idx); - - if (cppi5_desc_get_type(desc_vaddr) == - CPPI5_INFO0_DESC_TYPE_VAL_HOST) { -+ /* Provide residue information for the client */ - result->residue = d->residue - - cppi5_hdesc_get_pktlen(desc_vaddr); - if (result->residue) -@@ -3986,7 +3987,12 @@ static void udma_desc_pre_callback(struct virt_dma_chan *vc, - result->result = DMA_TRANS_NOERROR; - } else { - result->residue = 0; -- result->result = DMA_TRANS_NOERROR; -+ /* Propagate TR Response errors to the client */ -+ status = d->hwdesc[0].tr_resp_base->status; -+ if (status) -+ result->result = DMA_TRANS_ABORTED; -+ else -+ result->result = DMA_TRANS_NOERROR; - } - } - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -index f04595b750abc..5ec3f50a72acd 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -@@ -1014,7 +1014,7 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id - vpg = dcn301_vpg_create(ctx, vpg_inst); - afmt = dcn301_afmt_create(ctx, afmt_inst); - -- if (!enc1 || !vpg || !afmt) { -+ if (!enc1 || !vpg || !afmt || eng_id >= ARRAY_SIZE(stream_enc_regs)) { - kfree(enc1); - kfree(vpg); - kfree(afmt); -diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c -index daac2050d77d0..6f531bb61f7e5 100644 ---- a/drivers/gpu/drm/i915/gvt/handlers.c -+++ b/drivers/gpu/drm/i915/gvt/handlers.c -@@ -2844,8 +2844,7 @@ static int handle_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset, - for (i = start; i < end; i += 4) { - p = intel_gvt_find_mmio_info(gvt, i); - if (p) { -- WARN(1, "dup mmio definition offset %x\n", -- info->offset); -+ WARN(1, "dup mmio definition offset %x\n", i); - - /* We return -EEXIST here to make GVT-g load fail. - * So duplicated MMIO can be found as soon as -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -index 38d38f923df64..25245ef386db6 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -@@ -2053,7 +2053,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) - } - - /* reset the merge 3D HW block */ -- if (phys_enc->hw_pp->merge_3d) { -+ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { - phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, - BLEND_3D_NONE); - if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d) -@@ -2069,7 +2069,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) - if (phys_enc->hw_wb) - intf_cfg.wb = phys_enc->hw_wb->idx; - -- if (phys_enc->hw_pp->merge_3d) -+ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) - intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; - - if (ctl->ops.reset_intf_cfg) -diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c -index 103eef9f059a0..b20701893e5b3 100644 ---- a/drivers/gpu/drm/msm/dp/dp_ctrl.c -+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c -@@ -133,11 +133,6 @@ static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl) - tbd = dp_link_get_test_bits_depth(ctrl->link, - ctrl->panel->dp_mode.bpp); - -- if (tbd == DP_TEST_BIT_DEPTH_UNKNOWN) { -- pr_debug("BIT_DEPTH not set. Configure default\n"); -- tbd = DP_TEST_BIT_DEPTH_8; -- } -- - config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT; - - /* Num of Lanes */ -diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c -index cb66d1126ea96..ceb382fa56d5b 100644 ---- a/drivers/gpu/drm/msm/dp/dp_link.c -+++ b/drivers/gpu/drm/msm/dp/dp_link.c -@@ -7,6 +7,7 @@ - - #include - -+#include "dp_reg.h" - #include "dp_link.h" - #include "dp_panel.h" - -@@ -1075,7 +1076,7 @@ int dp_link_process_request(struct dp_link *dp_link) - - int dp_link_get_colorimetry_config(struct dp_link *dp_link) - { -- u32 cc; -+ u32 cc = DP_MISC0_COLORIMERY_CFG_LEGACY_RGB; - struct dp_link_private *link; - - if (!dp_link) { -@@ -1089,10 +1090,11 @@ int dp_link_get_colorimetry_config(struct dp_link *dp_link) - * Unless a video pattern CTS test is ongoing, use RGB_VESA - * Only RGB_VESA and RGB_CEA supported for now - */ -- if (dp_link_is_video_pattern_requested(link)) -- cc = link->dp_link.test_video.test_dyn_range; -- else -- cc = DP_TEST_DYNAMIC_RANGE_VESA; -+ if (dp_link_is_video_pattern_requested(link)) { -+ if (link->dp_link.test_video.test_dyn_range & -+ DP_TEST_DYNAMIC_RANGE_CEA) -+ cc = DP_MISC0_COLORIMERY_CFG_CEA_RGB; -+ } - - return cc; - } -@@ -1172,6 +1174,9 @@ void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link) - u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) - { - u32 tbd; -+ struct dp_link_private *link; -+ -+ link = container_of(dp_link, struct dp_link_private, dp_link); - - /* - * Few simplistic rules and assumptions made here: -@@ -1189,12 +1194,13 @@ u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp) - tbd = DP_TEST_BIT_DEPTH_10; - break; - default: -- tbd = DP_TEST_BIT_DEPTH_UNKNOWN; -+ drm_dbg_dp(link->drm_dev, "bpp=%d not supported, use bpc=8\n", -+ bpp); -+ tbd = DP_TEST_BIT_DEPTH_8; - break; - } - -- if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN) -- tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); -+ tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT); - - return tbd; - } -diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h -index 268602803d9a3..176a503ece9c0 100644 ---- a/drivers/gpu/drm/msm/dp/dp_reg.h -+++ b/drivers/gpu/drm/msm/dp/dp_reg.h -@@ -129,6 +129,9 @@ - #define DP_MISC0_COLORIMETRY_CFG_SHIFT (0x00000001) - #define DP_MISC0_TEST_BITS_DEPTH_SHIFT (0x00000005) - -+#define DP_MISC0_COLORIMERY_CFG_LEGACY_RGB (0) -+#define DP_MISC0_COLORIMERY_CFG_CEA_RGB (0x04) -+ - #define REG_DP_VALID_BOUNDARY (0x00000030) - #define REG_DP_VALID_BOUNDARY_2 (0x00000034) - -diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c -index d11f674e3dc37..51f321bcd778a 100644 ---- a/drivers/hwmon/aspeed-pwm-tacho.c -+++ b/drivers/hwmon/aspeed-pwm-tacho.c -@@ -194,6 +194,8 @@ struct aspeed_pwm_tacho_data { - u8 fan_tach_ch_source[16]; - struct aspeed_cooling_device *cdev[8]; - const struct attribute_group *groups[3]; -+ /* protects access to shared ASPEED_PTCR_RESULT */ -+ struct mutex tach_lock; - }; - - enum type { TYPEM, TYPEN, TYPEO }; -@@ -528,6 +530,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, - u8 fan_tach_ch_source, type, mode, both; - int ret; - -+ mutex_lock(&priv->tach_lock); -+ - regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); - regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); - -@@ -545,6 +549,8 @@ static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv, - ASPEED_RPM_STATUS_SLEEP_USEC, - usec); - -+ mutex_unlock(&priv->tach_lock); -+ - /* return -ETIMEDOUT if we didn't get an answer. */ - if (ret) - return ret; -@@ -904,6 +910,7 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev) - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; -+ mutex_init(&priv->tach_lock); - priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs, - &aspeed_pwm_tacho_regmap_config); - if (IS_ERR(priv->regmap)) -diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c -index 09aab5859fa75..59344ad62822d 100644 ---- a/drivers/hwmon/coretemp.c -+++ b/drivers/hwmon/coretemp.c -@@ -380,7 +380,7 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) - } - - static int create_core_attrs(struct temp_data *tdata, struct device *dev, -- int attr_no) -+ int index) - { - int i; - static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, -@@ -392,13 +392,20 @@ static int create_core_attrs(struct temp_data *tdata, struct device *dev, - }; - - for (i = 0; i < tdata->attr_size; i++) { -+ /* -+ * We map the attr number to core id of the CPU -+ * The attr number is always core id + 2 -+ * The Pkgtemp will always show up as temp1_*, if available -+ */ -+ int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2; -+ - snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, - "temp%d_%s", attr_no, suffixes[i]); - sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); - tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; - tdata->sd_attrs[i].dev_attr.attr.mode = 0444; - tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; -- tdata->sd_attrs[i].index = attr_no; -+ tdata->sd_attrs[i].index = index; - tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr; - } - tdata->attr_group.attrs = tdata->attrs; -@@ -456,27 +463,22 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, - struct platform_data *pdata = platform_get_drvdata(pdev); - struct cpuinfo_x86 *c = &cpu_data(cpu); - u32 eax, edx; -- int err, index, attr_no; -+ int err, index; - - /* -- * Find attr number for sysfs: -- * We map the attr number to core id of the CPU -- * The attr number is always core id + 2 -- * The Pkgtemp will always show up as temp1_*, if available -+ * Get the index of tdata in pdata->core_data[] -+ * tdata for package: pdata->core_data[1] -+ * tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1] - */ - if (pkg_flag) { -- attr_no = PKG_SYSFS_ATTR_NO; -+ index = PKG_SYSFS_ATTR_NO; - } else { -- index = ida_alloc(&pdata->ida, GFP_KERNEL); -+ index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL); - if (index < 0) - return index; -- pdata->cpu_map[index] = topology_core_id(cpu); -- attr_no = index + BASE_SYSFS_ATTR_NO; -- } - -- if (attr_no > MAX_CORE_DATA - 1) { -- err = -ERANGE; -- goto ida_free; -+ pdata->cpu_map[index] = topology_core_id(cpu); -+ index += BASE_SYSFS_ATTR_NO; - } - - tdata = init_temp_data(cpu, pkg_flag); -@@ -508,20 +510,20 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, - } - } - -- pdata->core_data[attr_no] = tdata; -+ pdata->core_data[index] = tdata; - - /* Create sysfs interfaces */ -- err = create_core_attrs(tdata, pdata->hwmon_dev, attr_no); -+ err = create_core_attrs(tdata, pdata->hwmon_dev, index); - if (err) - goto exit_free; - - return 0; - exit_free: -- pdata->core_data[attr_no] = NULL; -+ pdata->core_data[index] = NULL; - kfree(tdata); - ida_free: - if (!pkg_flag) -- ida_free(&pdata->ida, index); -+ ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO); - return err; - } - -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 447e1bcc82a32..4859b99d54fc2 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -2825,7 +2825,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, - iwmr->ibmr.pd = pd; - iwmr->ibmr.device = pd->device; - iwmr->ibmr.iova = virt; -- iwmr->page_size = PAGE_SIZE; -+ iwmr->page_size = SZ_4K; - - if (req.reg_type == IRDMA_MEMREG_TYPE_MEM) { - iwmr->page_size = ib_umem_find_best_pgsz(region, -diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c -index c4d8caadec59e..661d6c8b059bf 100644 ---- a/drivers/input/keyboard/atkbd.c -+++ b/drivers/input/keyboard/atkbd.c -@@ -792,7 +792,6 @@ static int atkbd_probe(struct atkbd *atkbd) - { - struct ps2dev *ps2dev = &atkbd->ps2dev; - unsigned char param[2]; -- bool skip_getid; - - /* - * Some systems, where the bit-twiddling when testing the io-lines of the -@@ -806,6 +805,11 @@ static int atkbd_probe(struct atkbd *atkbd) - "keyboard reset failed on %s\n", - ps2dev->serio->phys); - -+ if (atkbd_skip_getid(atkbd)) { -+ atkbd->id = 0xab83; -+ return 0; -+ } -+ - /* - * Then we check the keyboard ID. We should get 0xab83 under normal conditions. - * Some keyboards report different values, but the first byte is always 0xab or -@@ -814,18 +818,17 @@ static int atkbd_probe(struct atkbd *atkbd) - */ - - param[0] = param[1] = 0xa5; /* initialize with invalid values */ -- skip_getid = atkbd_skip_getid(atkbd); -- if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { -+ if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { - - /* -- * If the get ID command was skipped or failed, we check if we can at least set -+ * If the get ID command failed, we check if we can at least set - * the LEDs on the keyboard. This should work on every keyboard out there. - * It also turns the LEDs off, which we want anyway. - */ - param[0] = 0; - if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) - return -1; -- atkbd->id = skip_getid ? 0xab83 : 0xabba; -+ atkbd->id = 0xabba; - return 0; - } - -diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h -index b585b1dab870e..cd45a65e17f2c 100644 ---- a/drivers/input/serio/i8042-acpipnpio.h -+++ b/drivers/input/serio/i8042-acpipnpio.h -@@ -1208,6 +1208,12 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { - SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | - SERIO_QUIRK_NOPNP) - }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "NS5x_7xPU"), -+ }, -+ .driver_data = (void *)(SERIO_QUIRK_NOAUX) -+ }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), -diff --git a/drivers/mtd/parsers/ofpart_core.c b/drivers/mtd/parsers/ofpart_core.c -index 192190c42fc84..e7b8e9d0a9103 100644 ---- a/drivers/mtd/parsers/ofpart_core.c -+++ b/drivers/mtd/parsers/ofpart_core.c -@@ -122,6 +122,25 @@ static int parse_fixed_partitions(struct mtd_info *master, - - a_cells = of_n_addr_cells(pp); - s_cells = of_n_size_cells(pp); -+ if (!dedicated && s_cells == 0) { -+ /* -+ * This is a ugly workaround to not create -+ * regression on devices that are still creating -+ * partitions as direct children of the nand controller. -+ * This can happen in case the nand controller node has -+ * #size-cells equal to 0 and the firmware (e.g. -+ * U-Boot) just add the partitions there assuming -+ * 32-bit addressing. -+ * -+ * If you get this warning your firmware and/or DTS -+ * should be really fixed. -+ * -+ * This is working only for devices smaller than 4GiB. -+ */ -+ pr_warn("%s: ofpart partition %pOF (%pOF) #size-cells is wrongly set to <0>, assuming <1> for parsing partitions.\n", -+ master->name, pp, mtd_node); -+ s_cells = 1; -+ } - if (len / 4 != a_cells + s_cells) { - pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n", - master->name, pp, -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -index abd4832e4ed21..5acb3e16b5677 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -@@ -993,7 +993,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic) - return 0; - - err_exit_hwts_rx: -- aq_ring_free(&aq_ptp->hwts_rx); -+ aq_ring_hwts_rx_free(&aq_ptp->hwts_rx); - err_exit_ptp_rx: - aq_ring_free(&aq_ptp->ptp_rx); - err_exit_ptp_tx: -@@ -1011,7 +1011,7 @@ void aq_ptp_ring_free(struct aq_nic_s *aq_nic) - - aq_ring_free(&aq_ptp->ptp_tx); - aq_ring_free(&aq_ptp->ptp_rx); -- aq_ring_free(&aq_ptp->hwts_rx); -+ aq_ring_hwts_rx_free(&aq_ptp->hwts_rx); - - aq_ptp_skb_ring_release(&aq_ptp->skb_ring); - } -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -index 9c314fe14ab62..0eaaba3a18ee0 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -@@ -919,6 +919,19 @@ void aq_ring_free(struct aq_ring_s *self) - } - } - -+void aq_ring_hwts_rx_free(struct aq_ring_s *self) -+{ -+ if (!self) -+ return; -+ -+ if (self->dx_ring) { -+ dma_free_coherent(aq_nic_get_dev(self->aq_nic), -+ self->size * self->dx_size + AQ_CFG_RXDS_DEF, -+ self->dx_ring, self->dx_ring_pa); -+ self->dx_ring = NULL; -+ } -+} -+ - unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) - { - unsigned int count; -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h -index 52847310740a2..d627ace850ff5 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h -@@ -210,6 +210,7 @@ int aq_ring_rx_fill(struct aq_ring_s *self); - int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, unsigned int idx, - unsigned int size, unsigned int dx_size); -+void aq_ring_hwts_rx_free(struct aq_ring_s *self); - void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic); - - unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -index 0f896f606c3e6..c00d6d67db518 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -@@ -930,8 +930,11 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) - if (pfvf->ptp && qidx < pfvf->hw.tx_queues) { - err = qmem_alloc(pfvf->dev, &sq->timestamps, qset->sqe_cnt, - sizeof(*sq->timestamps)); -- if (err) -+ if (err) { -+ kfree(sq->sg); -+ sq->sg = NULL; - return err; -+ } - } - - sq->head = 0; -@@ -947,7 +950,14 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) - sq->stats.bytes = 0; - sq->stats.pkts = 0; - -- return pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura); -+ err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura); -+ if (err) { -+ kfree(sq->sg); -+ sq->sg = NULL; -+ return err; -+ } -+ -+ return 0; - - } - -diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h -index 54bb072aeb2d3..c11d626856247 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/common.h -+++ b/drivers/net/ethernet/stmicro/stmmac/common.h -@@ -209,6 +209,7 @@ struct stmmac_safety_stats { - unsigned long mac_errors[32]; - unsigned long mtl_errors[32]; - unsigned long dma_errors[32]; -+ unsigned long dma_dpp_errors[32]; - }; - - /* Number of fields in Safety Stats */ -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -index 880a75bf2eb1f..8748c37e9dac9 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -@@ -282,6 +282,8 @@ - #define XGMAC_RXCEIE BIT(4) - #define XGMAC_TXCEIE BIT(0) - #define XGMAC_MTL_ECC_INT_STATUS 0x000010cc -+#define XGMAC_MTL_DPP_CONTROL 0x000010e0 -+#define XGMAC_DPP_DISABLE BIT(0) - #define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x))) - #define XGMAC_TQS GENMASK(25, 16) - #define XGMAC_TQS_SHIFT 16 -@@ -364,6 +366,7 @@ - #define XGMAC_DCEIE BIT(1) - #define XGMAC_TCEIE BIT(0) - #define XGMAC_DMA_ECC_INT_STATUS 0x0000306c -+#define XGMAC_DMA_DPP_INT_STATUS 0x00003074 - #define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x))) - #define XGMAC_SPH BIT(24) - #define XGMAC_PBLx8 BIT(16) -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -index c2181c277291b..ec1616ffbfa7a 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -@@ -789,6 +789,44 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= { - { false, "UNKNOWN", "Unknown Error" }, /* 31 */ - }; - -+#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error" -+#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error" -+ -+static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = { -+ { true, "TDPES0", DPP_TX_ERR }, -+ { true, "TDPES1", DPP_TX_ERR }, -+ { true, "TDPES2", DPP_TX_ERR }, -+ { true, "TDPES3", DPP_TX_ERR }, -+ { true, "TDPES4", DPP_TX_ERR }, -+ { true, "TDPES5", DPP_TX_ERR }, -+ { true, "TDPES6", DPP_TX_ERR }, -+ { true, "TDPES7", DPP_TX_ERR }, -+ { true, "TDPES8", DPP_TX_ERR }, -+ { true, "TDPES9", DPP_TX_ERR }, -+ { true, "TDPES10", DPP_TX_ERR }, -+ { true, "TDPES11", DPP_TX_ERR }, -+ { true, "TDPES12", DPP_TX_ERR }, -+ { true, "TDPES13", DPP_TX_ERR }, -+ { true, "TDPES14", DPP_TX_ERR }, -+ { true, "TDPES15", DPP_TX_ERR }, -+ { true, "RDPES0", DPP_RX_ERR }, -+ { true, "RDPES1", DPP_RX_ERR }, -+ { true, "RDPES2", DPP_RX_ERR }, -+ { true, "RDPES3", DPP_RX_ERR }, -+ { true, "RDPES4", DPP_RX_ERR }, -+ { true, "RDPES5", DPP_RX_ERR }, -+ { true, "RDPES6", DPP_RX_ERR }, -+ { true, "RDPES7", DPP_RX_ERR }, -+ { true, "RDPES8", DPP_RX_ERR }, -+ { true, "RDPES9", DPP_RX_ERR }, -+ { true, "RDPES10", DPP_RX_ERR }, -+ { true, "RDPES11", DPP_RX_ERR }, -+ { true, "RDPES12", DPP_RX_ERR }, -+ { true, "RDPES13", DPP_RX_ERR }, -+ { true, "RDPES14", DPP_RX_ERR }, -+ { true, "RDPES15", DPP_RX_ERR }, -+}; -+ - static void dwxgmac3_handle_dma_err(struct net_device *ndev, - void __iomem *ioaddr, bool correctable, - struct stmmac_safety_stats *stats) -@@ -800,6 +838,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev, - - dwxgmac3_log_error(ndev, value, correctable, "DMA", - dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats); -+ -+ value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS); -+ writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS); -+ -+ dwxgmac3_log_error(ndev, value, false, "DMA_DPP", -+ dwxgmac3_dma_dpp_errors, -+ STAT_OFF(dma_dpp_errors), stats); - } - - static int -@@ -838,6 +883,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp, - value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */ - writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL); - -+ /* 5. Enable Data Path Parity Protection */ -+ value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL); -+ /* already enabled by default, explicit enable it again */ -+ value &= ~XGMAC_DPP_DISABLE; -+ writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL); -+ - return 0; - } - -@@ -871,7 +922,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev, - ret |= !corr; - } - -- err = dma & (XGMAC_DEUIS | XGMAC_DECIS); -+ /* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in -+ * DMA_Safety_Interrupt_Status, so we handle DMA Data Path -+ * Parity Errors here -+ */ -+ err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS); - corr = dma & XGMAC_DECIS; - if (err) { - dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats); -@@ -887,6 +942,7 @@ static const struct dwxgmac3_error { - { dwxgmac3_mac_errors }, - { dwxgmac3_mtl_errors }, - { dwxgmac3_dma_errors }, -+ { dwxgmac3_dma_dpp_errors }, - }; - - static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats, -diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c -index c3fbdd6b68baf..f3fa4bd121169 100644 ---- a/drivers/net/netdevsim/dev.c -+++ b/drivers/net/netdevsim/dev.c -@@ -835,14 +835,14 @@ static void nsim_dev_trap_report_work(struct work_struct *work) - trap_report_dw.work); - nsim_dev = nsim_trap_data->nsim_dev; - -- /* For each running port and enabled packet trap, generate a UDP -- * packet with a random 5-tuple and report it. -- */ - if (!devl_trylock(priv_to_devlink(nsim_dev))) { -- schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 0); -+ schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1); - return; - } - -+ /* For each running port and enabled packet trap, generate a UDP -+ * packet with a random 5-tuple and report it. -+ */ - list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) { - if (!netif_running(nsim_dev_port->ns->netdev)) - continue; -diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c -index 15a179631903f..abc65c4d7a303 100644 ---- a/drivers/net/ppp/ppp_async.c -+++ b/drivers/net/ppp/ppp_async.c -@@ -469,6 +469,10 @@ ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) - case PPPIOCSMRU: - if (get_user(val, p)) - break; -+ if (val > U16_MAX) { -+ err = -EINVAL; -+ break; -+ } - if (val < PPP_MRU) - val = PPP_MRU; - ap->mru = val; -diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c -index 9de617ca9daa2..7e61c6b278a74 100644 ---- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c -+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c -@@ -675,8 +675,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) - channel->irq = platform_get_irq_optional(pdev, 0); - channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); - if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { -- int ret; -- - channel->is_otg_channel = true; - channel->uses_otg_pins = !of_property_read_bool(dev->of_node, - "renesas,no-otg-pins"); -@@ -740,8 +738,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) - ret = PTR_ERR(provider); - goto error; - } else if (channel->is_otg_channel) { -- int ret; -- - ret = device_create_file(dev, &dev_attr_role); - if (ret < 0) - goto error; -diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c -index 31a775877f6e3..63c45809943ff 100644 ---- a/drivers/phy/ti/phy-omap-usb2.c -+++ b/drivers/phy/ti/phy-omap-usb2.c -@@ -116,7 +116,7 @@ static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) - { - struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - -- if (!phy->comparator) -+ if (!phy->comparator || !phy->comparator->set_vbus) - return -ENODEV; - - return phy->comparator->set_vbus(phy->comparator, enabled); -@@ -126,7 +126,7 @@ static int omap_usb_start_srp(struct usb_otg *otg) - { - struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - -- if (!phy->comparator) -+ if (!phy->comparator || !phy->comparator->start_srp) - return -ENODEV; - - return phy->comparator->start_srp(phy->comparator); -diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c -index 66290961c47c2..cfa6f0edff17c 100644 ---- a/drivers/scsi/scsi_error.c -+++ b/drivers/scsi/scsi_error.c -@@ -277,11 +277,12 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) - { - struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); - struct Scsi_Host *shost = scmd->device->host; -+ unsigned int busy = scsi_host_busy(shost); - unsigned long flags; - - spin_lock_irqsave(shost->host_lock, flags); - shost->host_failed++; -- scsi_eh_wakeup(shost, scsi_host_busy(shost)); -+ scsi_eh_wakeup(shost, busy); - spin_unlock_irqrestore(shost->host_lock, flags); - } - -diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index 0e7e9f1e5a029..5c5954b78585e 100644 ---- a/drivers/scsi/scsi_lib.c -+++ b/drivers/scsi/scsi_lib.c -@@ -280,9 +280,11 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd) - rcu_read_lock(); - __clear_bit(SCMD_STATE_INFLIGHT, &cmd->state); - if (unlikely(scsi_host_in_recovery(shost))) { -+ unsigned int busy = scsi_host_busy(shost); -+ - spin_lock_irqsave(shost->host_lock, flags); - if (shost->host_failed || shost->host_eh_scheduled) -- scsi_eh_wakeup(shost, scsi_host_busy(shost)); -+ scsi_eh_wakeup(shost, busy); - spin_unlock_irqrestore(shost->host_lock, flags); - } - rcu_read_unlock(); -diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c -index f6f13e7f1ba14..f4d8e80c4c347 100644 ---- a/drivers/usb/dwc3/host.c -+++ b/drivers/usb/dwc3/host.c -@@ -66,7 +66,7 @@ out: - - int dwc3_host_init(struct dwc3 *dwc) - { -- struct property_entry props[4]; -+ struct property_entry props[5]; - struct platform_device *xhci; - int ret, irq; - int prop_idx = 0; -@@ -94,6 +94,8 @@ int dwc3_host_init(struct dwc3 *dwc) - - memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); - -+ props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-sg-trb-cache-size-quirk"); -+ - if (dwc->usb3_lpm_capable) - props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb3-lpm-capable"); - -diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c -index c9438dc56f5fc..b387d39bfb81d 100644 ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -301,6 +301,9 @@ static int xhci_plat_probe(struct platform_device *pdev) - if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) - xhci->quirks |= XHCI_BROKEN_PORT_PED; - -+ if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk")) -+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; -+ - device_property_read_u32(tmpdev, "imod-interval-ns", - &xhci->imod_interval); - } -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index f1d7a5a863aa4..b3e60b3847941 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -146,6 +146,7 @@ static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ - { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ - { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ -+ { USB_DEVICE(0x10C4, 0x87ED) }, /* IMST USB-Stick for Smart Meter */ - { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */ - { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ - { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index 4adef92598709..c0a0cca65437f 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -2269,6 +2269,7 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */ - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */ - .driver_info = RSVD(4) }, - { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ -diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c -index b1e844bf31f81..703a9c5635573 100644 ---- a/drivers/usb/serial/qcserial.c -+++ b/drivers/usb/serial/qcserial.c -@@ -184,6 +184,8 @@ static const struct usb_device_id id_table[] = { - {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ - {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ - {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ -+ {DEVICE_SWI(0x413c, 0x8217)}, /* Dell Wireless DW5826e */ -+ {DEVICE_SWI(0x413c, 0x8218)}, /* Dell Wireless DW5826e QDL */ - - /* Huawei devices */ - {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ -diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c -index 2eea080298812..61c72e62abd49 100644 ---- a/drivers/vhost/vhost.c -+++ b/drivers/vhost/vhost.c -@@ -2588,12 +2588,11 @@ EXPORT_SYMBOL_GPL(vhost_disable_notify); - /* Create a new message. */ - struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type) - { -- struct vhost_msg_node *node = kmalloc(sizeof *node, GFP_KERNEL); -+ /* Make sure all padding within the structure is initialized. */ -+ struct vhost_msg_node *node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return NULL; - -- /* Make sure all padding within the structure is initialized. */ -- memset(&node->msg, 0, sizeof node->msg); - node->vq = vq; - node->msg.type = type; - return node; -diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c -index 72f34f96d0155..2c797eb519da9 100644 ---- a/fs/dlm/lowcomms.c -+++ b/fs/dlm/lowcomms.c -@@ -174,7 +174,7 @@ static LIST_HEAD(dlm_node_addrs); - static DEFINE_SPINLOCK(dlm_node_addrs_spin); - - static struct listen_connection listen_con; --static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT]; -+static struct sockaddr_storage dlm_local_addr[DLM_MAX_ADDR_COUNT]; - static int dlm_local_count; - int dlm_allow_conn; - -@@ -398,7 +398,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out, - if (!sa_out) - return 0; - -- if (dlm_local_addr[0]->ss_family == AF_INET) { -+ if (dlm_local_addr[0].ss_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *) &sas; - struct sockaddr_in *ret4 = (struct sockaddr_in *) sa_out; - ret4->sin_addr.s_addr = in4->sin_addr.s_addr; -@@ -727,7 +727,7 @@ static void add_sock(struct socket *sock, struct connection *con) - static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, - int *addr_len) - { -- saddr->ss_family = dlm_local_addr[0]->ss_family; -+ saddr->ss_family = dlm_local_addr[0].ss_family; - if (saddr->ss_family == AF_INET) { - struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr; - in4_addr->sin_port = cpu_to_be16(port); -@@ -1167,7 +1167,7 @@ static int sctp_bind_addrs(struct socket *sock, uint16_t port) - int i, addr_len, result = 0; - - for (i = 0; i < dlm_local_count; i++) { -- memcpy(&localaddr, dlm_local_addr[i], sizeof(localaddr)); -+ memcpy(&localaddr, &dlm_local_addr[i], sizeof(localaddr)); - make_sockaddr(&localaddr, port, &addr_len); - - if (!i) -@@ -1187,7 +1187,7 @@ static int sctp_bind_addrs(struct socket *sock, uint16_t port) - /* Get local addresses */ - static void init_local(void) - { -- struct sockaddr_storage sas, *addr; -+ struct sockaddr_storage sas; - int i; - - dlm_local_count = 0; -@@ -1195,21 +1195,10 @@ static void init_local(void) - if (dlm_our_addr(&sas, i)) - break; - -- addr = kmemdup(&sas, sizeof(*addr), GFP_NOFS); -- if (!addr) -- break; -- dlm_local_addr[dlm_local_count++] = addr; -+ memcpy(&dlm_local_addr[dlm_local_count++], &sas, sizeof(sas)); - } - } - --static void deinit_local(void) --{ -- int i; -- -- for (i = 0; i < dlm_local_count; i++) -- kfree(dlm_local_addr[i]); --} -- - static struct writequeue_entry *new_writequeue_entry(struct connection *con) - { - struct writequeue_entry *entry; -@@ -1575,7 +1564,7 @@ static void dlm_connect(struct connection *con) - } - - /* Create a socket to communicate with */ -- result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, -+ result = sock_create_kern(&init_net, dlm_local_addr[0].ss_family, - SOCK_STREAM, dlm_proto_ops->proto, &sock); - if (result < 0) - goto socket_err; -@@ -1786,7 +1775,6 @@ void dlm_lowcomms_stop(void) - foreach_conn(free_conn); - srcu_read_unlock(&connections_srcu, idx); - work_stop(); -- deinit_local(); - - dlm_proto_ops = NULL; - } -@@ -1803,7 +1791,7 @@ static int dlm_listen_for_all(void) - if (result < 0) - return result; - -- result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, -+ result = sock_create_kern(&init_net, dlm_local_addr[0].ss_family, - SOCK_STREAM, dlm_proto_ops->proto, &sock); - if (result < 0) { - log_print("Can't create comms socket: %d", result); -@@ -1842,7 +1830,7 @@ static int dlm_tcp_bind(struct socket *sock) - /* Bind to our cluster-known address connecting to avoid - * routing problems. - */ -- memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr)); -+ memcpy(&src_addr, &dlm_local_addr[0], sizeof(src_addr)); - make_sockaddr(&src_addr, 0, &addr_len); - - result = kernel_bind(sock, (struct sockaddr *)&src_addr, -@@ -1899,9 +1887,9 @@ static int dlm_tcp_listen_bind(struct socket *sock) - int addr_len; - - /* Bind to our port */ -- make_sockaddr(dlm_local_addr[0], dlm_config.ci_tcp_port, &addr_len); -+ make_sockaddr(&dlm_local_addr[0], dlm_config.ci_tcp_port, &addr_len); - return kernel_bind(sock, (struct sockaddr *)&dlm_local_addr[0], -- addr_len); -+ addr_len); - } - - static const struct dlm_proto_ops dlm_tcp_ops = { -@@ -1992,7 +1980,7 @@ int dlm_lowcomms_start(void) - - error = work_start(); - if (error) -- goto fail_local; -+ goto fail; - - dlm_allow_conn = 1; - -@@ -2022,8 +2010,6 @@ fail_listen: - fail_proto_ops: - dlm_allow_conn = 0; - work_stop(); --fail_local: -- deinit_local(); - fail: - return error; - } -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index c1515daf1def1..40903c172a34f 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -1118,6 +1118,24 @@ void ext4_mb_generate_buddy(struct super_block *sb, - atomic64_add(period, &sbi->s_mb_generation_time); - } - -+static void mb_regenerate_buddy(struct ext4_buddy *e4b) -+{ -+ int count; -+ int order = 1; -+ void *buddy; -+ -+ while ((buddy = mb_find_buddy(e4b, order++, &count))) -+ mb_set_bits(buddy, 0, count); -+ -+ e4b->bd_info->bb_fragments = 0; -+ memset(e4b->bd_info->bb_counters, 0, -+ sizeof(*e4b->bd_info->bb_counters) * -+ (e4b->bd_sb->s_blocksize_bits + 2)); -+ -+ ext4_mb_generate_buddy(e4b->bd_sb, e4b->bd_buddy, -+ e4b->bd_bitmap, e4b->bd_group, e4b->bd_info); -+} -+ - /* The buddy information is attached the buddy cache inode - * for convenience. The information regarding each group - * is loaded via ext4_mb_load_buddy. The information involve -@@ -1796,6 +1814,8 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, - ext4_mark_group_bitmap_corrupted( - sb, e4b->bd_group, - EXT4_GROUP_INFO_BBITMAP_CORRUPT); -+ } else { -+ mb_regenerate_buddy(e4b); - } - goto done; - } -diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c -index 3d9f6495a4db4..967262c37da52 100644 ---- a/fs/f2fs/compress.c -+++ b/fs/f2fs/compress.c -@@ -55,6 +55,7 @@ struct f2fs_compress_ops { - int (*init_decompress_ctx)(struct decompress_io_ctx *dic); - void (*destroy_decompress_ctx)(struct decompress_io_ctx *dic); - int (*decompress_pages)(struct decompress_io_ctx *dic); -+ bool (*is_level_valid)(int level); - }; - - static unsigned int offset_in_cluster(struct compress_ctx *cc, pgoff_t index) -@@ -322,11 +323,21 @@ static int lz4_decompress_pages(struct decompress_io_ctx *dic) - return 0; - } - -+static bool lz4_is_level_valid(int lvl) -+{ -+#ifdef CONFIG_F2FS_FS_LZ4HC -+ return !lvl || (lvl >= LZ4HC_MIN_CLEVEL && lvl <= LZ4HC_MAX_CLEVEL); -+#else -+ return lvl == 0; -+#endif -+} -+ - static const struct f2fs_compress_ops f2fs_lz4_ops = { - .init_compress_ctx = lz4_init_compress_ctx, - .destroy_compress_ctx = lz4_destroy_compress_ctx, - .compress_pages = lz4_compress_pages, - .decompress_pages = lz4_decompress_pages, -+ .is_level_valid = lz4_is_level_valid, - }; - #endif - -@@ -490,6 +501,11 @@ static int zstd_decompress_pages(struct decompress_io_ctx *dic) - return 0; - } - -+static bool zstd_is_level_valid(int lvl) -+{ -+ return lvl >= zstd_min_clevel() && lvl <= zstd_max_clevel(); -+} -+ - static const struct f2fs_compress_ops f2fs_zstd_ops = { - .init_compress_ctx = zstd_init_compress_ctx, - .destroy_compress_ctx = zstd_destroy_compress_ctx, -@@ -497,6 +513,7 @@ static const struct f2fs_compress_ops f2fs_zstd_ops = { - .init_decompress_ctx = zstd_init_decompress_ctx, - .destroy_decompress_ctx = zstd_destroy_decompress_ctx, - .decompress_pages = zstd_decompress_pages, -+ .is_level_valid = zstd_is_level_valid, - }; - #endif - -@@ -555,6 +572,16 @@ bool f2fs_is_compress_backend_ready(struct inode *inode) - return f2fs_cops[F2FS_I(inode)->i_compress_algorithm]; - } - -+bool f2fs_is_compress_level_valid(int alg, int lvl) -+{ -+ const struct f2fs_compress_ops *cops = f2fs_cops[alg]; -+ -+ if (cops->is_level_valid) -+ return cops->is_level_valid(lvl); -+ -+ return lvl == 0; -+} -+ - static mempool_t *compress_page_pool; - static int num_compress_pages = 512; - module_param(num_compress_pages, uint, 0444); -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 5c76ba764b71f..e5a9498b89c06 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -4219,6 +4219,7 @@ bool f2fs_compress_write_end(struct inode *inode, void *fsdata, - int f2fs_truncate_partial_cluster(struct inode *inode, u64 from, bool lock); - void f2fs_compress_write_end_io(struct bio *bio, struct page *page); - bool f2fs_is_compress_backend_ready(struct inode *inode); -+bool f2fs_is_compress_level_valid(int alg, int lvl); - int f2fs_init_compress_mempool(void); - void f2fs_destroy_compress_mempool(void); - void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task); -@@ -4283,6 +4284,7 @@ static inline bool f2fs_is_compress_backend_ready(struct inode *inode) - /* not support compression */ - return false; - } -+static inline bool f2fs_is_compress_level_valid(int alg, int lvl) { return false; } - static inline struct page *f2fs_compress_control_page(struct page *page) - { - WARN_ON_ONCE(1); -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 3805162dcef2b..0c0d0671febea 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -628,7 +628,7 @@ static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) - if (kstrtouint(str + 1, 10, &level)) - return -EINVAL; - -- if (level < LZ4HC_MIN_CLEVEL || level > LZ4HC_MAX_CLEVEL) { -+ if (!f2fs_is_compress_level_valid(COMPRESS_LZ4, level)) { - f2fs_info(sbi, "invalid lz4hc compress level: %d", level); - return -EINVAL; - } -@@ -666,7 +666,7 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) - if (kstrtouint(str + 1, 10, &level)) - return -EINVAL; - -- if (level < zstd_min_clevel() || level > zstd_max_clevel()) { -+ if (!f2fs_is_compress_level_valid(COMPRESS_ZSTD, level)) { - f2fs_info(sbi, "invalid zstd compress level: %d", level); - return -EINVAL; - } -diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h -index 8c9abaf139e67..74482ef569ab7 100644 ---- a/fs/ntfs3/ntfs_fs.h -+++ b/fs/ntfs3/ntfs_fs.h -@@ -467,7 +467,7 @@ bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn, - int al_update(struct ntfs_inode *ni, int sync); - static inline size_t al_aligned(size_t size) - { -- return (size + 1023) & ~(size_t)1023; -+ return size_add(size, 1023) & ~(size_t)1023; - } - - /* Globals from bitfunc.c */ -diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c -index 634035bcb9347..b8e14bcd2c68d 100644 ---- a/fs/smb/client/sess.c -+++ b/fs/smb/client/sess.c -@@ -248,6 +248,8 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - &iface->sockaddr, - rc); - kref_put(&iface->refcount, release_iface); -+ /* failure to add chan should increase weight */ -+ iface->weight_fulfilled++; - continue; - } - -diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index c923f4e60f240..3576c6e89fea4 100644 ---- a/include/linux/dmaengine.h -+++ b/include/linux/dmaengine.h -@@ -954,7 +954,8 @@ static inline int dmaengine_slave_config(struct dma_chan *chan, - - static inline bool is_slave_direction(enum dma_transfer_direction direction) - { -- return (direction == DMA_MEM_TO_DEV) || (direction == DMA_DEV_TO_MEM); -+ return (direction == DMA_MEM_TO_DEV) || (direction == DMA_DEV_TO_MEM) || -+ (direction == DMA_DEV_TO_DEV); - } - - static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index f2044d5a652b5..254d4a898179c 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -197,6 +197,7 @@ enum hrtimer_base_type { - * @max_hang_time: Maximum time spent in hrtimer_interrupt - * @softirq_expiry_lock: Lock which is taken while softirq based hrtimer are - * expired -+ * @online: CPU is online from an hrtimers point of view - * @timer_waiters: A hrtimer_cancel() invocation waits for the timer - * callback to finish. - * @expires_next: absolute time of the next event, is required for remote -@@ -219,7 +220,8 @@ struct hrtimer_cpu_base { - unsigned int hres_active : 1, - in_hrtirq : 1, - hang_detected : 1, -- softirq_activated : 1; -+ softirq_activated : 1, -+ online : 1; - #ifdef CONFIG_HIGH_RES_TIMERS - unsigned int nr_events; - unsigned short nr_retries; -diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h -index af8f4c304d272..707af820f1a97 100644 ---- a/include/uapi/linux/netfilter/nf_tables.h -+++ b/include/uapi/linux/netfilter/nf_tables.h -@@ -266,9 +266,11 @@ enum nft_rule_attributes { - /** - * enum nft_rule_compat_flags - nf_tables rule compat flags - * -+ * @NFT_RULE_COMPAT_F_UNUSED: unused - * @NFT_RULE_COMPAT_F_INV: invert the check result - */ - enum nft_rule_compat_flags { -+ NFT_RULE_COMPAT_F_UNUSED = (1 << 0), - NFT_RULE_COMPAT_F_INV = (1 << 1), - NFT_RULE_COMPAT_F_MASK = NFT_RULE_COMPAT_F_INV, - }; -diff --git a/io_uring/net.c b/io_uring/net.c -index 67f09a40bcb21..618ab186fe036 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -875,6 +875,7 @@ retry_multishot: - if (!buf) - return -ENOBUFS; - sr->buf = buf; -+ sr->len = len; - } - - ret = import_single_range(ITER_DEST, sr->buf, len, &iov, &msg.msg_iter); -diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c -index 1c90e710d537f..cc6db3bce1b2f 100644 ---- a/kernel/time/clocksource.c -+++ b/kernel/time/clocksource.c -@@ -126,6 +126,7 @@ static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); - static DEFINE_SPINLOCK(watchdog_lock); - static int watchdog_running; - static atomic_t watchdog_reset_pending; -+static int64_t watchdog_max_interval; - - static inline void clocksource_watchdog_lock(unsigned long *flags) - { -@@ -144,6 +145,7 @@ static void __clocksource_change_rating(struct clocksource *cs, int rating); - * Interval: 0.5sec. - */ - #define WATCHDOG_INTERVAL (HZ >> 1) -+#define WATCHDOG_INTERVAL_MAX_NS ((2 * WATCHDOG_INTERVAL) * (NSEC_PER_SEC / HZ)) - - static void clocksource_watchdog_work(struct work_struct *work) - { -@@ -396,8 +398,8 @@ static inline void clocksource_reset_watchdog(void) - static void clocksource_watchdog(struct timer_list *unused) - { - u64 csnow, wdnow, cslast, wdlast, delta; -+ int64_t wd_nsec, cs_nsec, interval; - int next_cpu, reset_pending; -- int64_t wd_nsec, cs_nsec; - struct clocksource *cs; - enum wd_read_status read_ret; - unsigned long extra_wait = 0; -@@ -467,6 +469,27 @@ static void clocksource_watchdog(struct timer_list *unused) - if (atomic_read(&watchdog_reset_pending)) - continue; - -+ /* -+ * The processing of timer softirqs can get delayed (usually -+ * on account of ksoftirqd not getting to run in a timely -+ * manner), which causes the watchdog interval to stretch. -+ * Skew detection may fail for longer watchdog intervals -+ * on account of fixed margins being used. -+ * Some clocksources, e.g. acpi_pm, cannot tolerate -+ * watchdog intervals longer than a few seconds. -+ */ -+ interval = max(cs_nsec, wd_nsec); -+ if (unlikely(interval > WATCHDOG_INTERVAL_MAX_NS)) { -+ if (system_state > SYSTEM_SCHEDULING && -+ interval > 2 * watchdog_max_interval) { -+ watchdog_max_interval = interval; -+ pr_warn("Long readout interval, skipping watchdog check: cs_nsec: %lld wd_nsec: %lld\n", -+ cs_nsec, wd_nsec); -+ } -+ watchdog_timer.expires = jiffies; -+ continue; -+ } -+ - /* Check the deviation from the watchdog clocksource. */ - md = cs->uncertainty_margin + watchdog->uncertainty_margin; - if (abs(cs_nsec - wd_nsec) > md) { -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 5561dabc9b225..8e0aff1d1ea4f 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1082,6 +1082,7 @@ static int enqueue_hrtimer(struct hrtimer *timer, - enum hrtimer_mode mode) - { - debug_activate(timer, mode); -+ WARN_ON_ONCE(!base->cpu_base->online); - - base->cpu_base->active_bases |= 1 << base->index; - -@@ -2180,6 +2181,7 @@ int hrtimers_prepare_cpu(unsigned int cpu) - cpu_base->softirq_next_timer = NULL; - cpu_base->expires_next = KTIME_MAX; - cpu_base->softirq_expires_next = KTIME_MAX; -+ cpu_base->online = 1; - hrtimer_cpu_base_init_expiry_lock(cpu_base); - return 0; - } -@@ -2247,6 +2249,7 @@ int hrtimers_cpu_dying(unsigned int dying_cpu) - smp_call_function_single(ncpu, retrigger_next_event, NULL, 0); - - raw_spin_unlock(&new_base->lock); -+ old_base->online = 0; - raw_spin_unlock(&old_base->lock); - - return 0; -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 2f646335d2183..9408dc3bb42d3 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -1637,10 +1637,12 @@ EXPORT_SYMBOL(inet_current_timestamp); - - int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) - { -- if (sk->sk_family == AF_INET) -+ unsigned int family = READ_ONCE(sk->sk_family); -+ -+ if (family == AF_INET) - return ip_recv_error(sk, msg, len, addr_len); - #if IS_ENABLED(CONFIG_IPV6) -- if (sk->sk_family == AF_INET6) -+ if (family == AF_INET6) - return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); - #endif - return -EINVAL; -diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c -index 586b1b3e35b80..80ccd6661aa32 100644 ---- a/net/ipv4/ip_tunnel_core.c -+++ b/net/ipv4/ip_tunnel_core.c -@@ -332,7 +332,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu) - }; - skb_reset_network_header(skb); - -- csum = csum_partial(icmp6h, len, 0); -+ csum = skb_checksum(skb, skb_transport_offset(skb), len, 0); - icmp6h->icmp6_cksum = csum_ipv6_magic(&nip6h->saddr, &nip6h->daddr, len, - IPPROTO_ICMPV6, csum); - -diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c -index c07645c999f9a..c6f0da028a2a4 100644 ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -7221,8 +7221,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, - - rcu_read_lock(); - beacon_ies = rcu_dereference(req->bss->beacon_ies); -- -- if (beacon_ies) { -+ if (!beacon_ies) { - /* - * Wait up to one beacon interval ... - * should this be more if we miss one? -diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c -index 6952da7dfc02c..e1623fbf36548 100644 ---- a/net/netfilter/nft_compat.c -+++ b/net/netfilter/nft_compat.c -@@ -135,7 +135,7 @@ static void nft_target_eval_bridge(const struct nft_expr *expr, - - static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = { - [NFTA_TARGET_NAME] = { .type = NLA_NUL_STRING }, -- [NFTA_TARGET_REV] = { .type = NLA_U32 }, -+ [NFTA_TARGET_REV] = NLA_POLICY_MAX(NLA_BE32, 255), - [NFTA_TARGET_INFO] = { .type = NLA_BINARY }, - }; - -@@ -200,6 +200,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] - static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) - { - struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; -+ u32 l4proto; - u32 flags; - int err; - -@@ -212,12 +213,18 @@ static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) - return -EINVAL; - - flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS])); -- if (flags & ~NFT_RULE_COMPAT_F_MASK) -+ if (flags & NFT_RULE_COMPAT_F_UNUSED || -+ flags & ~NFT_RULE_COMPAT_F_MASK) - return -EINVAL; - if (flags & NFT_RULE_COMPAT_F_INV) - *inv = true; - -- *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); -+ l4proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO])); -+ if (l4proto > U16_MAX) -+ return -EINVAL; -+ -+ *proto = l4proto; -+ - return 0; - } - -@@ -418,7 +425,7 @@ static void nft_match_eval(const struct nft_expr *expr, - - static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { - [NFTA_MATCH_NAME] = { .type = NLA_NUL_STRING }, -- [NFTA_MATCH_REV] = { .type = NLA_U32 }, -+ [NFTA_MATCH_REV] = NLA_POLICY_MAX(NLA_BE32, 255), - [NFTA_MATCH_INFO] = { .type = NLA_BINARY }, - }; - -@@ -721,7 +728,7 @@ out_put: - static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = { - [NFTA_COMPAT_NAME] = { .type = NLA_NUL_STRING, - .len = NFT_COMPAT_NAME_MAX-1 }, -- [NFTA_COMPAT_REV] = { .type = NLA_U32 }, -+ [NFTA_COMPAT_REV] = NLA_POLICY_MAX(NLA_BE32, 255), - [NFTA_COMPAT_TYPE] = { .type = NLA_U32 }, - }; - -diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c -index 1101665f52537..8df7564f0611e 100644 ---- a/net/netfilter/nft_ct.c -+++ b/net/netfilter/nft_ct.c -@@ -484,6 +484,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, - break; - #endif - case NFT_CT_ID: -+ if (tb[NFTA_CT_DIRECTION]) -+ return -EINVAL; -+ - len = sizeof(u32); - break; - default: -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index 4e1cc31729b80..e1969209b3abb 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -342,9 +342,6 @@ - #include "nft_set_pipapo_avx2.h" - #include "nft_set_pipapo.h" - --/* Current working bitmap index, toggled between field matches */ --static DEFINE_PER_CPU(bool, nft_pipapo_scratch_index); -- - /** - * pipapo_refill() - For each set bit, set bits from selected mapping table item - * @map: Bitmap to be scanned for set bits -@@ -412,6 +409,7 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, - const u32 *key, const struct nft_set_ext **ext) - { - struct nft_pipapo *priv = nft_set_priv(set); -+ struct nft_pipapo_scratch *scratch; - unsigned long *res_map, *fill_map; - u8 genmask = nft_genmask_cur(net); - const u8 *rp = (const u8 *)key; -@@ -422,15 +420,17 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set, - - local_bh_disable(); - -- map_index = raw_cpu_read(nft_pipapo_scratch_index); -- - m = rcu_dereference(priv->match); - - if (unlikely(!m || !*raw_cpu_ptr(m->scratch))) - goto out; - -- res_map = *raw_cpu_ptr(m->scratch) + (map_index ? m->bsize_max : 0); -- fill_map = *raw_cpu_ptr(m->scratch) + (map_index ? 0 : m->bsize_max); -+ scratch = *raw_cpu_ptr(m->scratch); -+ -+ map_index = scratch->map_index; -+ -+ res_map = scratch->map + (map_index ? m->bsize_max : 0); -+ fill_map = scratch->map + (map_index ? 0 : m->bsize_max); - - memset(res_map, 0xff, m->bsize_max * sizeof(*res_map)); - -@@ -460,7 +460,7 @@ next_match: - b = pipapo_refill(res_map, f->bsize, f->rules, fill_map, f->mt, - last); - if (b < 0) { -- raw_cpu_write(nft_pipapo_scratch_index, map_index); -+ scratch->map_index = map_index; - local_bh_enable(); - - return false; -@@ -477,7 +477,7 @@ next_match: - * current inactive bitmap is clean and can be reused as - * *next* bitmap (not initial) for the next packet. - */ -- raw_cpu_write(nft_pipapo_scratch_index, map_index); -+ scratch->map_index = map_index; - local_bh_enable(); - - return true; -@@ -1101,6 +1101,25 @@ static void pipapo_map(struct nft_pipapo_match *m, - f->mt[map[i].to + j].e = e; - } - -+/** -+ * pipapo_free_scratch() - Free per-CPU map at original (not aligned) address -+ * @m: Matching data -+ * @cpu: CPU number -+ */ -+static void pipapo_free_scratch(const struct nft_pipapo_match *m, unsigned int cpu) -+{ -+ struct nft_pipapo_scratch *s; -+ void *mem; -+ -+ s = *per_cpu_ptr(m->scratch, cpu); -+ if (!s) -+ return; -+ -+ mem = s; -+ mem -= s->align_off; -+ kfree(mem); -+} -+ - /** - * pipapo_realloc_scratch() - Reallocate scratch maps for partial match results - * @clone: Copy of matching data with pending insertions and deletions -@@ -1114,12 +1133,13 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone, - int i; - - for_each_possible_cpu(i) { -- unsigned long *scratch; -+ struct nft_pipapo_scratch *scratch; - #ifdef NFT_PIPAPO_ALIGN -- unsigned long *scratch_aligned; -+ void *scratch_aligned; -+ u32 align_off; - #endif -- -- scratch = kzalloc_node(bsize_max * sizeof(*scratch) * 2 + -+ scratch = kzalloc_node(struct_size(scratch, map, -+ bsize_max * 2) + - NFT_PIPAPO_ALIGN_HEADROOM, - GFP_KERNEL, cpu_to_node(i)); - if (!scratch) { -@@ -1133,14 +1153,25 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone, - return -ENOMEM; - } - -- kfree(*per_cpu_ptr(clone->scratch, i)); -- -- *per_cpu_ptr(clone->scratch, i) = scratch; -+ pipapo_free_scratch(clone, i); - - #ifdef NFT_PIPAPO_ALIGN -- scratch_aligned = NFT_PIPAPO_LT_ALIGN(scratch); -- *per_cpu_ptr(clone->scratch_aligned, i) = scratch_aligned; -+ /* Align &scratch->map (not the struct itself): the extra -+ * %NFT_PIPAPO_ALIGN_HEADROOM bytes passed to kzalloc_node() -+ * above guarantee we can waste up to those bytes in order -+ * to align the map field regardless of its offset within -+ * the struct. -+ */ -+ BUILD_BUG_ON(offsetof(struct nft_pipapo_scratch, map) > NFT_PIPAPO_ALIGN_HEADROOM); -+ -+ scratch_aligned = NFT_PIPAPO_LT_ALIGN(&scratch->map); -+ scratch_aligned -= offsetof(struct nft_pipapo_scratch, map); -+ align_off = scratch_aligned - (void *)scratch; -+ -+ scratch = scratch_aligned; -+ scratch->align_off = align_off; - #endif -+ *per_cpu_ptr(clone->scratch, i) = scratch; - } - - return 0; -@@ -1294,11 +1325,6 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) - if (!new->scratch) - goto out_scratch; - --#ifdef NFT_PIPAPO_ALIGN -- new->scratch_aligned = alloc_percpu(*new->scratch_aligned); -- if (!new->scratch_aligned) -- goto out_scratch; --#endif - for_each_possible_cpu(i) - *per_cpu_ptr(new->scratch, i) = NULL; - -@@ -1350,10 +1376,7 @@ out_lt: - } - out_scratch_realloc: - for_each_possible_cpu(i) -- kfree(*per_cpu_ptr(new->scratch, i)); --#ifdef NFT_PIPAPO_ALIGN -- free_percpu(new->scratch_aligned); --#endif -+ pipapo_free_scratch(new, i); - out_scratch: - free_percpu(new->scratch); - kfree(new); -@@ -1638,13 +1661,9 @@ static void pipapo_free_match(struct nft_pipapo_match *m) - int i; - - for_each_possible_cpu(i) -- kfree(*per_cpu_ptr(m->scratch, i)); -+ pipapo_free_scratch(m, i); - --#ifdef NFT_PIPAPO_ALIGN -- free_percpu(m->scratch_aligned); --#endif - free_percpu(m->scratch); -- - pipapo_free_fields(m); - - kfree(m); -@@ -2132,7 +2151,7 @@ static int nft_pipapo_init(const struct nft_set *set, - m->field_count = field_count; - m->bsize_max = 0; - -- m->scratch = alloc_percpu(unsigned long *); -+ m->scratch = alloc_percpu(struct nft_pipapo_scratch *); - if (!m->scratch) { - err = -ENOMEM; - goto out_scratch; -@@ -2140,16 +2159,6 @@ static int nft_pipapo_init(const struct nft_set *set, - for_each_possible_cpu(i) - *per_cpu_ptr(m->scratch, i) = NULL; - --#ifdef NFT_PIPAPO_ALIGN -- m->scratch_aligned = alloc_percpu(unsigned long *); -- if (!m->scratch_aligned) { -- err = -ENOMEM; -- goto out_free; -- } -- for_each_possible_cpu(i) -- *per_cpu_ptr(m->scratch_aligned, i) = NULL; --#endif -- - rcu_head_init(&m->rcu); - - nft_pipapo_for_each_field(f, i, m) { -@@ -2180,9 +2189,6 @@ static int nft_pipapo_init(const struct nft_set *set, - return 0; - - out_free: --#ifdef NFT_PIPAPO_ALIGN -- free_percpu(m->scratch_aligned); --#endif - free_percpu(m->scratch); - out_scratch: - kfree(m); -@@ -2236,11 +2242,8 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, - - nft_set_pipapo_match_destroy(ctx, set, m); - --#ifdef NFT_PIPAPO_ALIGN -- free_percpu(m->scratch_aligned); --#endif - for_each_possible_cpu(cpu) -- kfree(*per_cpu_ptr(m->scratch, cpu)); -+ pipapo_free_scratch(m, cpu); - free_percpu(m->scratch); - pipapo_free_fields(m); - kfree(m); -@@ -2253,11 +2256,8 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, - if (priv->dirty) - nft_set_pipapo_match_destroy(ctx, set, m); - --#ifdef NFT_PIPAPO_ALIGN -- free_percpu(priv->clone->scratch_aligned); --#endif - for_each_possible_cpu(cpu) -- kfree(*per_cpu_ptr(priv->clone->scratch, cpu)); -+ pipapo_free_scratch(priv->clone, cpu); - free_percpu(priv->clone->scratch); - - pipapo_free_fields(priv->clone); -diff --git a/net/netfilter/nft_set_pipapo.h b/net/netfilter/nft_set_pipapo.h -index 25a75591583eb..30a3d092cd841 100644 ---- a/net/netfilter/nft_set_pipapo.h -+++ b/net/netfilter/nft_set_pipapo.h -@@ -130,21 +130,29 @@ struct nft_pipapo_field { - union nft_pipapo_map_bucket *mt; - }; - -+/** -+ * struct nft_pipapo_scratch - percpu data used for lookup and matching -+ * @map_index: Current working bitmap index, toggled between field matches -+ * @align_off: Offset to get the originally allocated address -+ * @map: store partial matching results during lookup -+ */ -+struct nft_pipapo_scratch { -+ u8 map_index; -+ u32 align_off; -+ unsigned long map[]; -+}; -+ - /** - * struct nft_pipapo_match - Data used for lookup and matching - * @field_count Amount of fields in set - * @scratch: Preallocated per-CPU maps for partial matching results -- * @scratch_aligned: Version of @scratch aligned to NFT_PIPAPO_ALIGN bytes - * @bsize_max: Maximum lookup table bucket size of all fields, in longs - * @rcu Matching data is swapped on commits - * @f: Fields, with lookup and mapping tables - */ - struct nft_pipapo_match { - int field_count; --#ifdef NFT_PIPAPO_ALIGN -- unsigned long * __percpu *scratch_aligned; --#endif -- unsigned long * __percpu *scratch; -+ struct nft_pipapo_scratch * __percpu *scratch; - size_t bsize_max; - struct rcu_head rcu; - struct nft_pipapo_field f[]; -diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c -index 52e0d026d30ad..90e275bb3e5d7 100644 ---- a/net/netfilter/nft_set_pipapo_avx2.c -+++ b/net/netfilter/nft_set_pipapo_avx2.c -@@ -71,9 +71,6 @@ - #define NFT_PIPAPO_AVX2_ZERO(reg) \ - asm volatile("vpxor %ymm" #reg ", %ymm" #reg ", %ymm" #reg) - --/* Current working bitmap index, toggled between field matches */ --static DEFINE_PER_CPU(bool, nft_pipapo_avx2_scratch_index); -- - /** - * nft_pipapo_avx2_prepare() - Prepare before main algorithm body - * -@@ -1120,11 +1117,12 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, - const u32 *key, const struct nft_set_ext **ext) - { - struct nft_pipapo *priv = nft_set_priv(set); -- unsigned long *res, *fill, *scratch; -+ struct nft_pipapo_scratch *scratch; - u8 genmask = nft_genmask_cur(net); - const u8 *rp = (const u8 *)key; - struct nft_pipapo_match *m; - struct nft_pipapo_field *f; -+ unsigned long *res, *fill; - bool map_index; - int i, ret = 0; - -@@ -1141,15 +1139,16 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set, - */ - kernel_fpu_begin_mask(0); - -- scratch = *raw_cpu_ptr(m->scratch_aligned); -+ scratch = *raw_cpu_ptr(m->scratch); - if (unlikely(!scratch)) { - kernel_fpu_end(); - return false; - } -- map_index = raw_cpu_read(nft_pipapo_avx2_scratch_index); - -- res = scratch + (map_index ? m->bsize_max : 0); -- fill = scratch + (map_index ? 0 : m->bsize_max); -+ map_index = scratch->map_index; -+ -+ res = scratch->map + (map_index ? m->bsize_max : 0); -+ fill = scratch->map + (map_index ? 0 : m->bsize_max); - - /* Starting map doesn't need to be set for this implementation */ - -@@ -1221,7 +1220,7 @@ next_match: - - out: - if (i % 2) -- raw_cpu_write(nft_pipapo_avx2_scratch_index, !map_index); -+ scratch->map_index = !map_index; - kernel_fpu_end(); - - return ret >= 0; -diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c -index e34662f4a71e0..5bf5572e945cc 100644 ---- a/net/netfilter/nft_set_rbtree.c -+++ b/net/netfilter/nft_set_rbtree.c -@@ -235,7 +235,7 @@ static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, - - static const struct nft_rbtree_elem * - nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, -- struct nft_rbtree_elem *rbe, u8 genmask) -+ struct nft_rbtree_elem *rbe) - { - struct nft_set *set = (struct nft_set *)__set; - struct rb_node *prev = rb_prev(&rbe->node); -@@ -254,7 +254,7 @@ nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, - while (prev) { - rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); - if (nft_rbtree_interval_end(rbe_prev) && -- nft_set_elem_active(&rbe_prev->ext, genmask)) -+ nft_set_elem_active(&rbe_prev->ext, NFT_GENMASK_ANY)) - break; - - prev = rb_prev(prev); -@@ -365,7 +365,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, - nft_set_elem_active(&rbe->ext, cur_genmask)) { - const struct nft_rbtree_elem *removed_end; - -- removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask); -+ removed_end = nft_rbtree_gc_elem(set, priv, rbe); - if (IS_ERR(removed_end)) - return PTR_ERR(removed_end); - -diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c -index aab0697013982..5d91ef562ff78 100644 ---- a/net/rxrpc/conn_event.c -+++ b/net/rxrpc/conn_event.c -@@ -41,6 +41,14 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, - - _enter("%d", conn->debug_id); - -+ if (sp && sp->hdr.type == RXRPC_PACKET_TYPE_ACK) { -+ if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), -+ &pkt.ack, sizeof(pkt.ack)) < 0) -+ return; -+ if (pkt.ack.reason == RXRPC_ACK_PING_RESPONSE) -+ return; -+ } -+ - chan = &conn->channels[channel]; - - /* If the last call got moved on whilst we were waiting to run, just -diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c -index cdcd2731860ba..1cb9935620886 100644 ---- a/net/tipc/bearer.c -+++ b/net/tipc/bearer.c -@@ -1088,6 +1088,12 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) - - #ifdef CONFIG_TIPC_MEDIA_UDP - if (attrs[TIPC_NLA_BEARER_UDP_OPTS]) { -+ if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) { -+ rtnl_unlock(); -+ NL_SET_ERR_MSG(info->extack, "UDP option is unsupported"); -+ return -EINVAL; -+ } -+ - err = tipc_udp_nl_bearer_add(b, - attrs[TIPC_NLA_BEARER_UDP_OPTS]); - if (err) { -diff --git a/net/unix/garbage.c b/net/unix/garbage.c -index dc27635403932..767b338a7a2d4 100644 ---- a/net/unix/garbage.c -+++ b/net/unix/garbage.c -@@ -314,6 +314,17 @@ void unix_gc(void) - /* Here we are. Hitlist is filled. Die. */ - __skb_queue_purge(&hitlist); - -+#if IS_ENABLED(CONFIG_AF_UNIX_OOB) -+ list_for_each_entry_safe(u, next, &gc_candidates, link) { -+ struct sk_buff *skb = u->oob_skb; -+ -+ if (skb) { -+ u->oob_skb = NULL; -+ kfree_skb(skb); -+ } -+ } -+#endif -+ - spin_lock(&unix_gc_lock); - - /* There could be io_uring registered files, just push them back to -diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c -index 9ee71a99a0871..0932473b63945 100644 ---- a/sound/soc/amd/acp-config.c -+++ b/sound/soc/amd/acp-config.c -@@ -3,7 +3,7 @@ - // This file is provided under a dual BSD/GPLv2 license. When using or - // redistributing this file, you may do so under either license. - // --// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. -+// Copyright(c) 2021 Advanced Micro Devices, Inc. - // - // Authors: Ajit Kumar Pandey - // -@@ -35,19 +35,6 @@ static const struct config_entry config_table[] = { - {} - }, - }, -- { -- .flags = FLAG_AMD_LEGACY, -- .device = ACP_PCI_DEV_ID, -- .dmi_table = (const struct dmi_system_id []) { -- { -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "Valve"), -- DMI_MATCH(DMI_PRODUCT_NAME, "Jupiter"), -- }, -- }, -- {} -- }, -- }, - { - .flags = FLAG_AMD_SOF, - .device = ACP_PCI_DEV_ID, -diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c -index 33380cad3a735..b8a474a2e4d59 100644 ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -2029,10 +2029,14 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */ - QUIRK_FLAG_GENERIC_IMPLICIT_FB), -+ DEVICE_FLG(0x0499, 0x3108, /* Yamaha YIT-W12TX */ -+ QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */ - QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */ - QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M), -+ DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ -+ QUIRK_FLAG_IFACE_SKIP_CLOSE), - DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */ - QUIRK_FLAG_SET_IFACE_FIRST), - DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */ -@@ -2071,14 +2075,22 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_GENERIC_IMPLICIT_FB), - DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */ - QUIRK_FLAG_GENERIC_IMPLICIT_FB), -+ DEVICE_FLG(0x07fd, 0x000b, /* MOTU M Series 2nd hardware revision */ -+ QUIRK_FLAG_CTL_MSG_DELAY_1M), - DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */ - QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */ - QUIRK_FLAG_CTL_MSG_DELAY_1M), - DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */ - QUIRK_FLAG_CTL_MSG_DELAY_1M), -+ DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ -+ QUIRK_FLAG_FIXED_RATE), -+ DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ -+ QUIRK_FLAG_FIXED_RATE), - DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */ - QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), -+ DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ -+ QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ - QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */ -@@ -2111,6 +2123,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), - DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */ - QUIRK_FLAG_GET_SAMPLE_RATE), -+ DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */ -+ QUIRK_FLAG_GET_SAMPLE_RATE), -+ DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */ -+ QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */ - QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), - DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */ -@@ -2153,6 +2169,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */ - QUIRK_FLAG_GET_SAMPLE_RATE), -+ DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */ -+ QUIRK_FLAG_GENERIC_IMPLICIT_FB), -+ DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */ -+ QUIRK_FLAG_GENERIC_IMPLICIT_FB), -+ DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ -+ QUIRK_FLAG_GENERIC_IMPLICIT_FB), - DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ - QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ -@@ -2161,22 +2183,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_ALIGN_TRANSFER), - DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ - QUIRK_FLAG_ALIGN_TRANSFER), -- DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ -- QUIRK_FLAG_GET_SAMPLE_RATE), -- DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */ -- QUIRK_FLAG_GENERIC_IMPLICIT_FB), -- DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */ -- QUIRK_FLAG_GENERIC_IMPLICIT_FB), -- DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ -- QUIRK_FLAG_GENERIC_IMPLICIT_FB), -- DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ -- QUIRK_FLAG_IFACE_SKIP_CLOSE), -- DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ -- QUIRK_FLAG_FIXED_RATE), -- DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ -- QUIRK_FLAG_FIXED_RATE), -- DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */ -- QUIRK_FLAG_GET_SAMPLE_RATE), - - /* Vendor matches */ - VENDOR_FLG(0x045e, /* MS Lifecam */ -diff --git a/tools/testing/selftests/net/cmsg_ipv6.sh b/tools/testing/selftests/net/cmsg_ipv6.sh -index 330d0b1ceced3..c921750ca118d 100755 ---- a/tools/testing/selftests/net/cmsg_ipv6.sh -+++ b/tools/testing/selftests/net/cmsg_ipv6.sh -@@ -91,7 +91,7 @@ for ovr in setsock cmsg both diff; do - check_result $? 0 "TCLASS $prot $ovr - pass" - - while [ -d /proc/$BG ]; do -- $NSEXE ./cmsg_sender -6 -p u $TGT6 1234 -+ $NSEXE ./cmsg_sender -6 -p $p $m $((TOS2)) $TGT6 1234 - done - - tcpdump -r $TMPF -v 2>&1 | grep "class $TOS2" >> /dev/null -@@ -128,7 +128,7 @@ for ovr in setsock cmsg both diff; do - check_result $? 0 "HOPLIMIT $prot $ovr - pass" - - while [ -d /proc/$BG ]; do -- $NSEXE ./cmsg_sender -6 -p u $TGT6 1234 -+ $NSEXE ./cmsg_sender -6 -p $p $m $LIM $TGT6 1234 - done - - tcpdump -r $TMPF -v 2>&1 | grep "hlim $LIM[^0-9]" >> /dev/null -diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh -index 1b6e484e586dc..00ab4c6e40446 100755 ---- a/tools/testing/selftests/net/pmtu.sh -+++ b/tools/testing/selftests/net/pmtu.sh -@@ -1928,6 +1928,13 @@ check_command() { - return 0 - } - -+check_running() { -+ pid=${1} -+ cmd=${2} -+ -+ [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "{cmd}" ] -+} -+ - test_cleanup_vxlanX_exception() { - outer="${1}" - encap="vxlan" -@@ -1958,11 +1965,12 @@ test_cleanup_vxlanX_exception() { - - ${ns_a} ip link del dev veth_A-R1 & - iplink_pid=$! -- sleep 1 -- if [ "$(cat /proc/${iplink_pid}/cmdline 2>/dev/null | tr -d '\0')" = "iplinkdeldevveth_A-R1" ]; then -- err " can't delete veth device in a timely manner, PMTU dst likely leaked" -- return 1 -- fi -+ for i in $(seq 1 20); do -+ check_running ${iplink_pid} "iplinkdeldevveth_A-R1" || return 0 -+ sleep 0.1 -+ done -+ err " can't delete veth device in a timely manner, PMTU dst likely leaked" -+ return 1 - } - - test_cleanup_ipv6_exception() { -diff --git a/tools/testing/selftests/net/udpgro_fwd.sh b/tools/testing/selftests/net/udpgro_fwd.sh -index c079565add392..9690a5d7ffd7d 100755 ---- a/tools/testing/selftests/net/udpgro_fwd.sh -+++ b/tools/testing/selftests/net/udpgro_fwd.sh -@@ -37,6 +37,10 @@ create_ns() { - for ns in $NS_SRC $NS_DST; do - ip netns add $ns - ip -n $ns link set dev lo up -+ -+ # disable route solicitations to decrease 'noise' traffic -+ ip netns exec $ns sysctl -qw net.ipv6.conf.default.router_solicitations=0 -+ ip netns exec $ns sysctl -qw net.ipv6.conf.all.router_solicitations=0 - done - - ip link add name veth$SRC type veth peer name veth$DST -@@ -78,6 +82,12 @@ create_vxlan_pair() { - create_vxlan_endpoint $BASE$ns veth$ns $BM_NET_V6$((3 - $ns)) vxlan6$ns 6 - ip -n $BASE$ns addr add dev vxlan6$ns $OL_NET_V6$ns/24 nodad - done -+ -+ # preload neighbur cache, do avoid some noisy traffic -+ local addr_dst=$(ip -j -n $BASE$DST link show dev vxlan6$DST |jq -r '.[]["address"]') -+ local addr_src=$(ip -j -n $BASE$SRC link show dev vxlan6$SRC |jq -r '.[]["address"]') -+ ip -n $BASE$DST neigh add dev vxlan6$DST lladdr $addr_src $OL_NET_V6$SRC -+ ip -n $BASE$SRC neigh add dev vxlan6$SRC lladdr $addr_dst $OL_NET_V6$DST - } - - is_ipv6() { -@@ -117,7 +127,7 @@ run_test() { - # not enable GRO - ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 4789 - ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000 -- ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args & -+ ip netns exec $NS_DST ./udpgso_bench_rx -C 2000 -R 100 -n 10 -l 1300 $rx_args & - local spid=$! - sleep 0.1 - ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst -@@ -166,7 +176,7 @@ run_bench() { - # bind the sender and the receiver to different CPUs to try - # get reproducible results - ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus" -- ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 & -+ ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 2000 -R 100 & - local spid=$! - sleep 0.1 - ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst -diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c -index f35a924d4a303..1cbadd267c963 100644 ---- a/tools/testing/selftests/net/udpgso_bench_rx.c -+++ b/tools/testing/selftests/net/udpgso_bench_rx.c -@@ -375,7 +375,7 @@ static void do_recv(void) - do_flush_udp(fd); - - tnow = gettimeofday_ms(); -- if (tnow > treport) { -+ if (!cfg_expected_pkt_nr && tnow > treport) { - if (packets) - fprintf(stderr, - "%s rx: %6lu MB/s %8lu calls/s\n", diff --git a/patch/kernel/odroidxu4-current/patch-6.1.78-79.patch b/patch/kernel/odroidxu4-current/patch-6.1.78-79.patch deleted file mode 100644 index 1136d0338a..0000000000 --- a/patch/kernel/odroidxu4-current/patch-6.1.78-79.patch +++ /dev/null @@ -1,9468 +0,0 @@ -diff --git a/Documentation/ABI/testing/sysfs-class-net-statistics b/Documentation/ABI/testing/sysfs-class-net-statistics -index 55db27815361b..53e508c6936a5 100644 ---- a/Documentation/ABI/testing/sysfs-class-net-statistics -+++ b/Documentation/ABI/testing/sysfs-class-net-statistics -@@ -1,4 +1,4 @@ --What: /sys/class//statistics/collisions -+What: /sys/class/net//statistics/collisions - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -6,7 +6,7 @@ Description: - Indicates the number of collisions seen by this network device. - This value might not be relevant with all MAC layers. - --What: /sys/class//statistics/multicast -+What: /sys/class/net//statistics/multicast - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -14,7 +14,7 @@ Description: - Indicates the number of multicast packets received by this - network device. - --What: /sys/class//statistics/rx_bytes -+What: /sys/class/net//statistics/rx_bytes - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -23,7 +23,7 @@ Description: - See the network driver for the exact meaning of when this - value is incremented. - --What: /sys/class//statistics/rx_compressed -+What: /sys/class/net//statistics/rx_compressed - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -32,7 +32,7 @@ Description: - network device. This value might only be relevant for interfaces - that support packet compression (e.g: PPP). - --What: /sys/class//statistics/rx_crc_errors -+What: /sys/class/net//statistics/rx_crc_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -41,7 +41,7 @@ Description: - by this network device. Note that the specific meaning might - depend on the MAC layer used by the interface. - --What: /sys/class//statistics/rx_dropped -+What: /sys/class/net//statistics/rx_dropped - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -51,7 +51,7 @@ Description: - packet processing. See the network driver for the exact - meaning of this value. - --What: /sys/class//statistics/rx_errors -+What: /sys/class/net//statistics/rx_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -59,7 +59,7 @@ Description: - Indicates the number of receive errors on this network device. - See the network driver for the exact meaning of this value. - --What: /sys/class//statistics/rx_fifo_errors -+What: /sys/class/net//statistics/rx_fifo_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -68,7 +68,7 @@ Description: - network device. See the network driver for the exact - meaning of this value. - --What: /sys/class//statistics/rx_frame_errors -+What: /sys/class/net//statistics/rx_frame_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -78,7 +78,7 @@ Description: - on the MAC layer protocol used. See the network driver for - the exact meaning of this value. - --What: /sys/class//statistics/rx_length_errors -+What: /sys/class/net//statistics/rx_length_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -87,7 +87,7 @@ Description: - error, oversized or undersized. See the network driver for the - exact meaning of this value. - --What: /sys/class//statistics/rx_missed_errors -+What: /sys/class/net//statistics/rx_missed_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -96,7 +96,7 @@ Description: - due to lack of capacity in the receive side. See the network - driver for the exact meaning of this value. - --What: /sys/class//statistics/rx_nohandler -+What: /sys/class/net//statistics/rx_nohandler - Date: February 2016 - KernelVersion: 4.6 - Contact: netdev@vger.kernel.org -@@ -104,7 +104,7 @@ Description: - Indicates the number of received packets that were dropped on - an inactive device by the network core. - --What: /sys/class//statistics/rx_over_errors -+What: /sys/class/net//statistics/rx_over_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -114,7 +114,7 @@ Description: - (e.g: larger than MTU). See the network driver for the exact - meaning of this value. - --What: /sys/class//statistics/rx_packets -+What: /sys/class/net//statistics/rx_packets - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -122,7 +122,7 @@ Description: - Indicates the total number of good packets received by this - network device. - --What: /sys/class//statistics/tx_aborted_errors -+What: /sys/class/net//statistics/tx_aborted_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -132,7 +132,7 @@ Description: - a medium collision). See the network driver for the exact - meaning of this value. - --What: /sys/class//statistics/tx_bytes -+What: /sys/class/net//statistics/tx_bytes - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -143,7 +143,7 @@ Description: - transmitted packets or all packets that have been queued for - transmission. - --What: /sys/class//statistics/tx_carrier_errors -+What: /sys/class/net//statistics/tx_carrier_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -152,7 +152,7 @@ Description: - because of carrier errors (e.g: physical link down). See the - network driver for the exact meaning of this value. - --What: /sys/class//statistics/tx_compressed -+What: /sys/class/net//statistics/tx_compressed - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -161,7 +161,7 @@ Description: - this might only be relevant for devices that support - compression (e.g: PPP). - --What: /sys/class//statistics/tx_dropped -+What: /sys/class/net//statistics/tx_dropped - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -170,7 +170,7 @@ Description: - See the driver for the exact reasons as to why the packets were - dropped. - --What: /sys/class//statistics/tx_errors -+What: /sys/class/net//statistics/tx_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -179,7 +179,7 @@ Description: - a network device. See the driver for the exact reasons as to - why the packets were dropped. - --What: /sys/class//statistics/tx_fifo_errors -+What: /sys/class/net//statistics/tx_fifo_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -188,7 +188,7 @@ Description: - FIFO error. See the driver for the exact reasons as to why the - packets were dropped. - --What: /sys/class//statistics/tx_heartbeat_errors -+What: /sys/class/net//statistics/tx_heartbeat_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -197,7 +197,7 @@ Description: - reported as heartbeat errors. See the driver for the exact - reasons as to why the packets were dropped. - --What: /sys/class//statistics/tx_packets -+What: /sys/class/net//statistics/tx_packets - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -@@ -206,7 +206,7 @@ Description: - device. See the driver for whether this reports the number of all - attempted or successful transmissions. - --What: /sys/class//statistics/tx_window_errors -+What: /sys/class/net//statistics/tx_window_errors - Date: April 2005 - KernelVersion: 2.6.12 - Contact: netdev@vger.kernel.org -diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst -index d9fce65b2f047..27135b9c07acb 100644 ---- a/Documentation/arm64/silicon-errata.rst -+++ b/Documentation/arm64/silicon-errata.rst -@@ -221,3 +221,10 @@ stable kernels. - +----------------+-----------------+-----------------+-----------------------------+ - | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | - +----------------+-----------------+-----------------+-----------------------------+ -++----------------+-----------------+-----------------+-----------------------------+ -+| Microsoft | Azure Cobalt 100| #2139208 | ARM64_ERRATUM_2139208 | -++----------------+-----------------+-----------------+-----------------------------+ -+| Microsoft | Azure Cobalt 100| #2067961 | ARM64_ERRATUM_2067961 | -++----------------+-----------------+-----------------+-----------------------------+ -+| Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | -++----------------+-----------------+-----------------+-----------------------------+ -diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt -index 9bf9bbac16e25..cdc303caf5f45 100644 ---- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt -+++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt -@@ -1,4 +1,4 @@ --Marvell 8787/8897/8997 (sd8787/sd8897/sd8997/pcie8997) SDIO/PCIE devices -+Marvell 8787/8897/8978/8997 (sd8787/sd8897/sd8978/sd8997/pcie8997) SDIO/PCIE devices - ------ - - This node provides properties for controlling the Marvell SDIO/PCIE wireless device. -@@ -10,7 +10,9 @@ Required properties: - - compatible : should be one of the following: - * "marvell,sd8787" - * "marvell,sd8897" -+ * "marvell,sd8978" - * "marvell,sd8997" -+ * "nxp,iw416" - * "pci11ab,2b42" - * "pci1b4b,2b42" - -diff --git a/Makefile b/Makefile -index e93554269e474..d6bc9f597e8b8 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 78 -+SUBLEVEL = 79 - EXTRAVERSION = - NAME = Curry Ramen - -@@ -459,8 +459,7 @@ HOSTRUSTC = rustc - HOSTPKG_CONFIG = pkg-config - - KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ -- -O2 -fomit-frame-pointer -std=gnu11 \ -- -Wdeclaration-after-statement -+ -O2 -fomit-frame-pointer -std=gnu11 - KBUILD_USERCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS) - KBUILD_USERLDFLAGS := $(USERLDFLAGS) - -@@ -1018,9 +1017,6 @@ endif - # arch Makefile may override CC so keep this after arch Makefile is included - NOSTDINC_FLAGS += -nostdinc - --# warn about C99 declaration after statement --KBUILD_CFLAGS += -Wdeclaration-after-statement -- - # Variable Length Arrays (VLAs) should not be used anywhere in the kernel - KBUILD_CFLAGS += -Wvla - -diff --git a/arch/Kconfig b/arch/Kconfig -index 14273a6203dfc..f99fd9a4ca778 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -642,6 +642,7 @@ config SHADOW_CALL_STACK - bool "Shadow Call Stack" - depends on ARCH_SUPPORTS_SHADOW_CALL_STACK - depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER -+ depends on MMU - help - This option enables the compiler's Shadow Call Stack, which - uses a shadow stack to protect function return addresses from -diff --git a/arch/arc/include/asm/jump_label.h b/arch/arc/include/asm/jump_label.h -index 9d96180797396..a339223d9e052 100644 ---- a/arch/arc/include/asm/jump_label.h -+++ b/arch/arc/include/asm/jump_label.h -@@ -31,7 +31,7 @@ - static __always_inline bool arch_static_branch(struct static_key *key, - bool branch) - { -- asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" -+ asm goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" - "1: \n" - "nop \n" - ".pushsection __jump_table, \"aw\" \n" -@@ -47,7 +47,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, - static __always_inline bool arch_static_branch_jump(struct static_key *key, - bool branch) - { -- asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" -+ asm goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)" \n" - "1: \n" - "b %l[l_yes] \n" - ".pushsection __jump_table, \"aw\" \n" -diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts -index f9f7d99bd4db8..76f3e07bc8826 100644 ---- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts -+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts -@@ -76,6 +76,7 @@ reg_can1_supply: regulator-can1-supply { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enable_can1_power>; - regulator-name = "can1_supply"; -+ startup-delay-us = <1000>; - }; - - reg_can2_supply: regulator-can2-supply { -@@ -85,6 +86,7 @@ reg_can2_supply: regulator-can2-supply { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enable_can2_power>; - regulator-name = "can2_supply"; -+ startup-delay-us = <1000>; - }; - }; - -diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h -index e12d7d096fc03..e4eb54f6cd9fe 100644 ---- a/arch/arm/include/asm/jump_label.h -+++ b/arch/arm/include/asm/jump_label.h -@@ -11,7 +11,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - WASM(nop) "\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".word 1b, %l[l_yes], %c0\n\t" -@@ -25,7 +25,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - WASM(b) " %l[l_yes]\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".word 1b, %l[l_yes], %c0\n\t" -diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -index 9d116e1fbe10c..1ac4f8c24e231 100644 ---- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -@@ -169,10 +169,6 @@ led@6 { - }; - }; - --&blsp_dma { -- status = "okay"; --}; -- - &blsp_i2c2 { - /* On Low speed expansion */ - status = "okay"; -diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi -index bafac2cf7e3d6..987cebbda0571 100644 ---- a/arch/arm64/boot/dts/qcom/msm8916.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi -@@ -1522,7 +1522,7 @@ blsp_dma: dma-controller@7884000 { - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <0>; -- status = "disabled"; -+ qcom,controlled-remotely; - }; - - blsp1_uart1: serial@78af000 { -diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi -index 4d5905ef0b411..95c515da9f2e0 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi -@@ -4049,7 +4049,7 @@ usb_1: usb@a6f8800 { - assigned-clock-rates = <19200000>, <150000000>; - - interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, -+ <&pdc_intc 6 IRQ_TYPE_LEVEL_HIGH>, - <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>, - <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "hs_phy_irq", "ss_phy_irq", -@@ -4100,7 +4100,7 @@ usb_2: usb@a8f8800 { - assigned-clock-rates = <19200000>, <150000000>; - - interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, -+ <&pdc_intc 7 IRQ_TYPE_LEVEL_HIGH>, - <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>, - <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "hs_phy_irq", "ss_phy_irq", -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index 8efd0e227d780..eb1a9369926d2 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -3629,7 +3629,7 @@ usb_1: usb@a6f8800 { - assigned-clock-rates = <19200000>, <200000000>; - - interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, -+ <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 8 IRQ_TYPE_EDGE_BOTH>, - <&pdc 9 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "hs_phy_irq", "ss_phy_irq", -@@ -3678,7 +3678,7 @@ usb_2: usb@a8f8800 { - assigned-clock-rates = <19200000>, <200000000>; - - interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, -- <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, -+ <&pdc 7 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 10 IRQ_TYPE_EDGE_BOTH>, - <&pdc 11 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "hs_phy_irq", "ss_phy_irq", -diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/include/asm/alternative-macros.h -index 3622e9f4fb442..51738c56e96cd 100644 ---- a/arch/arm64/include/asm/alternative-macros.h -+++ b/arch/arm64/include/asm/alternative-macros.h -@@ -229,7 +229,7 @@ alternative_has_feature_likely(unsigned long feature) - compiletime_assert(feature < ARM64_NCAPS, - "feature must be < ARM64_NCAPS"); - -- asm_volatile_goto( -+ asm goto( - ALTERNATIVE_CB("b %l[l_no]", %[feature], alt_cb_patch_nops) - : - : [feature] "i" (feature) -@@ -247,7 +247,7 @@ alternative_has_feature_unlikely(unsigned long feature) - compiletime_assert(feature < ARM64_NCAPS, - "feature must be < ARM64_NCAPS"); - -- asm_volatile_goto( -+ asm goto( - ALTERNATIVE("nop", "b %l[l_yes]", %[feature]) - : - : [feature] "i" (feature) -diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h -index 7dce9c0aa7836..af3a678a76b3a 100644 ---- a/arch/arm64/include/asm/cputype.h -+++ b/arch/arm64/include/asm/cputype.h -@@ -61,6 +61,7 @@ - #define ARM_CPU_IMP_HISI 0x48 - #define ARM_CPU_IMP_APPLE 0x61 - #define ARM_CPU_IMP_AMPERE 0xC0 -+#define ARM_CPU_IMP_MICROSOFT 0x6D - - #define ARM_CPU_PART_AEM_V8 0xD0F - #define ARM_CPU_PART_FOUNDATION 0xD00 -@@ -128,6 +129,8 @@ - - #define AMPERE_CPU_PART_AMPERE1 0xAC3 - -+#define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49 /* Based on r0p0 of ARM Neoverse N2 */ -+ - #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) - #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) - #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) -@@ -179,6 +182,7 @@ - #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) - #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) - #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) -+#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100) - - /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ - #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX -diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h -index cea441b6aa5dc..b5bd3c38a01b2 100644 ---- a/arch/arm64/include/asm/jump_label.h -+++ b/arch/arm64/include/asm/jump_label.h -@@ -18,7 +18,7 @@ - static __always_inline bool arch_static_branch(struct static_key *key, - bool branch) - { -- asm_volatile_goto( -+ asm goto( - "1: nop \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align 3 \n\t" -@@ -35,7 +35,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, - static __always_inline bool arch_static_branch_jump(struct static_key *key, - bool branch) - { -- asm_volatile_goto( -+ asm goto( - "1: b %l[l_yes] \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align 3 \n\t" -diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c -index 61f22e9c92b4c..74584597bfb82 100644 ---- a/arch/arm64/kernel/cpu_errata.c -+++ b/arch/arm64/kernel/cpu_errata.c -@@ -390,6 +390,7 @@ static const struct midr_range erratum_1463225[] = { - static const struct midr_range trbe_overwrite_fill_mode_cpus[] = { - #ifdef CONFIG_ARM64_ERRATUM_2139208 - MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), -+ MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), - #endif - #ifdef CONFIG_ARM64_ERRATUM_2119858 - MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), -@@ -403,6 +404,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = { - static const struct midr_range tsb_flush_fail_cpus[] = { - #ifdef CONFIG_ARM64_ERRATUM_2067961 - MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), -+ MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), - #endif - #ifdef CONFIG_ARM64_ERRATUM_2054223 - MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), -@@ -415,6 +417,7 @@ static const struct midr_range tsb_flush_fail_cpus[] = { - static struct midr_range trbe_write_out_of_range_cpus[] = { - #ifdef CONFIG_ARM64_ERRATUM_2253138 - MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), -+ MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), - #endif - #ifdef CONFIG_ARM64_ERRATUM_2224489 - MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), -diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile -index 36c8f66cad251..d513533cc922f 100644 ---- a/arch/arm64/kernel/vdso32/Makefile -+++ b/arch/arm64/kernel/vdso32/Makefile -@@ -68,11 +68,9 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -fno-common \ - -Werror-implicit-function-declaration \ - -Wno-format-security \ -- -Wdeclaration-after-statement \ - -std=gnu11 - VDSO_CFLAGS += -O2 - # Some useful compiler-dependent flags from top-level Makefile --VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,) - VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) - VDSO_CFLAGS += -fno-strict-overflow - VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) -diff --git a/arch/csky/include/asm/jump_label.h b/arch/csky/include/asm/jump_label.h -index 98a3f4b168bd2..ef2e37a10a0fe 100644 ---- a/arch/csky/include/asm/jump_label.h -+++ b/arch/csky/include/asm/jump_label.h -@@ -12,7 +12,7 @@ - static __always_inline bool arch_static_branch(struct static_key *key, - bool branch) - { -- asm_volatile_goto( -+ asm goto( - "1: nop32 \n" - " .pushsection __jump_table, \"aw\" \n" - " .align 2 \n" -@@ -29,7 +29,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, - static __always_inline bool arch_static_branch_jump(struct static_key *key, - bool branch) - { -- asm_volatile_goto( -+ asm goto( - "1: bsr32 %l[label] \n" - " .pushsection __jump_table, \"aw\" \n" - " .align 2 \n" -diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h -index 4044eaf989ac7..0921ddda11a4b 100644 ---- a/arch/mips/include/asm/checksum.h -+++ b/arch/mips/include/asm/checksum.h -@@ -241,7 +241,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - " .set pop" - : "=&r" (sum), "=&r" (tmp) - : "r" (saddr), "r" (daddr), -- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum)); -+ "0" (htonl(len)), "r" (htonl(proto)), "r" (sum) -+ : "memory"); - - return csum_fold(sum); - } -diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h -index c5c6864e64bc4..405c85173f2c1 100644 ---- a/arch/mips/include/asm/jump_label.h -+++ b/arch/mips/include/asm/jump_label.h -@@ -36,7 +36,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\t" B_INSN " 2f\n\t" -+ asm goto("1:\t" B_INSN " 2f\n\t" - "2:\t.insn\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - WORD_INSN " 1b, %l[l_yes], %0\n\t" -@@ -50,7 +50,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\t" J_INSN " %l[l_yes]\n\t" -+ asm goto("1:\t" J_INSN " %l[l_yes]\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - WORD_INSN " 1b, %l[l_yes], %0\n\t" - ".popsection\n\t" -diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig -index 345d5e021484c..abf39ecda6fb1 100644 ---- a/arch/parisc/Kconfig -+++ b/arch/parisc/Kconfig -@@ -24,7 +24,6 @@ config PARISC - select RTC_DRV_GENERIC - select INIT_ALL_POSSIBLE - select BUG -- select BUILDTIME_TABLE_SORT - select HAVE_PCI - select HAVE_PERF_EVENTS - select HAVE_KERNEL_BZIP2 -diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h -index 74d17d7e759da..5937d5edaba1e 100644 ---- a/arch/parisc/include/asm/assembly.h -+++ b/arch/parisc/include/asm/assembly.h -@@ -576,6 +576,7 @@ - .section __ex_table,"aw" ! \ - .align 4 ! \ - .word (fault_addr - .), (except_addr - .) ! \ -+ or %r0,%r0,%r0 ! \ - .previous - - -diff --git a/arch/parisc/include/asm/extable.h b/arch/parisc/include/asm/extable.h -new file mode 100644 -index 0000000000000..4ea23e3d79dc9 ---- /dev/null -+++ b/arch/parisc/include/asm/extable.h -@@ -0,0 +1,64 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __PARISC_EXTABLE_H -+#define __PARISC_EXTABLE_H -+ -+#include -+#include -+ -+/* -+ * The exception table consists of three addresses: -+ * -+ * - A relative address to the instruction that is allowed to fault. -+ * - A relative address at which the program should continue (fixup routine) -+ * - An asm statement which specifies which CPU register will -+ * receive -EFAULT when an exception happens if the lowest bit in -+ * the fixup address is set. -+ * -+ * Note: The register specified in the err_opcode instruction will be -+ * modified at runtime if a fault happens. Register %r0 will be ignored. -+ * -+ * Since relative addresses are used, 32bit values are sufficient even on -+ * 64bit kernel. -+ */ -+ -+struct pt_regs; -+int fixup_exception(struct pt_regs *regs); -+ -+#define ARCH_HAS_RELATIVE_EXTABLE -+struct exception_table_entry { -+ int insn; /* relative address of insn that is allowed to fault. */ -+ int fixup; /* relative address of fixup routine */ -+ int err_opcode; /* sample opcode with register which holds error code */ -+}; -+ -+#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr, opcode )\ -+ ".section __ex_table,\"aw\"\n" \ -+ ".align 4\n" \ -+ ".word (" #fault_addr " - .), (" #except_addr " - .)\n" \ -+ opcode "\n" \ -+ ".previous\n" -+ -+/* -+ * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry -+ * (with lowest bit set) for which the fault handler in fixup_exception() will -+ * load -EFAULT on fault into the register specified by the err_opcode instruction, -+ * and zeroes the target register in case of a read fault in get_user(). -+ */ -+#define ASM_EXCEPTIONTABLE_VAR(__err_var) \ -+ int __err_var = 0 -+#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr, register )\ -+ ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1, "or %%r0,%%r0," register) -+ -+static inline void swap_ex_entry_fixup(struct exception_table_entry *a, -+ struct exception_table_entry *b, -+ struct exception_table_entry tmp, -+ int delta) -+{ -+ a->fixup = b->fixup + delta; -+ b->fixup = tmp.fixup - delta; -+ a->err_opcode = b->err_opcode; -+ b->err_opcode = tmp.err_opcode; -+} -+#define swap_ex_entry_fixup swap_ex_entry_fixup -+ -+#endif -diff --git a/arch/parisc/include/asm/jump_label.h b/arch/parisc/include/asm/jump_label.h -index 94428798b6aa6..317ebc5edc9fe 100644 ---- a/arch/parisc/include/asm/jump_label.h -+++ b/arch/parisc/include/asm/jump_label.h -@@ -12,7 +12,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".align %1\n\t" -@@ -29,7 +29,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "b,n %l[l_yes]\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".align %1\n\t" -diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h -index c822bd0c0e3c6..51f40eaf77806 100644 ---- a/arch/parisc/include/asm/special_insns.h -+++ b/arch/parisc/include/asm/special_insns.h -@@ -8,7 +8,8 @@ - "copy %%r0,%0\n" \ - "8:\tlpa %%r0(%1),%0\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ -+ "or %%r0,%%r0,%%r0") \ - : "=&r" (pa) \ - : "r" (va) \ - : "memory" \ -@@ -22,7 +23,8 @@ - "copy %%r0,%0\n" \ - "8:\tlpa %%r0(%%sr3,%1),%0\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ -+ "or %%r0,%%r0,%%r0") \ - : "=&r" (pa) \ - : "r" (va) \ - : "memory" \ -diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h -index 4165079898d9e..88d0ae5769dde 100644 ---- a/arch/parisc/include/asm/uaccess.h -+++ b/arch/parisc/include/asm/uaccess.h -@@ -7,6 +7,7 @@ - */ - #include - #include -+#include - - #include - #include -@@ -26,37 +27,6 @@ - #define STD_USER(sr, x, ptr) __put_user_asm(sr, "std", x, ptr) - #endif - --/* -- * The exception table contains two values: the first is the relative offset to -- * the address of the instruction that is allowed to fault, and the second is -- * the relative offset to the address of the fixup routine. Since relative -- * addresses are used, 32bit values are sufficient even on 64bit kernel. -- */ -- --#define ARCH_HAS_RELATIVE_EXTABLE --struct exception_table_entry { -- int insn; /* relative address of insn that is allowed to fault. */ -- int fixup; /* relative address of fixup routine */ --}; -- --#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ -- ".section __ex_table,\"aw\"\n" \ -- ".align 4\n" \ -- ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ -- ".previous\n" -- --/* -- * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry -- * (with lowest bit set) for which the fault handler in fixup_exception() will -- * load -EFAULT into %r29 for a read or write fault, and zeroes the target -- * register in case of a read fault in get_user(). -- */ --#define ASM_EXCEPTIONTABLE_REG 29 --#define ASM_EXCEPTIONTABLE_VAR(__variable) \ -- register long __variable __asm__ ("r29") = 0 --#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\ -- ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) -- - #define __get_user_internal(sr, val, ptr) \ - ({ \ - ASM_EXCEPTIONTABLE_VAR(__gu_err); \ -@@ -83,7 +53,7 @@ struct exception_table_entry { - \ - __asm__("1: " ldx " 0(%%sr%2,%3),%0\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%1") \ - : "=r"(__gu_val), "+r"(__gu_err) \ - : "i"(sr), "r"(ptr)); \ - \ -@@ -115,8 +85,8 @@ struct exception_table_entry { - "1: ldw 0(%%sr%2,%3),%0\n" \ - "2: ldw 4(%%sr%2,%3),%R0\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%1") \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b, "%1") \ - : "=&r"(__gu_tmp.l), "+r"(__gu_err) \ - : "i"(sr), "r"(ptr)); \ - \ -@@ -174,7 +144,7 @@ struct exception_table_entry { - __asm__ __volatile__ ( \ - "1: " stx " %1,0(%%sr%2,%3)\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%0") \ - : "+r"(__pu_err) \ - : "r"(x), "i"(sr), "r"(ptr)) - -@@ -186,15 +156,14 @@ struct exception_table_entry { - "1: stw %1,0(%%sr%2,%3)\n" \ - "2: stw %R1,4(%%sr%2,%3)\n" \ - "9:\n" \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b, "%0") \ -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b, "%0") \ - : "+r"(__pu_err) \ - : "r"(__val), "i"(sr), "r"(ptr)); \ - } while (0) - - #endif /* !defined(CONFIG_64BIT) */ - -- - /* - * Complex access routines -- external declarations - */ -@@ -216,7 +185,4 @@ unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src, - #define INLINE_COPY_TO_USER - #define INLINE_COPY_FROM_USER - --struct pt_regs; --int fixup_exception(struct pt_regs *regs); -- - #endif /* __PARISC_UACCESS_H */ -diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c -index 8f12b9f318ae6..a582928739dd5 100644 ---- a/arch/parisc/kernel/drivers.c -+++ b/arch/parisc/kernel/drivers.c -@@ -1003,6 +1003,9 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) - - pr_info("\n"); - -+ /* Prevent hung task messages when printing on serial console */ -+ cond_resched(); -+ - pr_info("#define HPA_%08lx_DESCRIPTION \"%s\"\n", - hpa, parisc_hardware_description(&dev->id)); - -diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c -index e8a4d77cff53a..8a8e7d7224a26 100644 ---- a/arch/parisc/kernel/unaligned.c -+++ b/arch/parisc/kernel/unaligned.c -@@ -118,8 +118,8 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) - "2: ldbs 1(%%sr1,%3), %0\n" - " depw %2, 23, 24, %0\n" - "3: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") - : "+r" (val), "+r" (ret), "=&r" (temp1) - : "r" (saddr), "r" (regs->isr) ); - -@@ -150,8 +150,8 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) - " mtctl %2,11\n" - " vshd %0,%3,%0\n" - "3: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") - : "+r" (val), "+r" (ret), "=&r" (temp1), "=&r" (temp2) - : "r" (saddr), "r" (regs->isr) ); - -@@ -187,8 +187,8 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) - " mtsar %%r19\n" - " shrpd %0,%%r20,%%sar,%0\n" - "3: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") - : "=r" (val), "+r" (ret) - : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); -@@ -207,9 +207,9 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) - " vshd %0,%R0,%0\n" - " vshd %R0,%4,%R0\n" - "4: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 4b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 4b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 4b, "%1") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 4b, "%1") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b, "%1") - : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1) - : "r" (regs->isr) ); - } -@@ -242,8 +242,8 @@ static int emulate_sth(struct pt_regs *regs, int frreg) - "1: stb %1, 0(%%sr1, %3)\n" - "2: stb %2, 1(%%sr1, %3)\n" - "3: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%0") - : "+r" (ret), "=&r" (temp1) - : "r" (val), "r" (regs->ior), "r" (regs->isr) ); - -@@ -283,8 +283,8 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) - " stw %%r20,0(%%sr1,%2)\n" - " stw %%r21,4(%%sr1,%2)\n" - "3: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%0") - : "+r" (ret) - : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); -@@ -327,10 +327,10 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) - "3: std %%r20,0(%%sr1,%2)\n" - "4: std %%r21,8(%%sr1,%2)\n" - "5: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 5b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 5b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 5b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 5b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 5b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 5b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 5b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 5b, "%0") - : "+r" (ret) - : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); -@@ -356,11 +356,11 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) - "4: stw %%r1,4(%%sr1,%3)\n" - "5: stw %2,8(%%sr1,%3)\n" - "6: \n" -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 6b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b) -- ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b) -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 6b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b, "%0") -+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b, "%0") - : "+r" (ret) - : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r1" ); -diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c -index b00aa98b582c2..fbd9ada5e527e 100644 ---- a/arch/parisc/mm/fault.c -+++ b/arch/parisc/mm/fault.c -@@ -150,11 +150,16 @@ int fixup_exception(struct pt_regs *regs) - * Fix up get_user() and put_user(). - * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant - * bit in the relative address of the fixup routine to indicate -- * that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with -- * -EFAULT to report a userspace access error. -+ * that the register encoded in the "or %r0,%r0,register" -+ * opcode should be loaded with -EFAULT to report a userspace -+ * access error. - */ - if (fix->fixup & 1) { -- regs->gr[ASM_EXCEPTIONTABLE_REG] = -EFAULT; -+ int fault_error_reg = fix->err_opcode & 0x1f; -+ if (!WARN_ON(!fault_error_reg)) -+ regs->gr[fault_error_reg] = -EFAULT; -+ pr_debug("Unalignment fixup of register %d at %pS\n", -+ fault_error_reg, (void*)regs->iaoq[0]); - - /* zero target register for get_user() */ - if (parisc_acctyp(0, regs->iir) == VM_READ) { -diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h -index 61a4736355c24..20d5052e22925 100644 ---- a/arch/powerpc/include/asm/bug.h -+++ b/arch/powerpc/include/asm/bug.h -@@ -74,7 +74,7 @@ - ##__VA_ARGS__) - - #define WARN_ENTRY(insn, flags, label, ...) \ -- asm_volatile_goto( \ -+ asm goto( \ - "1: " insn "\n" \ - EX_TABLE(1b, %l[label]) \ - _EMIT_BUG_ENTRY \ -diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h -index 93ce3ec253877..2f2a86ed2280a 100644 ---- a/arch/powerpc/include/asm/jump_label.h -+++ b/arch/powerpc/include/asm/jump_label.h -@@ -17,7 +17,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "nop # arch_static_branch\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".long 1b - ., %l[l_yes] - .\n\t" -@@ -32,7 +32,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "b %l[l_yes] # arch_static_branch_jump\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".long 1b - ., %l[l_yes] - .\n\t" -diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h -index af58f1ed3952e..c4b798aa6ce80 100644 ---- a/arch/powerpc/include/asm/thread_info.h -+++ b/arch/powerpc/include/asm/thread_info.h -@@ -14,7 +14,7 @@ - - #ifdef __KERNEL__ - --#ifdef CONFIG_KASAN -+#if defined(CONFIG_KASAN) && CONFIG_THREAD_SHIFT < 15 - #define MIN_THREAD_SHIFT (CONFIG_THREAD_SHIFT + 1) - #else - #define MIN_THREAD_SHIFT CONFIG_THREAD_SHIFT -diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h -index 3ddc65c63a49e..45d4c9cf3f3a2 100644 ---- a/arch/powerpc/include/asm/uaccess.h -+++ b/arch/powerpc/include/asm/uaccess.h -@@ -72,7 +72,7 @@ __pu_failed: \ - * are no aliasing issues. - */ - #define __put_user_asm_goto(x, addr, label, op) \ -- asm_volatile_goto( \ -+ asm goto( \ - "1: " op "%U1%X1 %0,%1 # put_user\n" \ - EX_TABLE(1b, %l2) \ - : \ -@@ -85,7 +85,7 @@ __pu_failed: \ - __put_user_asm_goto(x, ptr, label, "std") - #else /* __powerpc64__ */ - #define __put_user_asm2_goto(x, addr, label) \ -- asm_volatile_goto( \ -+ asm goto( \ - "1: stw%X1 %0, %1\n" \ - "2: stw%X1 %L0, %L1\n" \ - EX_TABLE(1b, %l2) \ -@@ -132,7 +132,7 @@ do { \ - #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT - - #define __get_user_asm_goto(x, addr, label, op) \ -- asm_volatile_goto( \ -+ asm_goto_output( \ - "1: "op"%U1%X1 %0, %1 # get_user\n" \ - EX_TABLE(1b, %l2) \ - : "=r" (x) \ -@@ -145,7 +145,7 @@ do { \ - __get_user_asm_goto(x, addr, label, "ld") - #else /* __powerpc64__ */ - #define __get_user_asm2_goto(x, addr, label) \ -- asm_volatile_goto( \ -+ asm_goto_output( \ - "1: lwz%X1 %0, %1\n" \ - "2: lwz%X1 %L0, %L1\n" \ - EX_TABLE(1b, %l2) \ -diff --git a/arch/powerpc/kernel/cpu_specs_e500mc.h b/arch/powerpc/kernel/cpu_specs_e500mc.h -index ceb06b109f831..2ae8e9a7b461c 100644 ---- a/arch/powerpc/kernel/cpu_specs_e500mc.h -+++ b/arch/powerpc/kernel/cpu_specs_e500mc.h -@@ -8,7 +8,8 @@ - - #ifdef CONFIG_PPC64 - #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ -- PPC_FEATURE_HAS_FPU | PPC_FEATURE_64) -+ PPC_FEATURE_HAS_FPU | PPC_FEATURE_64 | \ -+ PPC_FEATURE_BOOKE) - #else - #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ - PPC_FEATURE_BOOKE) -diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S -index a019ed6fc8393..26c151e2a7942 100644 ---- a/arch/powerpc/kernel/interrupt_64.S -+++ b/arch/powerpc/kernel/interrupt_64.S -@@ -52,7 +52,8 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) - mr r10,r1 - ld r1,PACAKSAVE(r13) - std r10,0(r1) -- std r11,_NIP(r1) -+ std r11,_LINK(r1) -+ std r11,_NIP(r1) /* Saved LR is also the next instruction */ - std r12,_MSR(r1) - std r0,GPR0(r1) - std r10,GPR1(r1) -@@ -70,7 +71,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) - std r9,GPR13(r1) - SAVE_NVGPRS(r1) - std r11,_XER(r1) -- std r11,_LINK(r1) - std r11,_CTR(r1) - - li r11,\trapnr -diff --git a/arch/powerpc/kernel/irq_64.c b/arch/powerpc/kernel/irq_64.c -index 9dc0ad3c533a8..5a6e44e4d36f5 100644 ---- a/arch/powerpc/kernel/irq_64.c -+++ b/arch/powerpc/kernel/irq_64.c -@@ -230,7 +230,7 @@ notrace void arch_local_irq_restore(unsigned long mask) - * This allows interrupts to be unmasked without hard disabling, and - * also without new hard interrupts coming in ahead of pending ones. - */ -- asm_volatile_goto( -+ asm goto( - "1: \n" - " lbz 9,%0(13) \n" - " cmpwi 9,0 \n" -diff --git a/arch/powerpc/mm/kasan/init_32.c b/arch/powerpc/mm/kasan/init_32.c -index a70828a6d9357..aa9aa11927b2f 100644 ---- a/arch/powerpc/mm/kasan/init_32.c -+++ b/arch/powerpc/mm/kasan/init_32.c -@@ -64,6 +64,7 @@ int __init __weak kasan_init_region(void *start, size_t size) - if (ret) - return ret; - -+ k_start = k_start & PAGE_MASK; - block = memblock_alloc(k_end - k_start, PAGE_SIZE); - if (!block) - return -ENOMEM; -diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c -index 541199c6a587d..5186d65d772e2 100644 ---- a/arch/powerpc/platforms/pseries/lpar.c -+++ b/arch/powerpc/platforms/pseries/lpar.c -@@ -660,8 +660,12 @@ u64 pseries_paravirt_steal_clock(int cpu) - { - struct lppaca *lppaca = &lppaca_of(cpu); - -- return be64_to_cpu(READ_ONCE(lppaca->enqueue_dispatch_tb)) + -- be64_to_cpu(READ_ONCE(lppaca->ready_enqueue_tb)); -+ /* -+ * VPA steal time counters are reported at TB frequency. Hence do a -+ * conversion to ns before returning -+ */ -+ return tb_to_ns(be64_to_cpu(READ_ONCE(lppaca->enqueue_dispatch_tb)) + -+ be64_to_cpu(READ_ONCE(lppaca->ready_enqueue_tb))); - } - #endif - -diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/jump_label.h -index 14a5ea8d8ef0f..4a35d787c0191 100644 ---- a/arch/riscv/include/asm/jump_label.h -+++ b/arch/riscv/include/asm/jump_label.h -@@ -17,7 +17,7 @@ - static __always_inline bool arch_static_branch(struct static_key * const key, - const bool branch) - { -- asm_volatile_goto( -+ asm goto( - " .align 2 \n\t" - " .option push \n\t" - " .option norelax \n\t" -@@ -39,7 +39,7 @@ static __always_inline bool arch_static_branch(struct static_key * const key, - static __always_inline bool arch_static_branch_jump(struct static_key * const key, - const bool branch) - { -- asm_volatile_goto( -+ asm goto( - " .align 2 \n\t" - " .option push \n\t" - " .option norelax \n\t" -diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h -index 895f774bbcc55..bf78cf381dfcd 100644 ---- a/arch/s390/include/asm/jump_label.h -+++ b/arch/s390/include/asm/jump_label.h -@@ -25,7 +25,7 @@ - */ - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("0: brcl 0,%l[label]\n" -+ asm goto("0: brcl 0,%l[label]\n" - ".pushsection __jump_table,\"aw\"\n" - ".balign 8\n" - ".long 0b-.,%l[label]-.\n" -@@ -39,7 +39,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("0: brcl 15,%l[label]\n" -+ asm goto("0: brcl 15,%l[label]\n" - ".pushsection __jump_table,\"aw\"\n" - ".balign 8\n" - ".long 0b-.,%l[label]-.\n" -diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h -index 94eb529dcb776..2718cbea826a7 100644 ---- a/arch/sparc/include/asm/jump_label.h -+++ b/arch/sparc/include/asm/jump_label.h -@@ -10,7 +10,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "nop\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" -@@ -26,7 +26,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "b %l[l_yes]\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" -diff --git a/arch/um/Makefile b/arch/um/Makefile -index 3dbd0e3b660ea..778c50f273992 100644 ---- a/arch/um/Makefile -+++ b/arch/um/Makefile -@@ -118,7 +118,9 @@ archprepare: - $(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h - - LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static --LINK-$(CONFIG_LD_SCRIPT_DYN) += $(call cc-option, -no-pie) -+ifdef CONFIG_LD_SCRIPT_DYN -+LINK-$(call gcc-min-version, 60100)$(CONFIG_CC_IS_CLANG) += -no-pie -+endif - LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib - - CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ -diff --git a/arch/um/include/asm/cpufeature.h b/arch/um/include/asm/cpufeature.h -index 4b6d1b526bc12..66fe06db872f0 100644 ---- a/arch/um/include/asm/cpufeature.h -+++ b/arch/um/include/asm/cpufeature.h -@@ -75,7 +75,7 @@ extern void setup_clear_cpu_cap(unsigned int bit); - */ - static __always_inline bool _static_cpu_has(u16 bit) - { -- asm_volatile_goto("1: jmp 6f\n" -+ asm goto("1: jmp 6f\n" - "2:\n" - ".skip -(((5f-4f) - (2b-1b)) > 0) * " - "((5f-4f) - (2b-1b)),0x90\n" -diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu -index 542377cd419d7..ce5ed2c2db0c9 100644 ---- a/arch/x86/Kconfig.cpu -+++ b/arch/x86/Kconfig.cpu -@@ -375,7 +375,7 @@ config X86_CMOV - config X86_MINIMUM_CPU_FAMILY - int - default "64" if X86_64 -- default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8) -+ default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8) - default "5" if X86_32 && X86_CMPXCHG64 - default "4" - -diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index ce0c8f7d32186..f835b328ba24f 100644 ---- a/arch/x86/include/asm/cpufeature.h -+++ b/arch/x86/include/asm/cpufeature.h -@@ -173,7 +173,7 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); - */ - static __always_inline bool _static_cpu_has(u16 bit) - { -- asm_volatile_goto( -+ asm goto( - ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]") - ".pushsection .altinstr_aux,\"ax\"\n" - "6:\n" -diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h -index 071572e23d3a0..cbbef32517f00 100644 ---- a/arch/x86/include/asm/jump_label.h -+++ b/arch/x86/include/asm/jump_label.h -@@ -24,7 +24,7 @@ - - static __always_inline bool arch_static_branch(struct static_key *key, bool branch) - { -- asm_volatile_goto("1:" -+ asm goto("1:" - "jmp %l[l_yes] # objtool NOPs this \n\t" - JUMP_TABLE_ENTRY - : : "i" (key), "i" (2 | branch) : : l_yes); -@@ -38,7 +38,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - - static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) - { -- asm_volatile_goto("1:" -+ asm goto("1:" - ".byte " __stringify(BYTES_NOP5) "\n\t" - JUMP_TABLE_ENTRY - : : "i" (key), "i" (branch) : : l_yes); -@@ -52,7 +52,7 @@ static __always_inline bool arch_static_branch(struct static_key * const key, co - - static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) - { -- asm_volatile_goto("1:" -+ asm goto("1:" - "jmp %l[l_yes]\n\t" - JUMP_TABLE_ENTRY - : : "i" (key), "i" (branch) : : l_yes); -diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h -index 7fa6112164172..1919ccf493cd1 100644 ---- a/arch/x86/include/asm/rmwcc.h -+++ b/arch/x86/include/asm/rmwcc.h -@@ -18,7 +18,7 @@ - #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \ - ({ \ - bool c = false; \ -- asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ -+ asm goto (fullop "; j" #cc " %l[cc_label]" \ - : : [var] "m" (_var), ## __VA_ARGS__ \ - : clobbers : cc_label); \ - if (0) { \ -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 6ca0c661cb637..c638535eedd55 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -155,7 +155,7 @@ extern int __get_user_bad(void); - - #ifdef CONFIG_X86_32 - #define __put_user_goto_u64(x, addr, label) \ -- asm_volatile_goto("\n" \ -+ asm goto("\n" \ - "1: movl %%eax,0(%1)\n" \ - "2: movl %%edx,4(%1)\n" \ - _ASM_EXTABLE_UA(1b, %l2) \ -@@ -317,7 +317,7 @@ do { \ - } while (0) - - #define __get_user_asm(x, addr, itype, ltype, label) \ -- asm_volatile_goto("\n" \ -+ asm_goto_output("\n" \ - "1: mov"itype" %[umem],%[output]\n" \ - _ASM_EXTABLE_UA(1b, %l2) \ - : [output] ltype(x) \ -@@ -397,7 +397,7 @@ do { \ - __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ - __typeof__(*(_ptr)) __old = *_old; \ - __typeof__(*(_ptr)) __new = (_new); \ -- asm_volatile_goto("\n" \ -+ asm_goto_output("\n" \ - "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ - _ASM_EXTABLE_UA(1b, %l[label]) \ - : CC_OUT(z) (success), \ -@@ -416,7 +416,7 @@ do { \ - __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ - __typeof__(*(_ptr)) __old = *_old; \ - __typeof__(*(_ptr)) __new = (_new); \ -- asm_volatile_goto("\n" \ -+ asm_goto_output("\n" \ - "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ - _ASM_EXTABLE_UA(1b, %l[label]) \ - : CC_OUT(z) (success), \ -@@ -499,7 +499,7 @@ struct __large_struct { unsigned long buf[100]; }; - * aliasing issues. - */ - #define __put_user_goto(x, addr, itype, ltype, label) \ -- asm_volatile_goto("\n" \ -+ asm goto("\n" \ - "1: mov"itype" %0,%1\n" \ - _ASM_EXTABLE_UA(1b, %l2) \ - : : ltype(x), "m" (__m(addr)) \ -diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h -index 6c2e3ff3cb28f..724ce44809ed2 100644 ---- a/arch/x86/include/asm/virtext.h -+++ b/arch/x86/include/asm/virtext.h -@@ -43,9 +43,9 @@ static inline int cpu_has_vmx(void) - */ - static inline int cpu_vmxoff(void) - { -- asm_volatile_goto("1: vmxoff\n\t" -- _ASM_EXTABLE(1b, %l[fault]) -- ::: "cc", "memory" : fault); -+ asm goto("1: vmxoff\n\t" -+ _ASM_EXTABLE(1b, %l[fault]) -+ ::: "cc", "memory" : fault); - - cr4_clear_bits(X86_CR4_VMXE); - return 0; -@@ -129,9 +129,9 @@ static inline void cpu_svm_disable(void) - * case, GIF must already be set, otherwise the NMI would have - * been blocked, so just eat the fault. - */ -- asm_volatile_goto("1: stgi\n\t" -- _ASM_EXTABLE(1b, %l[fault]) -- ::: "memory" : fault); -+ asm goto("1: stgi\n\t" -+ _ASM_EXTABLE(1b, %l[fault]) -+ ::: "memory" : fault); - fault: - wrmsrl(MSR_EFER, efer & ~EFER_SVME); - } -diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c -index 558076dbde5bf..247f2225aa9f3 100644 ---- a/arch/x86/kernel/fpu/signal.c -+++ b/arch/x86/kernel/fpu/signal.c -@@ -274,12 +274,13 @@ static int __restore_fpregs_from_user(void __user *buf, u64 ufeatures, - * Attempt to restore the FPU registers directly from user memory. - * Pagefaults are handled and any errors returned are fatal. - */ --static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, -- bool fx_only, unsigned int size) -+static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only) - { - struct fpu *fpu = ¤t->thread.fpu; - int ret; - -+ /* Restore enabled features only. */ -+ xrestore &= fpu->fpstate->user_xfeatures; - retry: - fpregs_lock(); - /* Ensure that XFD is up to date */ -@@ -309,7 +310,7 @@ static bool restore_fpregs_from_user(void __user *buf, u64 xrestore, - if (ret != X86_TRAP_PF) - return false; - -- if (!fault_in_readable(buf, size)) -+ if (!fault_in_readable(buf, fpu->fpstate->user_size)) - goto retry; - return false; - } -@@ -339,7 +340,6 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx, - struct user_i387_ia32_struct env; - bool success, fx_only = false; - union fpregs_state *fpregs; -- unsigned int state_size; - u64 user_xfeatures = 0; - - if (use_xsave()) { -@@ -349,17 +349,14 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx, - return false; - - fx_only = !fx_sw_user.magic1; -- state_size = fx_sw_user.xstate_size; - user_xfeatures = fx_sw_user.xfeatures; - } else { - user_xfeatures = XFEATURE_MASK_FPSSE; -- state_size = fpu->fpstate->user_size; - } - - if (likely(!ia32_fxstate)) { - /* Restore the FPU registers directly from user memory. */ -- return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only, -- state_size); -+ return restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only); - } - - /* -diff --git a/arch/x86/kvm/svm/svm_ops.h b/arch/x86/kvm/svm/svm_ops.h -index 36c8af87a707a..4e725854c63a1 100644 ---- a/arch/x86/kvm/svm/svm_ops.h -+++ b/arch/x86/kvm/svm/svm_ops.h -@@ -8,7 +8,7 @@ - - #define svm_asm(insn, clobber...) \ - do { \ -- asm_volatile_goto("1: " __stringify(insn) "\n\t" \ -+ asm goto("1: " __stringify(insn) "\n\t" \ - _ASM_EXTABLE(1b, %l[fault]) \ - ::: clobber : fault); \ - return; \ -@@ -18,7 +18,7 @@ fault: \ - - #define svm_asm1(insn, op1, clobber...) \ - do { \ -- asm_volatile_goto("1: " __stringify(insn) " %0\n\t" \ -+ asm goto("1: " __stringify(insn) " %0\n\t" \ - _ASM_EXTABLE(1b, %l[fault]) \ - :: op1 : clobber : fault); \ - return; \ -@@ -28,7 +28,7 @@ fault: \ - - #define svm_asm2(insn, op1, op2, clobber...) \ - do { \ -- asm_volatile_goto("1: " __stringify(insn) " %1, %0\n\t" \ -+ asm goto("1: " __stringify(insn) " %1, %0\n\t" \ - _ASM_EXTABLE(1b, %l[fault]) \ - :: op1, op2 : clobber : fault); \ - return; \ -diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c -index 9a75a0d5deae1..220cdbe1e286e 100644 ---- a/arch/x86/kvm/vmx/pmu_intel.c -+++ b/arch/x86/kvm/vmx/pmu_intel.c -@@ -38,7 +38,7 @@ static int fixed_pmc_events[] = {1, 0, 7}; - static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data) - { - struct kvm_pmc *pmc; -- u8 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl; -+ u64 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl; - int i; - - pmu->fixed_ctr_ctrl = data; -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 98d732b9418f1..57c1374fdfd49 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -2469,10 +2469,10 @@ static int kvm_cpu_vmxon(u64 vmxon_pointer) - - cr4_set_bits(X86_CR4_VMXE); - -- asm_volatile_goto("1: vmxon %[vmxon_pointer]\n\t" -- _ASM_EXTABLE(1b, %l[fault]) -- : : [vmxon_pointer] "m"(vmxon_pointer) -- : : fault); -+ asm goto("1: vmxon %[vmxon_pointer]\n\t" -+ _ASM_EXTABLE(1b, %l[fault]) -+ : : [vmxon_pointer] "m"(vmxon_pointer) -+ : : fault); - return 0; - - fault: -diff --git a/arch/x86/kvm/vmx/vmx_ops.h b/arch/x86/kvm/vmx/vmx_ops.h -index ec268df83ed67..5edab28dfb2ef 100644 ---- a/arch/x86/kvm/vmx/vmx_ops.h -+++ b/arch/x86/kvm/vmx/vmx_ops.h -@@ -73,7 +73,7 @@ static __always_inline unsigned long __vmcs_readl(unsigned long field) - - #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT - -- asm_volatile_goto("1: vmread %[field], %[output]\n\t" -+ asm_goto_output("1: vmread %[field], %[output]\n\t" - "jna %l[do_fail]\n\t" - - _ASM_EXTABLE(1b, %l[do_exception]) -@@ -166,7 +166,7 @@ static __always_inline unsigned long vmcs_readl(unsigned long field) - - #define vmx_asm1(insn, op1, error_args...) \ - do { \ -- asm_volatile_goto("1: " __stringify(insn) " %0\n\t" \ -+ asm goto("1: " __stringify(insn) " %0\n\t" \ - ".byte 0x2e\n\t" /* branch not taken hint */ \ - "jna %l[error]\n\t" \ - _ASM_EXTABLE(1b, %l[fault]) \ -@@ -183,7 +183,7 @@ fault: \ - - #define vmx_asm2(insn, op1, op2, error_args...) \ - do { \ -- asm_volatile_goto("1: " __stringify(insn) " %1, %0\n\t" \ -+ asm goto("1: " __stringify(insn) " %1, %0\n\t" \ - ".byte 0x2e\n\t" /* branch not taken hint */ \ - "jna %l[error]\n\t" \ - _ASM_EXTABLE(1b, %l[fault]) \ -diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c -index 968d7005f4a72..f50cc210a9818 100644 ---- a/arch/x86/mm/ident_map.c -+++ b/arch/x86/mm/ident_map.c -@@ -26,18 +26,31 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page, - for (; addr < end; addr = next) { - pud_t *pud = pud_page + pud_index(addr); - pmd_t *pmd; -+ bool use_gbpage; - - next = (addr & PUD_MASK) + PUD_SIZE; - if (next > end) - next = end; - -- if (info->direct_gbpages) { -- pud_t pudval; -+ /* if this is already a gbpage, this portion is already mapped */ -+ if (pud_large(*pud)) -+ continue; -+ -+ /* Is using a gbpage allowed? */ -+ use_gbpage = info->direct_gbpages; - -- if (pud_present(*pud)) -- continue; -+ /* Don't use gbpage if it maps more than the requested region. */ -+ /* at the begining: */ -+ use_gbpage &= ((addr & ~PUD_MASK) == 0); -+ /* ... or at the end: */ -+ use_gbpage &= ((next & ~PUD_MASK) == 0); -+ -+ /* Never overwrite existing mappings */ -+ use_gbpage &= !pud_present(*pud); -+ -+ if (use_gbpage) { -+ pud_t pudval; - -- addr &= PUD_MASK; - pudval = __pud((addr - info->offset) | info->page_flag); - set_pud(pud, pudval); - continue; -diff --git a/arch/xtensa/include/asm/jump_label.h b/arch/xtensa/include/asm/jump_label.h -index c812bf85021c0..46c8596259d2d 100644 ---- a/arch/xtensa/include/asm/jump_label.h -+++ b/arch/xtensa/include/asm/jump_label.h -@@ -13,7 +13,7 @@ - static __always_inline bool arch_static_branch(struct static_key *key, - bool branch) - { -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - "_nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" - ".word 1b, %l[l_yes], %c0\n\t" -@@ -38,7 +38,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, - * make it reachable and wrap both into a no-transform block - * to avoid any assembler interference with this. - */ -- asm_volatile_goto("1:\n\t" -+ asm goto("1:\n\t" - ".begin no-transform\n\t" - "_j %l[l_yes]\n\t" - "2:\n\t" -diff --git a/block/blk-mq.c b/block/blk-mq.c -index c07e5eebcbd85..7ed6b9469f979 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -747,11 +747,16 @@ static void req_bio_endio(struct request *rq, struct bio *bio, - /* - * Partial zone append completions cannot be supported as the - * BIO fragments may end up not being written sequentially. -+ * For such case, force the completed nbytes to be equal to -+ * the BIO size so that bio_advance() sets the BIO remaining -+ * size to 0 and we end up calling bio_endio() before returning. - */ -- if (bio->bi_iter.bi_size != nbytes) -+ if (bio->bi_iter.bi_size != nbytes) { - bio->bi_status = BLK_STS_IOERR; -- else -+ nbytes = bio->bi_iter.bi_size; -+ } else { - bio->bi_iter.bi_sector = rq->__sector; -+ } - } - - bio_advance(bio, nbytes); -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index d933ef6cc65af..55cd17a13e758 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -477,6 +477,16 @@ binder_enqueue_thread_work_ilocked(struct binder_thread *thread, - { - WARN_ON(!list_empty(&thread->waiting_thread_node)); - binder_enqueue_work_ilocked(work, &thread->todo); -+ -+ /* (e)poll-based threads require an explicit wakeup signal when -+ * queuing their own work; they rely on these events to consume -+ * messages without I/O block. Without it, threads risk waiting -+ * indefinitely without handling the work. -+ */ -+ if (thread->looper & BINDER_LOOPER_STATE_POLL && -+ thread->pid == current->pid && !thread->process_todo) -+ wake_up_interruptible_sync(&thread->wait); -+ - thread->process_todo = true; - } - -diff --git a/drivers/base/core.c b/drivers/base/core.c -index af90bfb0cc3d8..3078f44dc1861 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -337,10 +337,12 @@ static bool device_is_ancestor(struct device *dev, struct device *target) - return false; - } - -+#define DL_MARKER_FLAGS (DL_FLAG_INFERRED | \ -+ DL_FLAG_CYCLE | \ -+ DL_FLAG_MANAGED) - static inline bool device_link_flag_is_sync_state_only(u32 flags) - { -- return (flags & ~(DL_FLAG_INFERRED | DL_FLAG_CYCLE)) == -- (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED); -+ return (flags & ~DL_MARKER_FLAGS) == DL_FLAG_SYNC_STATE_ONLY; - } - - /** -@@ -2054,9 +2056,14 @@ static int fw_devlink_create_devlink(struct device *con, - - /* - * SYNC_STATE_ONLY device links don't block probing and supports cycles. -- * So cycle detection isn't necessary and shouldn't be done. -+ * So, one might expect that cycle detection isn't necessary for them. -+ * However, if the device link was marked as SYNC_STATE_ONLY because -+ * it's part of a cycle, then we still need to do cycle detection. This -+ * is because the consumer and supplier might be part of multiple cycles -+ * and we need to detect all those cycles. - */ -- if (!(flags & DL_FLAG_SYNC_STATE_ONLY)) { -+ if (!device_link_flag_is_sync_state_only(flags) || -+ flags & DL_FLAG_CYCLE) { - device_links_write_lock(); - if (__fw_devlink_relax_cycles(con, sup_handle)) { - __fwnode_link_cycle(link); -diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c -index 56ceba4698024..d238b47f74c34 100644 ---- a/drivers/base/power/domain.c -+++ b/drivers/base/power/domain.c -@@ -1052,7 +1052,7 @@ static int __init genpd_power_off_unused(void) - - return 0; - } --late_initcall(genpd_power_off_unused); -+late_initcall_sync(genpd_power_off_unused); - - #ifdef CONFIG_PM_SLEEP - -diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c -index 5eb0fe73ddc45..79fc96c8d8364 100644 ---- a/drivers/bus/moxtet.c -+++ b/drivers/bus/moxtet.c -@@ -830,6 +830,12 @@ static void moxtet_remove(struct spi_device *spi) - mutex_destroy(&moxtet->lock); - } - -+static const struct spi_device_id moxtet_spi_ids[] = { -+ { "moxtet" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(spi, moxtet_spi_ids); -+ - static const struct of_device_id moxtet_dt_ids[] = { - { .compatible = "cznic,moxtet" }, - {}, -@@ -841,6 +847,7 @@ static struct spi_driver moxtet_spi_driver = { - .name = "moxtet", - .of_match_table = moxtet_dt_ids, - }, -+ .id_table = moxtet_spi_ids, - .probe = moxtet_probe, - .remove = moxtet_remove, - }; -diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c -index b8e02c3a19610..bbfb0f288dc35 100644 ---- a/drivers/crypto/ccp/sev-dev.c -+++ b/drivers/crypto/ccp/sev-dev.c -@@ -515,10 +515,16 @@ EXPORT_SYMBOL_GPL(sev_platform_init); - - static int __sev_platform_shutdown_locked(int *error) - { -- struct sev_device *sev = psp_master->sev_data; -+ struct psp_device *psp = psp_master; -+ struct sev_device *sev; - int ret; - -- if (!sev || sev->state == SEV_STATE_UNINIT) -+ if (!psp || !psp->sev_data) -+ return 0; -+ -+ sev = psp->sev_data; -+ -+ if (sev->state == SEV_STATE_UNINIT) - return 0; - - ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error); -diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c -index e2070df6cad28..0b846c605d4bd 100644 ---- a/drivers/dma/ioat/dma.c -+++ b/drivers/dma/ioat/dma.c -@@ -584,11 +584,11 @@ desc_get_errstat(struct ioatdma_chan *ioat_chan, struct ioat_ring_ent *desc) - } - - /** -- * __cleanup - reclaim used descriptors -+ * __ioat_cleanup - reclaim used descriptors - * @ioat_chan: channel (ring) to clean - * @phys_complete: zeroed (or not) completion address (from status) - */ --static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete) -+static void __ioat_cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete) - { - struct ioatdma_device *ioat_dma = ioat_chan->ioat_dma; - struct ioat_ring_ent *desc; -@@ -675,7 +675,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan) - spin_lock_bh(&ioat_chan->cleanup_lock); - - if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) -- __cleanup(ioat_chan, phys_complete); -+ __ioat_cleanup(ioat_chan, phys_complete); - - if (is_ioat_halted(*ioat_chan->completion)) { - u32 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); -@@ -712,7 +712,7 @@ static void ioat_restart_channel(struct ioatdma_chan *ioat_chan) - - ioat_quiesce(ioat_chan, 0); - if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) -- __cleanup(ioat_chan, phys_complete); -+ __ioat_cleanup(ioat_chan, phys_complete); - - __ioat_restart_chan(ioat_chan); - } -@@ -786,7 +786,7 @@ static void ioat_eh(struct ioatdma_chan *ioat_chan) - - /* cleanup so tail points to descriptor that caused the error */ - if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) -- __cleanup(ioat_chan, phys_complete); -+ __ioat_cleanup(ioat_chan, phys_complete); - - chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); - pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr_int); -@@ -943,7 +943,7 @@ void ioat_timer_event(struct timer_list *t) - /* timer restarted in ioat_cleanup_preamble - * and IOAT_COMPLETION_ACK cleared - */ -- __cleanup(ioat_chan, phys_complete); -+ __ioat_cleanup(ioat_chan, phys_complete); - goto unlock_out; - } - -diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c -index 74bab06283b71..1879ec27c0236 100644 ---- a/drivers/firewire/core-device.c -+++ b/drivers/firewire/core-device.c -@@ -100,10 +100,9 @@ static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) - * @buf: where to put the string - * @size: size of @buf, in bytes - * -- * The string is taken from a minimal ASCII text descriptor leaf after -- * the immediate entry with @key. The string is zero-terminated. -- * An overlong string is silently truncated such that it and the -- * zero byte fit into @size. -+ * The string is taken from a minimal ASCII text descriptor leaf just after the entry with the -+ * @key. The string is zero-terminated. An overlong string is silently truncated such that it -+ * and the zero byte fit into @size. - * - * Returns strlen(buf) or a negative error code. - */ -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 4b91f95066eca..6a4749c0c5a58 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -4203,7 +4203,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); - - cancel_delayed_work_sync(&adev->delayed_init_work); -- flush_delayed_work(&adev->gfx.gfx_off_delay_work); - - amdgpu_ras_suspend(adev); - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -index 23f0067f92e4e..b803e785d3aff 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -@@ -585,8 +585,15 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) - - if (adev->gfx.gfx_off_req_count == 0 && - !adev->gfx.gfx_off_state) { -- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, -+ /* If going to s2idle, no need to wait */ -+ if (adev->in_s0ix) { -+ if (!amdgpu_dpm_set_powergating_by_smu(adev, -+ AMD_IP_BLOCK_TYPE_GFX, true)) -+ adev->gfx.gfx_off_state = true; -+ } else { -+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, - delay); -+ } - } - } else { - if (adev->gfx.gfx_off_req_count == 0) { -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 f02e509d5facb..a826c92933199 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -6001,7 +6001,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, - if (recalculate_timing) { - freesync_mode = get_highest_refresh_rate_mode(aconnector, false); - drm_mode_copy(&saved_mode, &mode); -+ saved_mode.picture_aspect_ratio = mode.picture_aspect_ratio; - drm_mode_copy(&mode, freesync_mode); -+ mode.picture_aspect_ratio = saved_mode.picture_aspect_ratio; - } else { - decide_crtc_timing_for_drm_display_mode( - &mode, preferred_mode, scale); -diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile -index ca7d240006213..6fdf87a6e240f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile -@@ -60,11 +60,11 @@ ifdef CONFIG_DRM_AMD_DC_DCN - CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags) --CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) -+CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) $(frame_warn_flag) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) --CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) -+CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) $(frame_warn_flag) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags) --CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) -+CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) $(frame_warn_flag) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag) - CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index eb09e86044c6d..68a6d4b0ead75 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -828,7 +828,7 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, - if (max_segment == 0) - max_segment = UINT_MAX; - err = sg_alloc_table_from_pages_segment(sg, pages, nr_pages, 0, -- nr_pages << PAGE_SHIFT, -+ (unsigned long)nr_pages << PAGE_SHIFT, - max_segment, GFP_KERNEL); - if (err) { - kfree(sg); -diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c -index d12ba47b37c4f..0de3612135e96 100644 ---- a/drivers/gpu/drm/msm/msm_iommu.c -+++ b/drivers/gpu/drm/msm/msm_iommu.c -@@ -21,6 +21,8 @@ struct msm_iommu_pagetable { - struct msm_mmu base; - struct msm_mmu *parent; - struct io_pgtable_ops *pgtbl_ops; -+ const struct iommu_flush_ops *tlb; -+ struct device *iommu_dev; - unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ - phys_addr_t ttbr; - u32 asid; -@@ -194,11 +196,33 @@ static const struct msm_mmu_funcs pagetable_funcs = { - - static void msm_iommu_tlb_flush_all(void *cookie) - { -+ struct msm_iommu_pagetable *pagetable = cookie; -+ struct adreno_smmu_priv *adreno_smmu; -+ -+ if (!pm_runtime_get_if_in_use(pagetable->iommu_dev)) -+ return; -+ -+ adreno_smmu = dev_get_drvdata(pagetable->parent->dev); -+ -+ pagetable->tlb->tlb_flush_all((void *)adreno_smmu->cookie); -+ -+ pm_runtime_put_autosuspend(pagetable->iommu_dev); - } - - static void msm_iommu_tlb_flush_walk(unsigned long iova, size_t size, - size_t granule, void *cookie) - { -+ struct msm_iommu_pagetable *pagetable = cookie; -+ struct adreno_smmu_priv *adreno_smmu; -+ -+ if (!pm_runtime_get_if_in_use(pagetable->iommu_dev)) -+ return; -+ -+ adreno_smmu = dev_get_drvdata(pagetable->parent->dev); -+ -+ pagetable->tlb->tlb_flush_walk(iova, size, granule, (void *)adreno_smmu->cookie); -+ -+ pm_runtime_put_autosuspend(pagetable->iommu_dev); - } - - static void msm_iommu_tlb_add_page(struct iommu_iotlb_gather *gather, -@@ -206,7 +230,7 @@ static void msm_iommu_tlb_add_page(struct iommu_iotlb_gather *gather, - { - } - --static const struct iommu_flush_ops null_tlb_ops = { -+static const struct iommu_flush_ops tlb_ops = { - .tlb_flush_all = msm_iommu_tlb_flush_all, - .tlb_flush_walk = msm_iommu_tlb_flush_walk, - .tlb_add_page = msm_iommu_tlb_add_page, -@@ -254,10 +278,10 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) - - /* The incoming cfg will have the TTBR1 quirk enabled */ - ttbr0_cfg.quirks &= ~IO_PGTABLE_QUIRK_ARM_TTBR1; -- ttbr0_cfg.tlb = &null_tlb_ops; -+ ttbr0_cfg.tlb = &tlb_ops; - - pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1, -- &ttbr0_cfg, iommu->domain); -+ &ttbr0_cfg, pagetable); - - if (!pagetable->pgtbl_ops) { - kfree(pagetable); -@@ -282,6 +306,8 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) - - /* Needed later for TLB flush */ - pagetable->parent = parent; -+ pagetable->tlb = ttbr1_cfg->tlb; -+ pagetable->iommu_dev = ttbr1_cfg->iommu_dev; - pagetable->pgsize_bitmap = ttbr0_cfg.pgsize_bitmap; - pagetable->ttbr = ttbr0_cfg.arm_lpae_s1_cfg.ttbr; - -diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c -index 31a5b81ee9fc4..be6674fb1af71 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_svm.c -+++ b/drivers/gpu/drm/nouveau/nouveau_svm.c -@@ -997,7 +997,7 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id) - if (ret) - return ret; - -- buffer->fault = kvcalloc(sizeof(*buffer->fault), buffer->entries, GFP_KERNEL); -+ buffer->fault = kvcalloc(buffer->entries, sizeof(*buffer->fault), GFP_KERNEL); - if (!buffer->fault) - return -ENOMEM; - -diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c -index 0035affc3e590..9b2d235168bb6 100644 ---- a/drivers/gpu/drm/virtio/virtgpu_drv.c -+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c -@@ -93,6 +93,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev) - goto err_free; - } - -+ dma_set_max_seg_size(dev->dev, dma_max_mapping_size(dev->dev) ?: UINT_MAX); - ret = virtio_gpu_init(vdev, dev); - if (ret) - goto err_free; -diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c -index 97a27a803f58d..6feb812fce375 100644 ---- a/drivers/hid/i2c-hid/i2c-hid-of.c -+++ b/drivers/hid/i2c-hid/i2c-hid-of.c -@@ -80,6 +80,7 @@ static int i2c_hid_of_probe(struct i2c_client *client, - if (!ihid_of) - return -ENOMEM; - -+ ihid_of->client = client; - ihid_of->ops.power_up = i2c_hid_of_power_up; - ihid_of->ops.power_down = i2c_hid_of_power_down; - -diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c -index af163e8dfec07..12d4c28741d7e 100644 ---- a/drivers/hid/wacom_sys.c -+++ b/drivers/hid/wacom_sys.c -@@ -2080,7 +2080,7 @@ static int wacom_allocate_inputs(struct wacom *wacom) - return 0; - } - --static int wacom_register_inputs(struct wacom *wacom) -+static int wacom_setup_inputs(struct wacom *wacom) - { - struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; - struct wacom_wac *wacom_wac = &(wacom->wacom_wac); -@@ -2099,10 +2099,6 @@ static int wacom_register_inputs(struct wacom *wacom) - input_free_device(pen_input_dev); - wacom_wac->pen_input = NULL; - pen_input_dev = NULL; -- } else { -- error = input_register_device(pen_input_dev); -- if (error) -- goto fail; - } - - error = wacom_setup_touch_input_capabilities(touch_input_dev, wacom_wac); -@@ -2111,10 +2107,6 @@ static int wacom_register_inputs(struct wacom *wacom) - input_free_device(touch_input_dev); - wacom_wac->touch_input = NULL; - touch_input_dev = NULL; -- } else { -- error = input_register_device(touch_input_dev); -- if (error) -- goto fail; - } - - error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); -@@ -2123,7 +2115,34 @@ static int wacom_register_inputs(struct wacom *wacom) - input_free_device(pad_input_dev); - wacom_wac->pad_input = NULL; - pad_input_dev = NULL; -- } else { -+ } -+ -+ return 0; -+} -+ -+static int wacom_register_inputs(struct wacom *wacom) -+{ -+ struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; -+ struct wacom_wac *wacom_wac = &(wacom->wacom_wac); -+ int error = 0; -+ -+ pen_input_dev = wacom_wac->pen_input; -+ touch_input_dev = wacom_wac->touch_input; -+ pad_input_dev = wacom_wac->pad_input; -+ -+ if (pen_input_dev) { -+ error = input_register_device(pen_input_dev); -+ if (error) -+ goto fail; -+ } -+ -+ if (touch_input_dev) { -+ error = input_register_device(touch_input_dev); -+ if (error) -+ goto fail; -+ } -+ -+ if (pad_input_dev) { - error = input_register_device(pad_input_dev); - if (error) - goto fail; -@@ -2379,6 +2398,20 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless) - goto fail; - } - -+ error = wacom_setup_inputs(wacom); -+ if (error) -+ goto fail; -+ -+ if (features->type == HID_GENERIC) -+ connect_mask |= HID_CONNECT_DRIVER; -+ -+ /* Regular HID work starts now */ -+ error = hid_hw_start(hdev, connect_mask); -+ if (error) { -+ hid_err(hdev, "hw start failed\n"); -+ goto fail; -+ } -+ - error = wacom_register_inputs(wacom); - if (error) - goto fail; -@@ -2393,16 +2426,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless) - goto fail; - } - -- if (features->type == HID_GENERIC) -- connect_mask |= HID_CONNECT_DRIVER; -- -- /* Regular HID work starts now */ -- error = hid_hw_start(hdev, connect_mask); -- if (error) { -- hid_err(hdev, "hw start failed\n"); -- goto fail; -- } -- - if (!wireless) { - /* Note that if query fails it is not a hard failure */ - wacom_query_tablet_data(wacom); -diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c -index 165ed872fa4e7..53235b276bb24 100644 ---- a/drivers/hid/wacom_wac.c -+++ b/drivers/hid/wacom_wac.c -@@ -2571,7 +2571,14 @@ static void wacom_wac_pen_report(struct hid_device *hdev, - wacom_wac->hid_data.tipswitch); - input_report_key(input, wacom_wac->tool[0], sense); - if (wacom_wac->serial[0]) { -- input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); -+ /* -+ * xf86-input-wacom does not accept a serial number -+ * of '0'. Report the low 32 bits if possible, but -+ * if they are zero, report the upper ones instead. -+ */ -+ __u32 serial_lo = wacom_wac->serial[0] & 0xFFFFFFFFu; -+ __u32 serial_hi = wacom_wac->serial[0] >> 32; -+ input_event(input, EV_MSC, MSC_SERIAL, (int)(serial_lo ? serial_lo : serial_hi)); - input_report_abs(input, ABS_MISC, sense ? id : 0); - } - -diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index e73cdb1d2b5a8..784a803279d99 100644 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -89,10 +89,8 @@ obj-$(CONFIG_I2C_NPCM) += i2c-npcm7xx.o - obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o - obj-$(CONFIG_I2C_OMAP) += i2c-omap.o - obj-$(CONFIG_I2C_OWL) += i2c-owl.o --i2c-pasemi-objs := i2c-pasemi-core.o i2c-pasemi-pci.o --obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o --i2c-apple-objs := i2c-pasemi-core.o i2c-pasemi-platform.o --obj-$(CONFIG_I2C_APPLE) += i2c-apple.o -+obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi-core.o i2c-pasemi-pci.o -+obj-$(CONFIG_I2C_APPLE) += i2c-pasemi-core.o i2c-pasemi-platform.o - obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o - obj-$(CONFIG_I2C_PNX) += i2c-pnx.o - obj-$(CONFIG_I2C_PXA) += i2c-pxa.o -diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c -index 3159ffbb77a20..9a4e9bf304c28 100644 ---- a/drivers/i2c/busses/i2c-i801.c -+++ b/drivers/i2c/busses/i2c-i801.c -@@ -500,11 +500,10 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, - /* Set block buffer mode */ - outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv)); - -- inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ -- - if (read_write == I2C_SMBUS_WRITE) { - len = data->block[0]; - outb_p(len, SMBHSTDAT0(priv)); -+ inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ - for (i = 0; i < len; i++) - outb_p(data->block[i+1], SMBBLKDAT(priv)); - } -@@ -520,6 +519,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, - return -EPROTO; - - data->block[0] = len; -+ inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ - for (i = 0; i < len; i++) - data->block[i + 1] = inb_p(SMBBLKDAT(priv)); - } -diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c -index 9028ffb58cc07..f297e41352e7a 100644 ---- a/drivers/i2c/busses/i2c-pasemi-core.c -+++ b/drivers/i2c/busses/i2c-pasemi-core.c -@@ -356,3 +356,8 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) - - return 0; - } -+EXPORT_SYMBOL_GPL(pasemi_i2c_common_probe); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Olof Johansson "); -+MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver"); -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index 8fce98bb77ff9..75b9c3f26bba6 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -605,20 +605,20 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i - - peripheral.addr = msgs[i].addr; - -+ ret = geni_i2c_gpi(gi2c, &msgs[i], &config, -+ &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c); -+ if (ret) -+ goto err; -+ - if (msgs[i].flags & I2C_M_RD) { - ret = geni_i2c_gpi(gi2c, &msgs[i], &config, - &rx_addr, &rx_buf, I2C_READ, gi2c->rx_c); - if (ret) - goto err; -- } -- -- ret = geni_i2c_gpi(gi2c, &msgs[i], &config, -- &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c); -- if (ret) -- goto err; - -- if (msgs[i].flags & I2C_M_RD) - dma_async_issue_pending(gi2c->rx_c); -+ } -+ - dma_async_issue_pending(gi2c->tx_c); - - timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); -diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig -index ffac66db7ac92..1f34747a68bfe 100644 ---- a/drivers/iio/accel/Kconfig -+++ b/drivers/iio/accel/Kconfig -@@ -219,10 +219,12 @@ config BMA400 - - config BMA400_I2C - tristate -+ select REGMAP_I2C - depends on BMA400 - - config BMA400_SPI - tristate -+ select REGMAP_SPI - depends on BMA400 - - config BMC150_ACCEL -diff --git a/drivers/iio/imu/bno055/Kconfig b/drivers/iio/imu/bno055/Kconfig -index 83e53acfbe880..c7f5866a177d9 100644 ---- a/drivers/iio/imu/bno055/Kconfig -+++ b/drivers/iio/imu/bno055/Kconfig -@@ -8,6 +8,7 @@ config BOSCH_BNO055 - config BOSCH_BNO055_SERIAL - tristate "Bosch BNO055 attached via UART" - depends on SERIAL_DEV_BUS -+ select REGMAP - select BOSCH_BNO055 - help - Enable this to support Bosch BNO055 IMUs attached via UART. -diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c -index c9614982cb671..a2f8278f00856 100644 ---- a/drivers/iio/industrialio-core.c -+++ b/drivers/iio/industrialio-core.c -@@ -1601,10 +1601,13 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) - ret = iio_device_register_sysfs_group(indio_dev, - &iio_dev_opaque->chan_attr_group); - if (ret) -- goto error_clear_attrs; -+ goto error_free_chan_attrs; - - return 0; - -+error_free_chan_attrs: -+ kfree(iio_dev_opaque->chan_attr_group.attrs); -+ iio_dev_opaque->chan_attr_group.attrs = NULL; - error_clear_attrs: - iio_free_chan_devattr_list(&iio_dev_opaque->channel_attr_list); - -diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c -index 5a1a625d8d16d..85097b769c209 100644 ---- a/drivers/iio/light/hid-sensor-als.c -+++ b/drivers/iio/light/hid-sensor-als.c -@@ -228,6 +228,7 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev, - case HID_USAGE_SENSOR_TIME_TIMESTAMP: - als_state->timestamp = hid_sensor_convert_timestamp(&als_state->common_attributes, - *(s64 *)raw_data); -+ ret = 0; - break; - default: - break; -diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c -index 69938204456f8..42b70cd42b393 100644 ---- a/drivers/iio/magnetometer/rm3100-core.c -+++ b/drivers/iio/magnetometer/rm3100-core.c -@@ -530,6 +530,7 @@ int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) - struct rm3100_data *data; - unsigned int tmp; - int ret; -+ int samp_rate_index; - - indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); - if (!indio_dev) -@@ -586,9 +587,14 @@ int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) - ret = regmap_read(regmap, RM3100_REG_TMRC, &tmp); - if (ret < 0) - return ret; -+ -+ samp_rate_index = tmp - RM3100_TMRC_OFFSET; -+ if (samp_rate_index < 0 || samp_rate_index >= RM3100_SAMP_NUM) { -+ dev_err(dev, "The value read from RM3100_REG_TMRC is invalid!\n"); -+ return -EINVAL; -+ } - /* Initializing max wait time, which is double conversion time. */ -- data->conversion_time = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][2] -- * 2; -+ data->conversion_time = rm3100_samp_rates[samp_rate_index][2] * 2; - - /* Cycle count values may not be what we want. */ - if ((tmp - RM3100_TMRC_OFFSET) == 0) -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 4859b99d54fc2..01faec6ea5285 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -2845,6 +2845,13 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, - - switch (req.reg_type) { - case IRDMA_MEMREG_TYPE_QP: -+ /* iWarp: Catch page not starting on OS page boundary */ -+ if (!rdma_protocol_roce(&iwdev->ibdev, 1) && -+ ib_umem_offset(iwmr->region)) { -+ err = -EINVAL; -+ goto error; -+ } -+ - total = req.sq_pages + req.rq_pages + shadow_pgcnt; - if (total > iwmr->page_cnt) { - err = -EINVAL; -diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c -index 83461e31774ec..d9ee193fb18bd 100644 ---- a/drivers/interconnect/qcom/sc8180x.c -+++ b/drivers/interconnect/qcom/sc8180x.c -@@ -1387,6 +1387,7 @@ static struct qcom_icc_bcm bcm_mm0 = { - - static struct qcom_icc_bcm bcm_co0 = { - .name = "CO0", -+ .keepalive = true, - .num_nodes = 1, - .nodes = { &slv_qns_cdsp_mem_noc } - }; -diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c -index 091b0fe7e3242..5d4421f75b43a 100644 ---- a/drivers/irqchip/irq-brcmstb-l2.c -+++ b/drivers/irqchip/irq-brcmstb-l2.c -@@ -2,7 +2,7 @@ - /* - * Generic Broadcom Set Top Box Level 2 Interrupt controller driver - * -- * Copyright (C) 2014-2017 Broadcom -+ * Copyright (C) 2014-2024 Broadcom - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -113,6 +113,9 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc) - generic_handle_domain_irq(b->domain, irq); - } while (status); - out: -+ /* Don't ack parent before all device writes are done */ -+ wmb(); -+ - chained_irq_exit(chip, desc); - } - -diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c -index 8956881503d9a..b83b39e93e1a9 100644 ---- a/drivers/irqchip/irq-gic-v3-its.c -+++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -3805,8 +3805,9 @@ static int its_vpe_set_affinity(struct irq_data *d, - bool force) - { - struct its_vpe *vpe = irq_data_get_irq_chip_data(d); -- int from, cpu = cpumask_first(mask_val); -+ struct cpumask common, *table_mask; - unsigned long flags; -+ int from, cpu; - - /* - * Changing affinity is mega expensive, so let's be as lazy as -@@ -3822,19 +3823,22 @@ static int its_vpe_set_affinity(struct irq_data *d, - * taken on any vLPI handling path that evaluates vpe->col_idx. - */ - from = vpe_to_cpuid_lock(vpe, &flags); -- if (from == cpu) -- goto out; -- -- vpe->col_idx = cpu; -+ table_mask = gic_data_rdist_cpu(from)->vpe_table_mask; - - /* -- * GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD -- * is sharing its VPE table with the current one. -+ * If we are offered another CPU in the same GICv4.1 ITS -+ * affinity, pick this one. Otherwise, any CPU will do. - */ -- if (gic_data_rdist_cpu(cpu)->vpe_table_mask && -- cpumask_test_cpu(from, gic_data_rdist_cpu(cpu)->vpe_table_mask)) -+ if (table_mask && cpumask_and(&common, mask_val, table_mask)) -+ cpu = cpumask_test_cpu(from, &common) ? from : cpumask_first(&common); -+ else -+ cpu = cpumask_first(mask_val); -+ -+ if (from == cpu) - goto out; - -+ vpe->col_idx = cpu; -+ - its_send_vmovp(vpe); - its_vpe_db_proxy_move(vpe, from, cpu); - -diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c -index 3d99b8bdd8ef1..de115ee6e9ec7 100644 ---- a/drivers/irqchip/irq-loongson-eiointc.c -+++ b/drivers/irqchip/irq-loongson-eiointc.c -@@ -242,7 +242,7 @@ static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, - int ret; - unsigned int i, type; - unsigned long hwirq = 0; -- struct eiointc *priv = domain->host_data; -+ struct eiointc_priv *priv = domain->host_data; - - ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); - if (ret) -diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h -index 71dcd8fd4050a..6314210d36971 100644 ---- a/drivers/md/dm-core.h -+++ b/drivers/md/dm-core.h -@@ -21,6 +21,8 @@ - #include "dm-ima.h" - - #define DM_RESERVED_MAX_IOS 1024 -+#define DM_MAX_TARGETS 1048576 -+#define DM_MAX_TARGET_PARAMS 1024 - - struct dm_io; - -diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c -index ff515437d81e7..0e6068ee783e7 100644 ---- a/drivers/md/dm-crypt.c -+++ b/drivers/md/dm-crypt.c -@@ -72,10 +72,8 @@ struct dm_crypt_io { - struct bio *base_bio; - u8 *integrity_metadata; - bool integrity_metadata_from_pool:1; -- bool in_tasklet:1; - - struct work_struct work; -- struct tasklet_struct tasklet; - - struct convert_context ctx; - -@@ -1729,7 +1727,6 @@ static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc, - io->ctx.r.req = NULL; - io->integrity_metadata = NULL; - io->integrity_metadata_from_pool = false; -- io->in_tasklet = false; - atomic_set(&io->io_pending, 0); - } - -@@ -1738,12 +1735,6 @@ static void crypt_inc_pending(struct dm_crypt_io *io) - atomic_inc(&io->io_pending); - } - --static void kcryptd_io_bio_endio(struct work_struct *work) --{ -- struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); -- bio_endio(io->base_bio); --} -- - /* - * One of the bios was finished. Check for completion of - * the whole request and correctly clean up the buffer. -@@ -1767,20 +1758,6 @@ static void crypt_dec_pending(struct dm_crypt_io *io) - - base_bio->bi_status = error; - -- /* -- * If we are running this function from our tasklet, -- * we can't call bio_endio() here, because it will call -- * clone_endio() from dm.c, which in turn will -- * free the current struct dm_crypt_io structure with -- * our tasklet. In this case we need to delay bio_endio() -- * execution to after the tasklet is done and dequeued. -- */ -- if (io->in_tasklet) { -- INIT_WORK(&io->work, kcryptd_io_bio_endio); -- queue_work(cc->io_queue, &io->work); -- return; -- } -- - bio_endio(base_bio); - } - -@@ -2213,11 +2190,6 @@ static void kcryptd_crypt(struct work_struct *work) - kcryptd_crypt_write_convert(io); - } - --static void kcryptd_crypt_tasklet(unsigned long work) --{ -- kcryptd_crypt((struct work_struct *)work); --} -- - static void kcryptd_queue_crypt(struct dm_crypt_io *io) - { - struct crypt_config *cc = io->cc; -@@ -2229,15 +2201,10 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io) - * irqs_disabled(): the kernel may run some IO completion from the idle thread, but - * it is being executed with irqs disabled. - */ -- if (in_hardirq() || irqs_disabled()) { -- io->in_tasklet = true; -- tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); -- tasklet_schedule(&io->tasklet); -+ if (!(in_hardirq() || irqs_disabled())) { -+ kcryptd_crypt(&io->work); - return; - } -- -- kcryptd_crypt(&io->work); -- return; - } - - INIT_WORK(&io->work, kcryptd_crypt); -diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c -index 206e6ce554dc7..4376754816abe 100644 ---- a/drivers/md/dm-ioctl.c -+++ b/drivers/md/dm-ioctl.c -@@ -1877,7 +1877,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern - minimum_data_size - sizeof(param_kernel->version))) - return -EFAULT; - -- if (param_kernel->data_size < minimum_data_size) { -+ if (unlikely(param_kernel->data_size < minimum_data_size) || -+ unlikely(param_kernel->data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS)) { - DMERR("Invalid data size in the ioctl structure: %u", - param_kernel->data_size); - return -EINVAL; -diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c -index dac6a5f25f2be..e0367a672eabf 100644 ---- a/drivers/md/dm-table.c -+++ b/drivers/md/dm-table.c -@@ -128,7 +128,12 @@ static int alloc_targets(struct dm_table *t, unsigned int num) - int dm_table_create(struct dm_table **result, fmode_t mode, - unsigned int num_targets, struct mapped_device *md) - { -- struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); -+ struct dm_table *t; -+ -+ if (num_targets > DM_MAX_TARGETS) -+ return -EOVERFLOW; -+ -+ t = kzalloc(sizeof(*t), GFP_KERNEL); - - if (!t) - return -ENOMEM; -@@ -143,7 +148,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode, - - if (!num_targets) { - kfree(t); -- return -ENOMEM; -+ return -EOVERFLOW; - } - - if (alloc_targets(t, num_targets)) { -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index 24df610a2c438..4669923f4cfb4 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -634,23 +634,6 @@ static void verity_work(struct work_struct *w) - verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); - } - --static void verity_tasklet(unsigned long data) --{ -- struct dm_verity_io *io = (struct dm_verity_io *)data; -- int err; -- -- io->in_tasklet = true; -- err = verity_verify_io(io); -- if (err == -EAGAIN || err == -ENOMEM) { -- /* fallback to retrying with work-queue */ -- INIT_WORK(&io->work, verity_work); -- queue_work(io->v->verify_wq, &io->work); -- return; -- } -- -- verity_finish_io(io, errno_to_blk_status(err)); --} -- - static void verity_end_io(struct bio *bio) - { - struct dm_verity_io *io = bio->bi_private; -@@ -663,13 +646,8 @@ static void verity_end_io(struct bio *bio) - return; - } - -- if (static_branch_unlikely(&use_tasklet_enabled) && io->v->use_tasklet) { -- tasklet_init(&io->tasklet, verity_tasklet, (unsigned long)io); -- tasklet_schedule(&io->tasklet); -- } else { -- INIT_WORK(&io->work, verity_work); -- queue_work(io->v->verify_wq, &io->work); -- } -+ INIT_WORK(&io->work, verity_work); -+ queue_work(io->v->verify_wq, &io->work); - } - - /* -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index f9d522c870e61..f3f6070084196 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -83,7 +83,6 @@ struct dm_verity_io { - struct bvec_iter iter; - - struct work_struct work; -- struct tasklet_struct tasklet; - - /* - * Three variably-size fields follow this struct: -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 3ccf1920682cb..c7efe15229514 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -963,9 +963,10 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev, - return; - - bio = bio_alloc_bioset(rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev, -- 1, -- REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH | REQ_FUA, -- GFP_NOIO, &mddev->sync_set); -+ 1, -+ REQ_OP_WRITE | REQ_SYNC | REQ_IDLE | REQ_META -+ | REQ_PREFLUSH | REQ_FUA, -+ GFP_NOIO, &mddev->sync_set); - - atomic_inc(&rdev->nr_pending); - -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -index aeb6bb63667eb..41abb18b00acb 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -@@ -559,7 +559,7 @@ static int rkisp1_probe(struct platform_device *pdev) - rkisp1->irqs[il] = irq; - } - -- ret = devm_request_irq(dev, irq, info->isrs[i].isr, 0, -+ ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED, - dev_driver_string(dev), dev); - if (ret) { - dev_err(dev, "request irq failed: %d\n", ret); -diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c -index fe17c7f98e810..52d82cbe7685f 100644 ---- a/drivers/media/rc/bpf-lirc.c -+++ b/drivers/media/rc/bpf-lirc.c -@@ -253,7 +253,7 @@ int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) - if (attr->attach_flags) - return -EINVAL; - -- rcdev = rc_dev_get_from_fd(attr->target_fd); -+ rcdev = rc_dev_get_from_fd(attr->target_fd, true); - if (IS_ERR(rcdev)) - return PTR_ERR(rcdev); - -@@ -278,7 +278,7 @@ int lirc_prog_detach(const union bpf_attr *attr) - if (IS_ERR(prog)) - return PTR_ERR(prog); - -- rcdev = rc_dev_get_from_fd(attr->target_fd); -+ rcdev = rc_dev_get_from_fd(attr->target_fd, true); - if (IS_ERR(rcdev)) { - bpf_prog_put(prog); - return PTR_ERR(rcdev); -@@ -303,7 +303,7 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) - if (attr->query.query_flags) - return -EINVAL; - -- rcdev = rc_dev_get_from_fd(attr->query.target_fd); -+ rcdev = rc_dev_get_from_fd(attr->query.target_fd, false); - if (IS_ERR(rcdev)) - return PTR_ERR(rcdev); - -diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c -index 1968067092594..69e630d85262f 100644 ---- a/drivers/media/rc/ir_toy.c -+++ b/drivers/media/rc/ir_toy.c -@@ -332,6 +332,7 @@ static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count) - sizeof(COMMAND_SMODE_EXIT), STATE_COMMAND_NO_RESP); - if (err) { - dev_err(irtoy->dev, "exit sample mode: %d\n", err); -+ kfree(buf); - return err; - } - -@@ -339,6 +340,7 @@ static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count) - sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND); - if (err) { - dev_err(irtoy->dev, "enter sample mode: %d\n", err); -+ kfree(buf); - return err; - } - -diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c -index 184e0b35744f3..adb8c794a2d7b 100644 ---- a/drivers/media/rc/lirc_dev.c -+++ b/drivers/media/rc/lirc_dev.c -@@ -814,7 +814,7 @@ void __exit lirc_dev_exit(void) - unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX); - } - --struct rc_dev *rc_dev_get_from_fd(int fd) -+struct rc_dev *rc_dev_get_from_fd(int fd, bool write) - { - struct fd f = fdget(fd); - struct lirc_fh *fh; -@@ -828,6 +828,9 @@ struct rc_dev *rc_dev_get_from_fd(int fd) - return ERR_PTR(-EINVAL); - } - -+ if (write && !(f.file->f_mode & FMODE_WRITE)) -+ return ERR_PTR(-EPERM); -+ - fh = f.file->private_data; - dev = fh->rc; - -diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h -index ef1e95e1af7fc..7df949fc65e2b 100644 ---- a/drivers/media/rc/rc-core-priv.h -+++ b/drivers/media/rc/rc-core-priv.h -@@ -325,7 +325,7 @@ void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev); - void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc); - int lirc_register(struct rc_dev *dev); - void lirc_unregister(struct rc_dev *dev); --struct rc_dev *rc_dev_get_from_fd(int fd); -+struct rc_dev *rc_dev_get_from_fd(int fd, bool write); - #else - static inline int lirc_dev_init(void) { return 0; } - static inline void lirc_dev_exit(void) {} -diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c -index cc57cc8204328..69cc24962706c 100644 ---- a/drivers/misc/fastrpc.c -+++ b/drivers/misc/fastrpc.c -@@ -1990,7 +1990,7 @@ static int fastrpc_cb_remove(struct platform_device *pdev) - int i; - - spin_lock_irqsave(&cctx->lock, flags); -- for (i = 1; i < FASTRPC_MAX_SESSIONS; i++) { -+ for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) { - if (cctx->session[i].sid == sess->sid) { - cctx->session[i].valid = false; - cctx->sesscount--; -diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c -index dd2a4b6ab6adb..e3c69c6b85a6c 100644 ---- a/drivers/mmc/core/slot-gpio.c -+++ b/drivers/mmc/core/slot-gpio.c -@@ -62,11 +62,15 @@ int mmc_gpio_alloc(struct mmc_host *host) - int mmc_gpio_get_ro(struct mmc_host *host) - { - struct mmc_gpio *ctx = host->slot.handler_priv; -+ int cansleep; - - if (!ctx || !ctx->ro_gpio) - return -ENOSYS; - -- return gpiod_get_value_cansleep(ctx->ro_gpio); -+ cansleep = gpiod_cansleep(ctx->ro_gpio); -+ return cansleep ? -+ gpiod_get_value_cansleep(ctx->ro_gpio) : -+ gpiod_get_value(ctx->ro_gpio); - } - EXPORT_SYMBOL(mmc_gpio_get_ro); - -diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c -index bca1d095b7597..24bb0e9809e76 100644 ---- a/drivers/mmc/host/sdhci-pci-o2micro.c -+++ b/drivers/mmc/host/sdhci-pci-o2micro.c -@@ -602,6 +602,35 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock) - sdhci_o2_enable_clk(host, clk); - } - -+static void sdhci_pci_o2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd) -+{ -+ struct sdhci_pci_chip *chip; -+ struct sdhci_pci_slot *slot = sdhci_priv(host); -+ u32 scratch_32 = 0; -+ u8 scratch_8 = 0; -+ -+ chip = slot->chip; -+ -+ if (mode == MMC_POWER_OFF) { -+ /* UnLock WP */ -+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); -+ scratch_8 &= 0x7f; -+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); -+ -+ /* Set PCR 0x354[16] to switch Clock Source back to OPE Clock */ -+ pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32); -+ scratch_32 &= ~(O2_SD_SEL_DLL); -+ pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32); -+ -+ /* Lock WP */ -+ pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); -+ scratch_8 |= 0x80; -+ pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); -+ } -+ -+ sdhci_set_power(host, mode, vdd); -+} -+ - static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) - { - struct sdhci_pci_chip *chip; -@@ -911,6 +940,7 @@ static const struct sdhci_ops sdhci_pci_o2_ops = { - .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, -+ .set_power = sdhci_pci_o2_set_power, - }; - - const struct sdhci_pci_fixes sdhci_o2 = { -diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c -index 8efa22d9f214d..053d375eae4f5 100644 ---- a/drivers/net/can/dev/netlink.c -+++ b/drivers/net/can/dev/netlink.c -@@ -311,7 +311,7 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], - /* Neither of TDC parameters nor TDC flags are - * provided: do calculation - */ -- can_calc_tdco(&priv->tdc, priv->tdc_const, &priv->data_bittiming, -+ can_calc_tdco(&priv->tdc, priv->tdc_const, &dbt, - &priv->ctrlmode, priv->ctrlmode_supported); - } /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly - * turned off. TDC is disabled: do nothing -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index 63d43ef86f9b9..76455405a6d8e 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -5333,7 +5333,7 @@ static int i40e_pf_wait_queues_disabled(struct i40e_pf *pf) - { - int v, ret = 0; - -- for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { -+ for (v = 0; v < pf->num_alloc_vsi; v++) { - if (pf->vsi[v]) { - ret = i40e_vsi_wait_queues_disabled(pf->vsi[v]); - if (ret) -diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -index 3d3db58090ed1..ed4be80fec2a5 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -@@ -2846,6 +2846,24 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg) - (u8 *)&stats, sizeof(stats)); - } - -+/** -+ * i40e_can_vf_change_mac -+ * @vf: pointer to the VF info -+ * -+ * Return true if the VF is allowed to change its MAC filters, false otherwise -+ */ -+static bool i40e_can_vf_change_mac(struct i40e_vf *vf) -+{ -+ /* If the VF MAC address has been set administratively (via the -+ * ndo_set_vf_mac command), then deny permission to the VF to -+ * add/delete unicast MAC addresses, unless the VF is trusted -+ */ -+ if (vf->pf_set_mac && !vf->trusted) -+ return false; -+ -+ return true; -+} -+ - #define I40E_MAX_MACVLAN_PER_HW 3072 - #define I40E_MAX_MACVLAN_PER_PF(num_ports) (I40E_MAX_MACVLAN_PER_HW / \ - (num_ports)) -@@ -2905,8 +2923,8 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, - * The VF may request to set the MAC address filter already - * assigned to it so do not return an error in that case. - */ -- if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) && -- !is_multicast_ether_addr(addr) && vf->pf_set_mac && -+ if (!i40e_can_vf_change_mac(vf) && -+ !is_multicast_ether_addr(addr) && - !ether_addr_equal(addr, vf->default_lan_addr.addr)) { - dev_err(&pf->pdev->dev, - "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n"); -@@ -3049,19 +3067,29 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) - ret = I40E_ERR_INVALID_MAC_ADDR; - goto error_param; - } -- if (ether_addr_equal(al->list[i].addr, vf->default_lan_addr.addr)) -- was_unimac_deleted = true; - } - vsi = pf->vsi[vf->lan_vsi_idx]; - - spin_lock_bh(&vsi->mac_filter_hash_lock); - /* delete addresses from the list */ -- for (i = 0; i < al->num_elements; i++) -+ for (i = 0; i < al->num_elements; i++) { -+ const u8 *addr = al->list[i].addr; -+ -+ /* Allow to delete VF primary MAC only if it was not set -+ * administratively by PF or if VF is trusted. -+ */ -+ if (ether_addr_equal(addr, vf->default_lan_addr.addr) && -+ i40e_can_vf_change_mac(vf)) -+ was_unimac_deleted = true; -+ else -+ continue; -+ - if (i40e_del_mac_filter(vsi, al->list[i].addr)) { - ret = I40E_ERR_INVALID_MAC_ADDR; - spin_unlock_bh(&vsi->mac_filter_hash_lock); - goto error_param; - } -+ } - - spin_unlock_bh(&vsi->mac_filter_hash_lock); - -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -index 3b9ba8fa247ab..dc2e204bcd727 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -@@ -65,6 +65,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, - tcam->max_groups = max_groups; - tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, - ACL_MAX_GROUP_SIZE); -+ tcam->max_group_size = min_t(unsigned int, tcam->max_group_size, -+ MLXSW_REG_PAGT_ACL_MAX_NUM); - - err = ops->init(mlxsw_sp, tcam->priv, tcam); - if (err) -diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_lag.c b/drivers/net/ethernet/microchip/lan966x/lan966x_lag.c -index 41fa2523d91d3..5f2cd9a8cf8fb 100644 ---- a/drivers/net/ethernet/microchip/lan966x/lan966x_lag.c -+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_lag.c -@@ -37,19 +37,24 @@ static void lan966x_lag_set_aggr_pgids(struct lan966x *lan966x) - - /* Now, set PGIDs for each active LAG */ - for (lag = 0; lag < lan966x->num_phys_ports; ++lag) { -- struct net_device *bond = lan966x->ports[lag]->bond; -+ struct lan966x_port *port = lan966x->ports[lag]; - int num_active_ports = 0; -+ struct net_device *bond; - unsigned long bond_mask; - u8 aggr_idx[16]; - -- if (!bond || (visited & BIT(lag))) -+ if (!port || !port->bond || (visited & BIT(lag))) - continue; - -+ bond = port->bond; - bond_mask = lan966x_lag_get_mask(lan966x, bond); - - for_each_set_bit(p, &bond_mask, lan966x->num_phys_ports) { - struct lan966x_port *port = lan966x->ports[p]; - -+ if (!port) -+ continue; -+ - lan_wr(ANA_PGID_PGID_SET(bond_mask), - lan966x, ANA_PGID(p)); - if (port->lag_tx_active) -diff --git a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -index f7492be452aed..7af03b45555dd 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -@@ -1379,10 +1379,30 @@ static void nfp_nft_ct_translate_mangle_action(struct flow_action_entry *mangle_ - mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); - return; - -+ /* Both struct tcphdr and struct udphdr start with -+ * __be16 source; -+ * __be16 dest; -+ * so we can use the same code for both. -+ */ - case FLOW_ACT_MANGLE_HDR_TYPE_TCP: - case FLOW_ACT_MANGLE_HDR_TYPE_UDP: -- mangle_action->mangle.val = (__force u16)cpu_to_be16(mangle_action->mangle.val); -- mangle_action->mangle.mask = (__force u16)cpu_to_be16(mangle_action->mangle.mask); -+ if (mangle_action->mangle.offset == offsetof(struct tcphdr, source)) { -+ mangle_action->mangle.val = -+ (__force u32)cpu_to_be32(mangle_action->mangle.val << 16); -+ /* The mask of mangle action is inverse mask, -+ * so clear the dest tp port with 0xFFFF to -+ * instead of rotate-left operation. -+ */ -+ mangle_action->mangle.mask = -+ (__force u32)cpu_to_be32(mangle_action->mangle.mask << 16 | 0xFFFF); -+ } -+ if (mangle_action->mangle.offset == offsetof(struct tcphdr, dest)) { -+ mangle_action->mangle.offset = 0; -+ mangle_action->mangle.val = -+ (__force u32)cpu_to_be32(mangle_action->mangle.val); -+ mangle_action->mangle.mask = -+ (__force u32)cpu_to_be32(mangle_action->mangle.mask); -+ } - return; - - default: -diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c -index 52f67157bd0f7..a3c52c91a575d 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c -@@ -980,7 +980,7 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, - u16 nfp_mac_idx = 0; - - entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); -- if (entry && nfp_tunnel_is_mac_idx_global(entry->index)) { -+ if (entry && (nfp_tunnel_is_mac_idx_global(entry->index) || netif_is_lag_port(netdev))) { - if (entry->bridge_count || - !nfp_flower_is_supported_bridge(netdev)) { - nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, -diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c -index 33b4c28563162..3f10c5365c80e 100644 ---- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c -+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c -@@ -537,11 +537,13 @@ static int enable_bars(struct nfp6000_pcie *nfp, u16 interface) - const u32 barcfg_msix_general = - NFP_PCIE_BAR_PCIE2CPP_MapType( - NFP_PCIE_BAR_PCIE2CPP_MapType_GENERAL) | -- NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT; -+ NFP_PCIE_BAR_PCIE2CPP_LengthSelect( -+ NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT); - const u32 barcfg_msix_xpb = - NFP_PCIE_BAR_PCIE2CPP_MapType( - NFP_PCIE_BAR_PCIE2CPP_MapType_BULK) | -- NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT | -+ NFP_PCIE_BAR_PCIE2CPP_LengthSelect( -+ NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT) | - NFP_PCIE_BAR_PCIE2CPP_Target_BaseAddress( - NFP_CPP_TARGET_ISLAND_XPB); - const u32 barcfg_explicit[4] = { -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index e988a60c8561b..66178ce6d000e 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3826,6 +3826,9 @@ static int __stmmac_open(struct net_device *dev, - priv->rx_copybreak = STMMAC_RX_COPYBREAK; - - buf_sz = dma_conf->dma_buf_sz; -+ for (int i = 0; i < MTL_MAX_TX_QUEUES; i++) -+ if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN) -+ dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs; - memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); - - stmmac_reset_queues_param(priv); -diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c -index 13c9c2d6b79bb..d95771ca4e5a3 100644 ---- a/drivers/net/ethernet/ti/cpsw.c -+++ b/drivers/net/ethernet/ti/cpsw.c -@@ -631,6 +631,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) - } - } - -+ phy->mac_managed_pm = true; -+ - slave->phy = phy; - - phy_attached_info(slave->phy); -diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c -index 83596ec0c7cb9..6e70aa1cc7bf1 100644 ---- a/drivers/net/ethernet/ti/cpsw_new.c -+++ b/drivers/net/ethernet/ti/cpsw_new.c -@@ -772,6 +772,9 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) - slave->slave_num); - return; - } -+ -+ phy->mac_managed_pm = true; -+ - slave->phy = phy; - - phy_attached_info(slave->phy); -diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c -index da737d959e81c..3a834d4e1c842 100644 ---- a/drivers/net/hyperv/netvsc.c -+++ b/drivers/net/hyperv/netvsc.c -@@ -740,7 +740,10 @@ void netvsc_device_remove(struct hv_device *device) - /* Disable NAPI and disassociate its context from the device. */ - for (i = 0; i < net_device->num_chn; i++) { - /* See also vmbus_reset_channel_cb(). */ -- napi_disable(&net_device->chan_table[i].napi); -+ /* only disable enabled NAPI channel */ -+ if (i < ndev->real_num_rx_queues) -+ napi_disable(&net_device->chan_table[i].napi); -+ - netif_napi_del(&net_device->chan_table[i].napi); - } - -diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c -index c1aac6ceb29e6..1b74055399840 100644 ---- a/drivers/net/hyperv/netvsc_drv.c -+++ b/drivers/net/hyperv/netvsc_drv.c -@@ -42,6 +42,10 @@ - #define LINKCHANGE_INT (2 * HZ) - #define VF_TAKEOVER_INT (HZ / 10) - -+/* Macros to define the context of vf registration */ -+#define VF_REG_IN_PROBE 1 -+#define VF_REG_IN_NOTIFIER 2 -+ - static unsigned int ring_size __ro_after_init = 128; - module_param(ring_size, uint, 0444); - MODULE_PARM_DESC(ring_size, "Ring buffer size (# of 4K pages)"); -@@ -2181,7 +2185,7 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb) - } - - static int netvsc_vf_join(struct net_device *vf_netdev, -- struct net_device *ndev) -+ struct net_device *ndev, int context) - { - struct net_device_context *ndev_ctx = netdev_priv(ndev); - int ret; -@@ -2204,7 +2208,11 @@ static int netvsc_vf_join(struct net_device *vf_netdev, - goto upper_link_failed; - } - -- schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); -+ /* If this registration is called from probe context vf_takeover -+ * is taken care of later in probe itself. -+ */ -+ if (context == VF_REG_IN_NOTIFIER) -+ schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); - - call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); - -@@ -2342,7 +2350,7 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev) - return NOTIFY_DONE; - } - --static int netvsc_register_vf(struct net_device *vf_netdev) -+static int netvsc_register_vf(struct net_device *vf_netdev, int context) - { - struct net_device_context *net_device_ctx; - struct netvsc_device *netvsc_dev; -@@ -2382,7 +2390,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev) - - netdev_info(ndev, "VF registering: %s\n", vf_netdev->name); - -- if (netvsc_vf_join(vf_netdev, ndev) != 0) -+ if (netvsc_vf_join(vf_netdev, ndev, context) != 0) - return NOTIFY_DONE; - - dev_hold(vf_netdev); -@@ -2480,10 +2488,31 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) - return NOTIFY_OK; - } - -+static int check_dev_is_matching_vf(struct net_device *event_ndev) -+{ -+ /* Skip NetVSC interfaces */ -+ if (event_ndev->netdev_ops == &device_ops) -+ return -ENODEV; -+ -+ /* Avoid non-Ethernet type devices */ -+ if (event_ndev->type != ARPHRD_ETHER) -+ return -ENODEV; -+ -+ /* Avoid Vlan dev with same MAC registering as VF */ -+ if (is_vlan_dev(event_ndev)) -+ return -ENODEV; -+ -+ /* Avoid Bonding master dev with same MAC registering as VF */ -+ if (netif_is_bond_master(event_ndev)) -+ return -ENODEV; -+ -+ return 0; -+} -+ - static int netvsc_probe(struct hv_device *dev, - const struct hv_vmbus_device_id *dev_id) - { -- struct net_device *net = NULL; -+ struct net_device *net = NULL, *vf_netdev; - struct net_device_context *net_device_ctx; - struct netvsc_device_info *device_info = NULL; - struct netvsc_device *nvdev; -@@ -2592,6 +2621,30 @@ static int netvsc_probe(struct hv_device *dev, - } - - list_add(&net_device_ctx->list, &netvsc_dev_list); -+ -+ /* When the hv_netvsc driver is unloaded and reloaded, the -+ * NET_DEVICE_REGISTER for the vf device is replayed before probe -+ * is complete. This is because register_netdevice_notifier() gets -+ * registered before vmbus_driver_register() so that callback func -+ * is set before probe and we don't miss events like NETDEV_POST_INIT -+ * So, in this section we try to register the matching vf device that -+ * is present as a netdevice, knowing that its register call is not -+ * processed in the netvsc_netdev_notifier(as probing is progress and -+ * get_netvsc_byslot fails). -+ */ -+ for_each_netdev(dev_net(net), vf_netdev) { -+ ret = check_dev_is_matching_vf(vf_netdev); -+ if (ret != 0) -+ continue; -+ -+ if (net != get_netvsc_byslot(vf_netdev)) -+ continue; -+ -+ netvsc_prepare_bonding(vf_netdev); -+ netvsc_register_vf(vf_netdev, VF_REG_IN_PROBE); -+ __netvsc_vf_setup(net, vf_netdev); -+ break; -+ } - rtnl_unlock(); - - netvsc_devinfo_put(device_info); -@@ -2748,28 +2801,17 @@ static int netvsc_netdev_event(struct notifier_block *this, - unsigned long event, void *ptr) - { - struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); -+ int ret = 0; - -- /* Skip our own events */ -- if (event_dev->netdev_ops == &device_ops) -- return NOTIFY_DONE; -- -- /* Avoid non-Ethernet type devices */ -- if (event_dev->type != ARPHRD_ETHER) -- return NOTIFY_DONE; -- -- /* Avoid Vlan dev with same MAC registering as VF */ -- if (is_vlan_dev(event_dev)) -- return NOTIFY_DONE; -- -- /* Avoid Bonding master dev with same MAC registering as VF */ -- if (netif_is_bond_master(event_dev)) -+ ret = check_dev_is_matching_vf(event_dev); -+ if (ret != 0) - return NOTIFY_DONE; - - switch (event) { - case NETDEV_POST_INIT: - return netvsc_prepare_bonding(event_dev); - case NETDEV_REGISTER: -- return netvsc_register_vf(event_dev); -+ return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER); - case NETDEV_UNREGISTER: - return netvsc_unregister_vf(event_dev); - case NETDEV_UP: -diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -index 585e8cd2d332d..f5fcc547de391 100644 ---- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -@@ -576,7 +576,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 2) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -592,7 +592,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 1) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -608,7 +608,7 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 0) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -665,7 +665,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 2) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -681,7 +681,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 1) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -697,7 +697,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt) - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 0) { -- ret = PTR_ERR(wifi_pkg); -+ ret = -EINVAL; - goto out_free; - } - -@@ -1044,6 +1044,9 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) - goto read_table; - } - -+ ret = PTR_ERR(wifi_pkg); -+ goto out_free; -+ - read_table: - fwrt->ppag_ver = tbl_rev; - flags = &wifi_pkg->package.elements[1]; -diff --git a/drivers/net/wireless/marvell/mwifiex/Kconfig b/drivers/net/wireless/marvell/mwifiex/Kconfig -index 2b4ff2b78a7e1..b182f7155d66f 100644 ---- a/drivers/net/wireless/marvell/mwifiex/Kconfig -+++ b/drivers/net/wireless/marvell/mwifiex/Kconfig -@@ -10,13 +10,14 @@ config MWIFIEX - mwifiex. - - config MWIFIEX_SDIO -- tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8887/SD8897/SD8977/SD8987/SD8997" -+ tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8887/SD8897/SD8977/SD8978/SD8987/SD8997" - depends on MWIFIEX && MMC - select FW_LOADER - select WANT_DEV_COREDUMP - help - This adds support for wireless adapters based on Marvell -- 8786/8787/8797/8887/8897/8977/8987/8997 chipsets with SDIO interface. -+ 8786/8787/8797/8887/8897/8977/8978/8987/8997 chipsets with -+ SDIO interface. SD8978 is also known as NXP IW416. - - If you choose to build it as a module, it will be called - mwifiex_sdio. -diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c -index ea1c1c2412e72..2c9b70e9a7263 100644 ---- a/drivers/net/wireless/marvell/mwifiex/sdio.c -+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c -@@ -263,7 +263,7 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = { - 0x68, 0x69, 0x6a}, - }; - --static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8987 = { -+static const struct mwifiex_sdio_card_reg mwifiex_reg_sd89xx = { - .start_rd_port = 0, - .start_wr_port = 0, - .base_0_reg = 0xF8, -@@ -331,6 +331,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { - .can_dump_fw = false, - .can_auto_tdls = false, - .can_ext_scan = false, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { -@@ -346,6 +347,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { - .can_dump_fw = false, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { -@@ -361,6 +363,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { - .can_dump_fw = false, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { -@@ -376,6 +379,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { - .can_dump_fw = true, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { -@@ -392,6 +396,24 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { - .fw_dump_enh = true, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, -+}; -+ -+static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { -+ .firmware_sdiouart = SD8978_SDIOUART_FW_NAME, -+ .reg = &mwifiex_reg_sd89xx, -+ .max_ports = 32, -+ .mp_agg_pkt_limit = 16, -+ .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, -+ .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX, -+ .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX, -+ .supports_sdio_new_mode = true, -+ .has_control_mask = false, -+ .can_dump_fw = true, -+ .fw_dump_enh = true, -+ .can_auto_tdls = false, -+ .can_ext_scan = true, -+ .fw_ready_extra_delay = true, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { -@@ -409,6 +431,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { - .fw_dump_enh = true, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { -@@ -424,11 +447,12 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { - .can_dump_fw = false, - .can_auto_tdls = true, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { - .firmware = SD8987_DEFAULT_FW_NAME, -- .reg = &mwifiex_reg_sd8987, -+ .reg = &mwifiex_reg_sd89xx, - .max_ports = 32, - .mp_agg_pkt_limit = 16, - .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, -@@ -440,6 +464,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { - .fw_dump_enh = true, - .can_auto_tdls = true, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { -@@ -455,6 +480,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { - .can_dump_fw = false, - .can_auto_tdls = false, - .can_ext_scan = true, -+ .fw_ready_extra_delay = false, - }; - - static struct memory_type_mapping generic_mem_type_map[] = { -@@ -482,7 +508,9 @@ static struct memory_type_mapping mem_type_mapping_tbl[] = { - static const struct of_device_id mwifiex_sdio_of_match_table[] __maybe_unused = { - { .compatible = "marvell,sd8787" }, - { .compatible = "marvell,sd8897" }, -+ { .compatible = "marvell,sd8978" }, - { .compatible = "marvell,sd8997" }, -+ { .compatible = "nxp,iw416" }, - { } - }; - -@@ -545,6 +573,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) - card->fw_dump_enh = data->fw_dump_enh; - card->can_auto_tdls = data->can_auto_tdls; - card->can_ext_scan = data->can_ext_scan; -+ card->fw_ready_extra_delay = data->fw_ready_extra_delay; - INIT_WORK(&card->work, mwifiex_sdio_work); - } - -@@ -748,8 +777,9 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) - static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, - u32 poll_num) - { -+ struct sdio_mmc_card *card = adapter->card; - int ret = 0; -- u16 firmware_stat; -+ u16 firmware_stat = 0; - u32 tries; - - for (tries = 0; tries < poll_num; tries++) { -@@ -765,6 +795,13 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, - ret = -1; - } - -+ if (card->fw_ready_extra_delay && -+ firmware_stat == FIRMWARE_READY_SDIO) -+ /* firmware might pretend to be ready, when it's not. -+ * Wait a little bit more as a workaround. -+ */ -+ msleep(100); -+ - return ret; - } - -@@ -920,6 +957,8 @@ static const struct sdio_device_id mwifiex_ids[] = { - .driver_data = (unsigned long)&mwifiex_sdio_sd8801}, - {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8977_WLAN), - .driver_data = (unsigned long)&mwifiex_sdio_sd8977}, -+ {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8978_WLAN), -+ .driver_data = (unsigned long)&mwifiex_sdio_sd8978}, - {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8987_WLAN), - .driver_data = (unsigned long)&mwifiex_sdio_sd8987}, - {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8997_WLAN), -@@ -3164,6 +3203,7 @@ MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); - MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME); - MODULE_FIRMWARE(SD8887_DEFAULT_FW_NAME); - MODULE_FIRMWARE(SD8977_DEFAULT_FW_NAME); -+MODULE_FIRMWARE(SD8978_SDIOUART_FW_NAME); - MODULE_FIRMWARE(SD8987_DEFAULT_FW_NAME); - MODULE_FIRMWARE(SD8997_DEFAULT_FW_NAME); - MODULE_FIRMWARE(SD8997_SDIOUART_FW_NAME); -diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h -index 3a24bb48b2996..a5112cb35cdcd 100644 ---- a/drivers/net/wireless/marvell/mwifiex/sdio.h -+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h -@@ -25,6 +25,7 @@ - #define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin" - #define SD8801_DEFAULT_FW_NAME "mrvl/sd8801_uapsta.bin" - #define SD8977_DEFAULT_FW_NAME "mrvl/sdsd8977_combo_v2.bin" -+#define SD8978_SDIOUART_FW_NAME "mrvl/sdiouartiw416_combo_v0.bin" - #define SD8987_DEFAULT_FW_NAME "mrvl/sd8987_uapsta.bin" - #define SD8997_DEFAULT_FW_NAME "mrvl/sdsd8997_combo_v4.bin" - #define SD8997_SDIOUART_FW_NAME "mrvl/sdiouart8997_combo_v4.bin" -@@ -257,6 +258,7 @@ struct sdio_mmc_card { - bool fw_dump_enh; - bool can_auto_tdls; - bool can_ext_scan; -+ bool fw_ready_extra_delay; - - struct mwifiex_sdio_mpa_tx mpa_tx; - struct mwifiex_sdio_mpa_rx mpa_rx; -@@ -280,6 +282,7 @@ struct mwifiex_sdio_device { - bool fw_dump_enh; - bool can_auto_tdls; - bool can_ext_scan; -+ bool fw_ready_extra_delay; - }; - - /* -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index 2716040985748..0d51c900c5538 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -104,13 +104,12 @@ bool provides_xdp_headroom = true; - module_param(provides_xdp_headroom, bool, 0644); - - static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, -- u8 status); -+ s8 status); - - static void make_tx_response(struct xenvif_queue *queue, -- struct xen_netif_tx_request *txp, -+ const struct xen_netif_tx_request *txp, - unsigned int extra_count, -- s8 st); --static void push_tx_responses(struct xenvif_queue *queue); -+ s8 status); - - static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); - -@@ -208,13 +207,9 @@ static void xenvif_tx_err(struct xenvif_queue *queue, - unsigned int extra_count, RING_IDX end) - { - RING_IDX cons = queue->tx.req_cons; -- unsigned long flags; - - do { -- spin_lock_irqsave(&queue->response_lock, flags); - make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); -- push_tx_responses(queue); -- spin_unlock_irqrestore(&queue->response_lock, flags); - if (cons == end) - break; - RING_COPY_REQUEST(&queue->tx, cons++, txp); -@@ -465,12 +460,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; - nr_slots--) { - if (unlikely(!txp->size)) { -- unsigned long flags; -- -- spin_lock_irqsave(&queue->response_lock, flags); - make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); -- push_tx_responses(queue); -- spin_unlock_irqrestore(&queue->response_lock, flags); - ++txp; - continue; - } -@@ -496,14 +486,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - - for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { - if (unlikely(!txp->size)) { -- unsigned long flags; -- -- spin_lock_irqsave(&queue->response_lock, flags); - make_tx_response(queue, txp, 0, - XEN_NETIF_RSP_OKAY); -- push_tx_responses(queue); -- spin_unlock_irqrestore(&queue->response_lock, -- flags); - continue; - } - -@@ -997,7 +981,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, - (ret == 0) ? - XEN_NETIF_RSP_OKAY : - XEN_NETIF_RSP_ERROR); -- push_tx_responses(queue); - continue; - } - -@@ -1009,7 +992,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, - - make_tx_response(queue, &txreq, extra_count, - XEN_NETIF_RSP_OKAY); -- push_tx_responses(queue); - continue; - } - -@@ -1444,8 +1426,35 @@ int xenvif_tx_action(struct xenvif_queue *queue, int budget) - return work_done; - } - -+static void _make_tx_response(struct xenvif_queue *queue, -+ const struct xen_netif_tx_request *txp, -+ unsigned int extra_count, -+ s8 status) -+{ -+ RING_IDX i = queue->tx.rsp_prod_pvt; -+ struct xen_netif_tx_response *resp; -+ -+ resp = RING_GET_RESPONSE(&queue->tx, i); -+ resp->id = txp->id; -+ resp->status = status; -+ -+ while (extra_count-- != 0) -+ RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; -+ -+ queue->tx.rsp_prod_pvt = ++i; -+} -+ -+static void push_tx_responses(struct xenvif_queue *queue) -+{ -+ int notify; -+ -+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); -+ if (notify) -+ notify_remote_via_irq(queue->tx_irq); -+} -+ - static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, -- u8 status) -+ s8 status) - { - struct pending_tx_info *pending_tx_info; - pending_ring_idx_t index; -@@ -1455,8 +1464,8 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, - - spin_lock_irqsave(&queue->response_lock, flags); - -- make_tx_response(queue, &pending_tx_info->req, -- pending_tx_info->extra_count, status); -+ _make_tx_response(queue, &pending_tx_info->req, -+ pending_tx_info->extra_count, status); - - /* Release the pending index before pusing the Tx response so - * its available before a new Tx request is pushed by the -@@ -1470,32 +1479,19 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, - spin_unlock_irqrestore(&queue->response_lock, flags); - } - -- - static void make_tx_response(struct xenvif_queue *queue, -- struct xen_netif_tx_request *txp, -+ const struct xen_netif_tx_request *txp, - unsigned int extra_count, -- s8 st) -+ s8 status) - { -- RING_IDX i = queue->tx.rsp_prod_pvt; -- struct xen_netif_tx_response *resp; -- -- resp = RING_GET_RESPONSE(&queue->tx, i); -- resp->id = txp->id; -- resp->status = st; -- -- while (extra_count-- != 0) -- RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; -+ unsigned long flags; - -- queue->tx.rsp_prod_pvt = ++i; --} -+ spin_lock_irqsave(&queue->response_lock, flags); - --static void push_tx_responses(struct xenvif_queue *queue) --{ -- int notify; -+ _make_tx_response(queue, txp, extra_count, status); -+ push_tx_responses(queue); - -- RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); -- if (notify) -- notify_remote_via_irq(queue->tx_irq); -+ spin_unlock_irqrestore(&queue->response_lock, flags); - } - - static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) -diff --git a/drivers/of/property.c b/drivers/of/property.c -index b636777e6f7c8..33d5f16c81204 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -762,7 +762,9 @@ struct device_node *of_graph_get_port_parent(struct device_node *node) - /* Walk 3 levels up only if there is 'ports' node. */ - for (depth = 3; depth && node; depth--) { - node = of_get_next_parent(node); -- if (depth == 2 && !of_node_name_eq(node, "ports")) -+ if (depth == 2 && !of_node_name_eq(node, "ports") && -+ !of_node_name_eq(node, "in-ports") && -+ !of_node_name_eq(node, "out-ports")) - break; - } - return node; -@@ -1243,7 +1245,7 @@ DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells") - DEFINE_SIMPLE_PROP(interconnects, "interconnects", "#interconnect-cells") - DEFINE_SIMPLE_PROP(iommus, "iommus", "#iommu-cells") - DEFINE_SIMPLE_PROP(mboxes, "mboxes", "#mbox-cells") --DEFINE_SIMPLE_PROP(io_channels, "io-channel", "#io-channel-cells") -+DEFINE_SIMPLE_PROP(io_channels, "io-channels", "#io-channel-cells") - DEFINE_SIMPLE_PROP(interrupt_parent, "interrupt-parent", NULL) - DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-cells") - DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells") -@@ -1261,7 +1263,6 @@ DEFINE_SIMPLE_PROP(pinctrl5, "pinctrl-5", NULL) - DEFINE_SIMPLE_PROP(pinctrl6, "pinctrl-6", NULL) - DEFINE_SIMPLE_PROP(pinctrl7, "pinctrl-7", NULL) - DEFINE_SIMPLE_PROP(pinctrl8, "pinctrl-8", NULL) --DEFINE_SIMPLE_PROP(remote_endpoint, "remote-endpoint", NULL) - DEFINE_SIMPLE_PROP(pwms, "pwms", "#pwm-cells") - DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells") - DEFINE_SIMPLE_PROP(leds, "leds", NULL) -@@ -1326,6 +1327,17 @@ static struct device_node *parse_interrupts(struct device_node *np, - return of_irq_parse_one(np, index, &sup_args) ? NULL : sup_args.np; - } - -+static struct device_node *parse_remote_endpoint(struct device_node *np, -+ const char *prop_name, -+ int index) -+{ -+ /* Return NULL for index > 0 to signify end of remote-endpoints. */ -+ if (!index || strcmp(prop_name, "remote-endpoint")) -+ return NULL; -+ -+ return of_graph_get_remote_port_parent(np); -+} -+ - static const struct supplier_bindings of_supplier_bindings[] = { - { .parse_prop = parse_clocks, }, - { .parse_prop = parse_interconnects, }, -diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index e541a8960f1de..ce1386074e66b 100644 ---- a/drivers/of/unittest.c -+++ b/drivers/of/unittest.c -@@ -49,6 +49,12 @@ static struct unittest_results { - failed; \ - }) - -+#ifdef CONFIG_OF_KOBJ -+#define OF_KREF_READ(NODE) kref_read(&(NODE)->kobj.kref) -+#else -+#define OF_KREF_READ(NODE) 1 -+#endif -+ - /* - * Expected message may have a message level other than KERN_INFO. - * Print the expected message only if the current loglevel will allow -@@ -562,7 +568,7 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - pr_err("missing testcase data\n"); - return; - } -- prefs[i] = kref_read(&p[i]->kobj.kref); -+ prefs[i] = OF_KREF_READ(p[i]); - } - - rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); -@@ -685,9 +691,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); - - for (i = 0; i < ARRAY_SIZE(p); ++i) { -- unittest(prefs[i] == kref_read(&p[i]->kobj.kref), -+ unittest(prefs[i] == OF_KREF_READ(p[i]), - "provider%d: expected:%d got:%d\n", -- i, prefs[i], kref_read(&p[i]->kobj.kref)); -+ i, prefs[i], OF_KREF_READ(p[i])); - of_node_put(p[i]); - } - } -diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c -index c0f30cefec102..a416011391856 100644 ---- a/drivers/s390/net/qeth_l3_main.c -+++ b/drivers/s390/net/qeth_l3_main.c -@@ -254,9 +254,10 @@ static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover) - if (!recover) { - hash_del(&addr->hnode); - kfree(addr); -- continue; -+ } else { -+ /* prepare for recovery */ -+ addr->disp_flag = QETH_DISP_ADDR_ADD; - } -- addr->disp_flag = QETH_DISP_ADDR_ADD; - } - - mutex_unlock(&card->ip_lock); -@@ -277,9 +278,11 @@ static void qeth_l3_recover_ip(struct qeth_card *card) - if (addr->disp_flag == QETH_DISP_ADDR_ADD) { - rc = qeth_l3_register_addr_entry(card, addr); - -- if (!rc) { -+ if (!rc || rc == -EADDRINUSE || rc == -ENETDOWN) { -+ /* keep it in the records */ - addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; - } else { -+ /* bad address */ - hash_del(&addr->hnode); - kfree(addr); - } -diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c -index 8a4124e7d2043..ddc048069af25 100644 ---- a/drivers/scsi/fcoe/fcoe_ctlr.c -+++ b/drivers/scsi/fcoe/fcoe_ctlr.c -@@ -319,17 +319,16 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *sel; - struct fcoe_fcf *fcf; -- unsigned long flags; - - mutex_lock(&fip->ctlr_mutex); -- spin_lock_irqsave(&fip->ctlr_lock, flags); -+ spin_lock_bh(&fip->ctlr_lock); - - kfree_skb(fip->flogi_req); - fip->flogi_req = NULL; - list_for_each_entry(fcf, &fip->fcfs, list) - fcf->flogi_sent = 0; - -- spin_unlock_irqrestore(&fip->ctlr_lock, flags); -+ spin_unlock_bh(&fip->ctlr_lock); - sel = fip->sel_fcf; - - if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr)) -@@ -700,7 +699,6 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, - { - struct fc_frame *fp; - struct fc_frame_header *fh; -- unsigned long flags; - u16 old_xid; - u8 op; - u8 mac[ETH_ALEN]; -@@ -734,11 +732,11 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, - op = FIP_DT_FLOGI; - if (fip->mode == FIP_MODE_VN2VN) - break; -- spin_lock_irqsave(&fip->ctlr_lock, flags); -+ spin_lock_bh(&fip->ctlr_lock); - kfree_skb(fip->flogi_req); - fip->flogi_req = skb; - fip->flogi_req_send = 1; -- spin_unlock_irqrestore(&fip->ctlr_lock, flags); -+ spin_unlock_bh(&fip->ctlr_lock); - schedule_work(&fip->timer_work); - return -EINPROGRESS; - case ELS_FDISC: -@@ -1707,11 +1705,10 @@ static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip) - static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *fcf; -- unsigned long flags; - int error; - - mutex_lock(&fip->ctlr_mutex); -- spin_lock_irqsave(&fip->ctlr_lock, flags); -+ spin_lock_bh(&fip->ctlr_lock); - LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n"); - fcf = fcoe_ctlr_select(fip); - if (!fcf || fcf->flogi_sent) { -@@ -1722,7 +1719,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - fcoe_ctlr_solicit(fip, NULL); - error = fcoe_ctlr_flogi_send_locked(fip); - } -- spin_unlock_irqrestore(&fip->ctlr_lock, flags); -+ spin_unlock_bh(&fip->ctlr_lock); - mutex_unlock(&fip->ctlr_mutex); - return error; - } -@@ -1739,9 +1736,8 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *fcf; -- unsigned long flags; - -- spin_lock_irqsave(&fip->ctlr_lock, flags); -+ spin_lock_bh(&fip->ctlr_lock); - fcf = fip->sel_fcf; - if (!fcf || !fip->flogi_req_send) - goto unlock; -@@ -1768,7 +1764,7 @@ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) - } else /* XXX */ - LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n"); - unlock: -- spin_unlock_irqrestore(&fip->ctlr_lock, flags); -+ spin_unlock_bh(&fip->ctlr_lock); - } - - /** -diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c -index c2d981d5a2dd5..4fad9d85bd6f9 100644 ---- a/drivers/scsi/storvsc_drv.c -+++ b/drivers/scsi/storvsc_drv.c -@@ -326,6 +326,7 @@ enum storvsc_request_type { - */ - - static int storvsc_ringbuffer_size = (128 * 1024); -+static int aligned_ringbuffer_size; - static u32 max_outstanding_req_per_channel; - static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth); - -@@ -683,8 +684,8 @@ static void handle_sc_creation(struct vmbus_channel *new_sc) - new_sc->next_request_id_callback = storvsc_next_request_id; - - ret = vmbus_open(new_sc, -- storvsc_ringbuffer_size, -- storvsc_ringbuffer_size, -+ aligned_ringbuffer_size, -+ aligned_ringbuffer_size, - (void *)&props, - sizeof(struct vmstorage_channel_properties), - storvsc_on_channel_callback, new_sc); -@@ -1964,7 +1965,7 @@ static int storvsc_probe(struct hv_device *device, - dma_set_min_align_mask(&device->device, HV_HYP_PAGE_SIZE - 1); - - stor_device->port_number = host->host_no; -- ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc); -+ ret = storvsc_connect_to_vsp(device, aligned_ringbuffer_size, is_fc); - if (ret) - goto err_out1; - -@@ -2157,7 +2158,7 @@ static int storvsc_resume(struct hv_device *hv_dev) - { - int ret; - -- ret = storvsc_connect_to_vsp(hv_dev, storvsc_ringbuffer_size, -+ ret = storvsc_connect_to_vsp(hv_dev, aligned_ringbuffer_size, - hv_dev_is_fc(hv_dev)); - return ret; - } -@@ -2191,8 +2192,9 @@ static int __init storvsc_drv_init(void) - * the ring buffer indices) by the max request size (which is - * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) - */ -+ aligned_ringbuffer_size = VMBUS_RING_SIZE(storvsc_ringbuffer_size); - max_outstanding_req_per_channel = -- ((storvsc_ringbuffer_size - PAGE_SIZE) / -+ ((aligned_ringbuffer_size - PAGE_SIZE) / - ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); -diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c -index d65f047b6c823..1179a1115137f 100644 ---- a/drivers/spi/spi-ppc4xx.c -+++ b/drivers/spi/spi-ppc4xx.c -@@ -166,10 +166,8 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t) - int scr; - u8 cdm = 0; - u32 speed; -- u8 bits_per_word; - - /* Start with the generic configuration for this device. */ -- bits_per_word = spi->bits_per_word; - speed = spi->max_speed_hz; - - /* -@@ -177,9 +175,6 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t) - * the transfer to overwrite the generic configuration with zeros. - */ - if (t) { -- if (t->bits_per_word) -- bits_per_word = t->bits_per_word; -- - if (t->speed_hz) - speed = min(t->speed_hz, spi->max_speed_hz); - } -diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c -index f177b20f0f2d9..ceba632138940 100644 ---- a/drivers/staging/iio/impedance-analyzer/ad5933.c -+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c -@@ -608,7 +608,7 @@ static void ad5933_work(struct work_struct *work) - struct ad5933_state, work.work); - struct iio_dev *indio_dev = i2c_get_clientdata(st->client); - __be16 buf[2]; -- int val[2]; -+ u16 val[2]; - unsigned char status; - int ret; - -diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c -index 338cb19dec23c..163a89f84c9c2 100644 ---- a/drivers/tty/serial/max310x.c -+++ b/drivers/tty/serial/max310x.c -@@ -237,6 +237,14 @@ - #define MAX310x_REV_MASK (0xf8) - #define MAX310X_WRITE_BIT 0x80 - -+/* Port startup definitions */ -+#define MAX310X_PORT_STARTUP_WAIT_RETRIES 20 /* Number of retries */ -+#define MAX310X_PORT_STARTUP_WAIT_DELAY_MS 10 /* Delay between retries */ -+ -+/* Crystal-related definitions */ -+#define MAX310X_XTAL_WAIT_RETRIES 20 /* Number of retries */ -+#define MAX310X_XTAL_WAIT_DELAY_MS 10 /* Delay between retries */ -+ - /* MAX3107 specific */ - #define MAX3107_REV_ID (0xa0) - -@@ -583,7 +591,7 @@ static int max310x_update_best_err(unsigned long f, long *besterr) - return 1; - } - --static u32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s, -+static s32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s, - unsigned long freq, bool xtal) - { - unsigned int div, clksrc, pllcfg = 0; -@@ -641,12 +649,20 @@ static u32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s, - - /* Wait for crystal */ - if (xtal) { -- unsigned int val; -- msleep(10); -- regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val); -- if (!(val & MAX310X_STS_CLKREADY_BIT)) { -- dev_warn(dev, "clock is not stable yet\n"); -- } -+ bool stable = false; -+ unsigned int try = 0, val = 0; -+ -+ do { -+ msleep(MAX310X_XTAL_WAIT_DELAY_MS); -+ regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val); -+ -+ if (val & MAX310X_STS_CLKREADY_BIT) -+ stable = true; -+ } while (!stable && (++try < MAX310X_XTAL_WAIT_RETRIES)); -+ -+ if (!stable) -+ return dev_err_probe(dev, -EAGAIN, -+ "clock is not stable\n"); - } - - return bestfreq; -@@ -1274,7 +1290,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty - { - int i, ret, fmin, fmax, freq; - struct max310x_port *s; -- u32 uartclk = 0; -+ s32 uartclk = 0; - bool xtal; - - for (i = 0; i < devtype->nr; i++) -@@ -1337,6 +1353,9 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty - goto out_clk; - - for (i = 0; i < devtype->nr; i++) { -+ bool started = false; -+ unsigned int try = 0, val = 0; -+ - /* Reset port */ - regmap_write(regmaps[i], MAX310X_MODE2_REG, - MAX310X_MODE2_RST_BIT); -@@ -1345,13 +1364,27 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty - - /* Wait for port startup */ - do { -- regmap_read(regmaps[i], MAX310X_BRGDIVLSB_REG, &ret); -- } while (ret != 0x01); -+ msleep(MAX310X_PORT_STARTUP_WAIT_DELAY_MS); -+ regmap_read(regmaps[i], MAX310X_BRGDIVLSB_REG, &val); -+ -+ if (val == 0x01) -+ started = true; -+ } while (!started && (++try < MAX310X_PORT_STARTUP_WAIT_RETRIES)); -+ -+ if (!started) { -+ ret = dev_err_probe(dev, -EAGAIN, "port reset failed\n"); -+ goto out_uart; -+ } - - regmap_write(regmaps[i], MAX310X_MODE1_REG, devtype->mode1); - } - - uartclk = max310x_set_ref_clk(dev, s, freq, xtal); -+ if (uartclk < 0) { -+ ret = uartclk; -+ goto out_uart; -+ } -+ - dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); - - for (i = 0; i < devtype->nr; i++) { -diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c -index 38703781ee2d1..1283c427cdf88 100644 ---- a/drivers/usb/common/ulpi.c -+++ b/drivers/usb/common/ulpi.c -@@ -301,7 +301,7 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) - return ret; - } - -- root = debugfs_create_dir(dev_name(dev), ulpi_root); -+ root = debugfs_create_dir(dev_name(&ulpi->dev), ulpi_root); - debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops); - - dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n", -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 4f181110d00db..d960a56b760ec 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -2389,17 +2389,25 @@ static int usb_enumerate_device_otg(struct usb_device *udev) - } - } else if (desc->bLength == sizeof - (struct usb_otg_descriptor)) { -- /* Set a_alt_hnp_support for legacy otg device */ -- err = usb_control_msg(udev, -- usb_sndctrlpipe(udev, 0), -- USB_REQ_SET_FEATURE, 0, -- USB_DEVICE_A_ALT_HNP_SUPPORT, -- 0, NULL, 0, -- USB_CTRL_SET_TIMEOUT); -- if (err < 0) -- dev_err(&udev->dev, -- "set a_alt_hnp_support failed: %d\n", -- err); -+ /* -+ * We are operating on a legacy OTP device -+ * These should be told that they are operating -+ * on the wrong port if we have another port that does -+ * support HNP -+ */ -+ if (bus->otg_port != 0) { -+ /* Set a_alt_hnp_support for legacy otg device */ -+ err = usb_control_msg(udev, -+ usb_sndctrlpipe(udev, 0), -+ USB_REQ_SET_FEATURE, 0, -+ USB_DEVICE_A_ALT_HNP_SUPPORT, -+ 0, NULL, 0, -+ USB_CTRL_SET_TIMEOUT); -+ if (err < 0) -+ dev_err(&udev->dev, -+ "set a_alt_hnp_support failed: %d\n", -+ err); -+ } - } - } - #endif -diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c -index c4703f6b20894..576c21bf77cda 100644 ---- a/drivers/usb/dwc3/gadget.c -+++ b/drivers/usb/dwc3/gadget.c -@@ -4583,15 +4583,13 @@ int dwc3_gadget_suspend(struct dwc3 *dwc) - unsigned long flags; - int ret; - -- if (!dwc->gadget_driver) -- return 0; -- - ret = dwc3_gadget_soft_disconnect(dwc); - if (ret) - goto err; - - spin_lock_irqsave(&dwc->lock, flags); -- dwc3_disconnect_gadget(dwc); -+ if (dwc->gadget_driver) -+ dwc3_disconnect_gadget(dwc); - spin_unlock_irqrestore(&dwc->lock, flags); - - return 0; -diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c -index 7b9a4cf9b100c..d35f30a9cae2c 100644 ---- a/drivers/usb/gadget/function/f_mass_storage.c -+++ b/drivers/usb/gadget/function/f_mass_storage.c -@@ -544,21 +544,37 @@ static int start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, - - static bool start_in_transfer(struct fsg_common *common, struct fsg_buffhd *bh) - { -+ int rc; -+ - if (!fsg_is_set(common)) - return false; - bh->state = BUF_STATE_SENDING; -- if (start_transfer(common->fsg, common->fsg->bulk_in, bh->inreq)) -+ rc = start_transfer(common->fsg, common->fsg->bulk_in, bh->inreq); -+ if (rc) { - bh->state = BUF_STATE_EMPTY; -+ if (rc == -ESHUTDOWN) { -+ common->running = 0; -+ return false; -+ } -+ } - return true; - } - - static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh) - { -+ int rc; -+ - if (!fsg_is_set(common)) - return false; - bh->state = BUF_STATE_RECEIVING; -- if (start_transfer(common->fsg, common->fsg->bulk_out, bh->outreq)) -+ rc = start_transfer(common->fsg, common->fsg->bulk_out, bh->outreq); -+ if (rc) { - bh->state = BUF_STATE_FULL; -+ if (rc == -ESHUTDOWN) { -+ common->running = 0; -+ return false; -+ } -+ } - return true; - } - -diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c -index dc2dea3768fb6..0695ee54ff781 100644 ---- a/drivers/usb/typec/ucsi/ucsi.c -+++ b/drivers/usb/typec/ucsi/ucsi.c -@@ -831,7 +831,9 @@ static void ucsi_handle_connector_change(struct work_struct *work) - - clear_bit(EVENT_PENDING, &con->ucsi->flags); - -+ mutex_lock(&ucsi->ppm_lock); - ret = ucsi_acknowledge_connector_change(ucsi); -+ mutex_unlock(&ucsi->ppm_lock); - if (ret) - dev_err(ucsi->dev, "%s: ACK failed (%d)", __func__, ret); - -diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c -index 217355f1f9b94..26171c5d3c61c 100644 ---- a/drivers/usb/typec/ucsi/ucsi_acpi.c -+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c -@@ -73,9 +73,13 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset, - const void *val, size_t val_len) - { - struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); -+ bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; - int ret; - -- set_bit(COMMAND_PENDING, &ua->flags); -+ if (ack) -+ set_bit(ACK_PENDING, &ua->flags); -+ else -+ set_bit(COMMAND_PENDING, &ua->flags); - - ret = ucsi_acpi_async_write(ucsi, offset, val, val_len); - if (ret) -@@ -85,7 +89,10 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset, - ret = -ETIMEDOUT; - - out_clear_bit: -- clear_bit(COMMAND_PENDING, &ua->flags); -+ if (ack) -+ clear_bit(ACK_PENDING, &ua->flags); -+ else -+ clear_bit(COMMAND_PENDING, &ua->flags); - - return ret; - } -@@ -142,8 +149,10 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data) - if (UCSI_CCI_CONNECTOR(cci)) - ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci)); - -- if (test_bit(COMMAND_PENDING, &ua->flags) && -- cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE)) -+ if (cci & UCSI_CCI_ACK_COMPLETE && test_bit(ACK_PENDING, &ua->flags)) -+ complete(&ua->complete); -+ if (cci & UCSI_CCI_COMMAND_COMPLETE && -+ test_bit(COMMAND_PENDING, &ua->flags)) - complete(&ua->complete); - } - -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index 08017b180a10d..9f77565bd7f5a 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -1318,6 +1318,7 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans, - */ - void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) - { -+ LIST_HEAD(retry_list); - struct btrfs_block_group *block_group; - struct btrfs_space_info *space_info; - struct btrfs_trans_handle *trans; -@@ -1339,6 +1340,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) - - spin_lock(&fs_info->unused_bgs_lock); - while (!list_empty(&fs_info->unused_bgs)) { -+ u64 used; - int trimming; - - block_group = list_first_entry(&fs_info->unused_bgs, -@@ -1374,9 +1376,9 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) - goto next; - } - -+ spin_lock(&space_info->lock); - spin_lock(&block_group->lock); -- if (block_group->reserved || block_group->pinned || -- block_group->used || block_group->ro || -+ if (btrfs_is_block_group_used(block_group) || block_group->ro || - list_is_singular(&block_group->list)) { - /* - * We want to bail if we made new allocations or have -@@ -1386,10 +1388,49 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) - */ - trace_btrfs_skip_unused_block_group(block_group); - spin_unlock(&block_group->lock); -+ spin_unlock(&space_info->lock); -+ up_write(&space_info->groups_sem); -+ goto next; -+ } -+ -+ /* -+ * The block group may be unused but there may be space reserved -+ * accounting with the existence of that block group, that is, -+ * space_info->bytes_may_use was incremented by a task but no -+ * space was yet allocated from the block group by the task. -+ * That space may or may not be allocated, as we are generally -+ * pessimistic about space reservation for metadata as well as -+ * for data when using compression (as we reserve space based on -+ * the worst case, when data can't be compressed, and before -+ * actually attempting compression, before starting writeback). -+ * -+ * So check if the total space of the space_info minus the size -+ * of this block group is less than the used space of the -+ * space_info - if that's the case, then it means we have tasks -+ * that might be relying on the block group in order to allocate -+ * extents, and add back the block group to the unused list when -+ * we finish, so that we retry later in case no tasks ended up -+ * needing to allocate extents from the block group. -+ */ -+ used = btrfs_space_info_used(space_info, true); -+ if (space_info->total_bytes - block_group->length < used) { -+ /* -+ * Add a reference for the list, compensate for the ref -+ * drop under the "next" label for the -+ * fs_info->unused_bgs list. -+ */ -+ btrfs_get_block_group(block_group); -+ list_add_tail(&block_group->bg_list, &retry_list); -+ -+ trace_btrfs_skip_unused_block_group(block_group); -+ spin_unlock(&block_group->lock); -+ spin_unlock(&space_info->lock); - up_write(&space_info->groups_sem); - goto next; - } -+ - spin_unlock(&block_group->lock); -+ spin_unlock(&space_info->lock); - - /* We don't want to force the issue, only flip if it's ok. */ - ret = inc_block_group_ro(block_group, 0); -@@ -1513,12 +1554,16 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) - btrfs_put_block_group(block_group); - spin_lock(&fs_info->unused_bgs_lock); - } -+ list_splice_tail(&retry_list, &fs_info->unused_bgs); - spin_unlock(&fs_info->unused_bgs_lock); - mutex_unlock(&fs_info->reclaim_bgs_lock); - return; - - flip_async: - btrfs_end_transaction(trans); -+ spin_lock(&fs_info->unused_bgs_lock); -+ list_splice_tail(&retry_list, &fs_info->unused_bgs); -+ spin_unlock(&fs_info->unused_bgs_lock); - mutex_unlock(&fs_info->reclaim_bgs_lock); - btrfs_put_block_group(block_group); - btrfs_discard_punt_unused_bgs_list(fs_info); -diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h -index 47a2dcbfee255..bace40a006379 100644 ---- a/fs/btrfs/block-group.h -+++ b/fs/btrfs/block-group.h -@@ -241,6 +241,13 @@ static inline u64 btrfs_block_group_end(struct btrfs_block_group *block_group) - return (block_group->start + block_group->length); - } - -+static inline bool btrfs_is_block_group_used(const struct btrfs_block_group *bg) -+{ -+ lockdep_assert_held(&bg->lock); -+ -+ return (bg->used > 0 || bg->reserved > 0 || bg->pinned > 0); -+} -+ - static inline bool btrfs_is_block_group_data_only( - struct btrfs_block_group *block_group) - { -diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c -index f2bc5563c0f92..63b7fa7067434 100644 ---- a/fs/btrfs/delalloc-space.c -+++ b/fs/btrfs/delalloc-space.c -@@ -243,7 +243,6 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info, - struct btrfs_block_rsv *block_rsv = &inode->block_rsv; - u64 reserve_size = 0; - u64 qgroup_rsv_size = 0; -- u64 csum_leaves; - unsigned outstanding_extents; - - lockdep_assert_held(&inode->lock); -@@ -258,10 +257,12 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info, - outstanding_extents); - reserve_size += btrfs_calc_metadata_size(fs_info, 1); - } -- csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, -- inode->csum_bytes); -- reserve_size += btrfs_calc_insert_metadata_size(fs_info, -- csum_leaves); -+ if (!(inode->flags & BTRFS_INODE_NODATASUM)) { -+ u64 csum_leaves; -+ -+ csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes); -+ reserve_size += btrfs_calc_insert_metadata_size(fs_info, csum_leaves); -+ } - /* - * For qgroup rsv, the calculation is very simple: - * account one nodesize for each outstanding extent -@@ -276,14 +277,20 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info, - spin_unlock(&block_rsv->lock); - } - --static void calc_inode_reservations(struct btrfs_fs_info *fs_info, -+static void calc_inode_reservations(struct btrfs_inode *inode, - u64 num_bytes, u64 disk_num_bytes, - u64 *meta_reserve, u64 *qgroup_reserve) - { -+ struct btrfs_fs_info *fs_info = inode->root->fs_info; - u64 nr_extents = count_max_extents(fs_info, num_bytes); -- u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes); -+ u64 csum_leaves; - u64 inode_update = btrfs_calc_metadata_size(fs_info, 1); - -+ if (inode->flags & BTRFS_INODE_NODATASUM) -+ csum_leaves = 0; -+ else -+ csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes); -+ - *meta_reserve = btrfs_calc_insert_metadata_size(fs_info, - nr_extents + csum_leaves); - -@@ -335,7 +342,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, - * everything out and try again, which is bad. This way we just - * over-reserve slightly, and clean up the mess when we are done. - */ -- calc_inode_reservations(fs_info, num_bytes, disk_num_bytes, -+ calc_inode_reservations(inode, num_bytes, disk_num_bytes, - &meta_reserve, &qgroup_reserve); - ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true, - noflush); -@@ -356,7 +363,8 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, - spin_lock(&inode->lock); - nr_extents = count_max_extents(fs_info, num_bytes); - btrfs_mod_outstanding_extents(inode, nr_extents); -- inode->csum_bytes += disk_num_bytes; -+ if (!(inode->flags & BTRFS_INODE_NODATASUM)) -+ inode->csum_bytes += disk_num_bytes; - btrfs_calculate_inode_block_rsv_size(fs_info, inode); - spin_unlock(&inode->lock); - -@@ -390,7 +398,8 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes, - - num_bytes = ALIGN(num_bytes, fs_info->sectorsize); - spin_lock(&inode->lock); -- inode->csum_bytes -= num_bytes; -+ if (!(inode->flags & BTRFS_INODE_NODATASUM)) -+ inode->csum_bytes -= num_bytes; - btrfs_calculate_inode_block_rsv_size(fs_info, inode); - spin_unlock(&inode->lock); - -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 40152458e7b74..0d1b05ded1e35 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -1662,8 +1662,17 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, - again: - root = btrfs_lookup_fs_root(fs_info, objectid); - if (root) { -- /* Shouldn't get preallocated anon_dev for cached roots */ -- ASSERT(!anon_dev); -+ /* -+ * Some other caller may have read out the newly inserted -+ * subvolume already (for things like backref walk etc). Not -+ * that common but still possible. In that case, we just need -+ * to free the anon_dev. -+ */ -+ if (unlikely(anon_dev)) { -+ free_anon_bdev(anon_dev); -+ anon_dev = 0; -+ } -+ - if (check_ref && btrfs_root_refs(&root->root_item) == 0) { - btrfs_put_root(root); - return ERR_PTR(-ENOENT); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 82f92b5652a77..f7f4bcc094642 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -3364,8 +3364,23 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) - unwritten_start += logical_len; - clear_extent_uptodate(io_tree, unwritten_start, end, NULL); - -- /* Drop extent maps for the part of the extent we didn't write. */ -- btrfs_drop_extent_map_range(inode, unwritten_start, end, false); -+ /* -+ * Drop extent maps for the part of the extent we didn't write. -+ * -+ * We have an exception here for the free_space_inode, this is -+ * because when we do btrfs_get_extent() on the free space inode -+ * we will search the commit root. If this is a new block group -+ * we won't find anything, and we will trip over the assert in -+ * writepage where we do ASSERT(em->block_start != -+ * EXTENT_MAP_HOLE). -+ * -+ * Theoretically we could also skip this for any NOCOW extent as -+ * we don't mess with the extent map tree in the NOCOW case, but -+ * for now simply skip this if we are the free space inode. -+ */ -+ if (!btrfs_is_free_space_inode(inode)) -+ btrfs_drop_extent_map_range(inode, unwritten_start, -+ end, false); - - /* - * If the ordered extent had an IOERR or something else went -@@ -10774,6 +10789,13 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, - if (encoded->encryption != BTRFS_ENCODED_IO_ENCRYPTION_NONE) - return -EINVAL; - -+ /* -+ * Compressed extents should always have checksums, so error out if we -+ * have a NOCOW file or inode was created while mounted with NODATASUM. -+ */ -+ if (inode->flags & BTRFS_INODE_NODATASUM) -+ return -EINVAL; -+ - orig_count = iov_iter_count(from); - - /* The extent size must be sane. */ -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 8516c70b5edc1..196e222749ccd 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -4695,6 +4695,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) - goto out; - } - -+ if (sa->create && is_fstree(sa->qgroupid)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ - trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); -diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c -index 96ec9ccc2ef61..b3472bf6b288f 100644 ---- a/fs/btrfs/qgroup.c -+++ b/fs/btrfs/qgroup.c -@@ -1635,6 +1635,15 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) - return ret; - } - -+static bool qgroup_has_usage(struct btrfs_qgroup *qgroup) -+{ -+ return (qgroup->rfer > 0 || qgroup->rfer_cmpr > 0 || -+ qgroup->excl > 0 || qgroup->excl_cmpr > 0 || -+ qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA] > 0 || -+ qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC] > 0 || -+ qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > 0); -+} -+ - int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) - { - struct btrfs_fs_info *fs_info = trans->fs_info; -@@ -1654,6 +1663,11 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) - goto out; - } - -+ if (is_fstree(qgroupid) && qgroup_has_usage(qgroup)) { -+ ret = -EBUSY; -+ goto out; -+ } -+ - /* Check if there are no children of this qgroup */ - if (!list_empty(&qgroup->members)) { - ret = -EBUSY; -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index 4a4d65b5e24f7..a75669972dc73 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -7852,7 +7852,7 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg) - } - - if (arg->flags & ~BTRFS_SEND_FLAG_MASK) { -- ret = -EINVAL; -+ ret = -EOPNOTSUPP; - goto out; - } - -diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c -index 111938a6307e6..57603782e7e2a 100644 ---- a/fs/ceph/caps.c -+++ b/fs/ceph/caps.c -@@ -1391,7 +1391,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap, - if (flushing & CEPH_CAP_XATTR_EXCL) { - arg->old_xattr_buf = __ceph_build_xattrs_blob(ci); - arg->xattr_version = ci->i_xattrs.version; -- arg->xattr_buf = ci->i_xattrs.blob; -+ arg->xattr_buf = ceph_buffer_get(ci->i_xattrs.blob); - } else { - arg->xattr_buf = NULL; - arg->old_xattr_buf = NULL; -@@ -1457,6 +1457,7 @@ static void __send_cap(struct cap_msg_args *arg, struct ceph_inode_info *ci) - encode_cap_msg(msg, arg); - ceph_con_send(&arg->session->s_con, msg); - ceph_buffer_put(arg->old_xattr_buf); -+ ceph_buffer_put(arg->xattr_buf); - if (arg->wake) - wake_up_all(&ci->i_cap_wq); - } -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 40903c172a34f..1a310ee7d9e55 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -1785,11 +1785,6 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, - mb_check_buddy(e4b); - mb_free_blocks_double(inode, e4b, first, count); - -- this_cpu_inc(discard_pa_seq); -- e4b->bd_info->bb_free += count; -- if (first < e4b->bd_info->bb_first_free) -- e4b->bd_info->bb_first_free = first; -- - /* access memory sequentially: check left neighbour, - * clear range and then check right neighbour - */ -@@ -1803,23 +1798,31 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, - struct ext4_sb_info *sbi = EXT4_SB(sb); - ext4_fsblk_t blocknr; - -+ /* -+ * Fastcommit replay can free already freed blocks which -+ * corrupts allocation info. Regenerate it. -+ */ -+ if (sbi->s_mount_state & EXT4_FC_REPLAY) { -+ mb_regenerate_buddy(e4b); -+ goto check; -+ } -+ - blocknr = ext4_group_first_block_no(sb, e4b->bd_group); - blocknr += EXT4_C2B(sbi, block); -- if (!(sbi->s_mount_state & EXT4_FC_REPLAY)) { -- ext4_grp_locked_error(sb, e4b->bd_group, -- inode ? inode->i_ino : 0, -- blocknr, -- "freeing already freed block (bit %u); block bitmap corrupt.", -- block); -- ext4_mark_group_bitmap_corrupted( -- sb, e4b->bd_group, -+ ext4_grp_locked_error(sb, e4b->bd_group, -+ inode ? inode->i_ino : 0, blocknr, -+ "freeing already freed block (bit %u); block bitmap corrupt.", -+ block); -+ ext4_mark_group_bitmap_corrupted(sb, e4b->bd_group, - EXT4_GROUP_INFO_BBITMAP_CORRUPT); -- } else { -- mb_regenerate_buddy(e4b); -- } -- goto done; -+ return; - } - -+ this_cpu_inc(discard_pa_seq); -+ e4b->bd_info->bb_free += count; -+ if (first < e4b->bd_info->bb_first_free) -+ e4b->bd_info->bb_first_free = first; -+ - /* let's maintain fragments counter */ - if (left_is_free && right_is_free) - e4b->bd_info->bb_fragments--; -@@ -1844,9 +1847,9 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, - if (first <= last) - mb_buddy_mark_free(e4b, first >> 1, last >> 1); - --done: - mb_set_largest_free_order(sb, e4b->bd_info); - mb_update_avg_fragment_size(sb, e4b->bd_info); -+check: - mb_check_buddy(e4b); - } - -diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c -index dedc9d445f243..8e3ff150bc36b 100644 ---- a/fs/ext4/move_extent.c -+++ b/fs/ext4/move_extent.c -@@ -621,6 +621,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, - goto out; - o_end = o_start + len; - -+ *moved_len = 0; - while (o_start < o_end) { - struct ext4_extent *ex; - ext4_lblk_t cur_blk, next_blk; -@@ -675,7 +676,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, - */ - ext4_double_up_write_data_sem(orig_inode, donor_inode); - /* Swap original branches with new branches */ -- move_extent_per_page(o_filp, donor_inode, -+ *moved_len += move_extent_per_page(o_filp, donor_inode, - orig_page_index, donor_page_index, - offset_in_page, cur_len, - unwritten, &ret); -@@ -685,9 +686,6 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, - o_start += cur_len; - d_start += cur_len; - } -- *moved_len = o_start - orig_blk; -- if (*moved_len > len) -- *moved_len = len; - - out: - if (*moved_len) { -diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c -index 8eea709e36599..4fe4b3393e71c 100644 ---- a/fs/hugetlbfs/inode.c -+++ b/fs/hugetlbfs/inode.c -@@ -123,6 +123,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) - loff_t len, vma_len; - int ret; - struct hstate *h = hstate_file(file); -+ vm_flags_t vm_flags; - - /* - * vma address alignment (but not the pgoff alignment) has -@@ -164,10 +165,20 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) - file_accessed(file); - - ret = -ENOMEM; -+ -+ vm_flags = vma->vm_flags; -+ /* -+ * for SHM_HUGETLB, the pages are reserved in the shmget() call so skip -+ * reserving here. Note: only for SHM hugetlbfs file, the inode -+ * flag S_PRIVATE is set. -+ */ -+ if (inode->i_flags & S_PRIVATE) -+ vm_flags |= VM_NORESERVE; -+ - if (!hugetlb_reserve_pages(inode, - vma->vm_pgoff >> huge_page_order(h), - len >> huge_page_shift(h), vma, -- vma->vm_flags)) -+ vm_flags)) - goto out; - - ret = 0; -@@ -1350,6 +1361,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par - { - struct hugetlbfs_fs_context *ctx = fc->fs_private; - struct fs_parse_result result; -+ struct hstate *h; - char *rest; - unsigned long ps; - int opt; -@@ -1394,11 +1406,12 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par - - case Opt_pagesize: - ps = memparse(param->string, &rest); -- ctx->hstate = size_to_hstate(ps); -- if (!ctx->hstate) { -+ h = size_to_hstate(ps); -+ if (!h) { - pr_err("Unsupported page size %lu MB\n", ps / SZ_1M); - return -EINVAL; - } -+ ctx->hstate = h; - return 0; - - case Opt_min_size: -diff --git a/fs/namespace.c b/fs/namespace.c -index 29a8d90dd1072..1533550f73567 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -4172,10 +4172,15 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr) - /* - * If this is an attached mount make sure it's located in the callers - * mount namespace. If it's not don't let the caller interact with it. -- * If this is a detached mount make sure it has an anonymous mount -- * namespace attached to it, i.e. we've created it via OPEN_TREE_CLONE. -+ * -+ * If this mount doesn't have a parent it's most often simply a -+ * detached mount with an anonymous mount namespace. IOW, something -+ * that's simply not attached yet. But there are apparently also users -+ * that do change mount properties on the rootfs itself. That obviously -+ * neither has a parent nor is it a detached mount so we cannot -+ * unconditionally check for detached mounts. - */ -- if (!(mnt_has_parent(mnt) ? check_mnt(mnt) : is_anon_ns(mnt->mnt_ns))) -+ if ((mnt_has_parent(mnt) || !is_anon_ns(mnt->mnt_ns)) && !check_mnt(mnt)) - goto out; - - /* -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index faecdbfa01a29..b3f6dda930d8b 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -4908,10 +4908,8 @@ nfsd_break_deleg_cb(struct file_lock *fl) - */ - fl->fl_break_time = 0; - -- spin_lock(&fp->fi_lock); - fp->fi_had_conflict = true; - nfsd_break_one_deleg(dp); -- spin_unlock(&fp->fi_lock); - return false; - } - -@@ -5499,12 +5497,13 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp, - if (status) - goto out_unlock; - -+ status = -EAGAIN; -+ if (fp->fi_had_conflict) -+ goto out_unlock; -+ - spin_lock(&state_lock); - spin_lock(&fp->fi_lock); -- if (fp->fi_had_conflict) -- status = -EAGAIN; -- else -- status = hash_delegation_locked(dp, fp); -+ status = hash_delegation_locked(dp, fp); - spin_unlock(&fp->fi_lock); - spin_unlock(&state_lock); - -@@ -7736,14 +7735,16 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - { - struct file_lock *fl; - int status = false; -- struct nfsd_file *nf = find_any_file(fp); -+ struct nfsd_file *nf; - struct inode *inode; - struct file_lock_context *flctx; - -+ spin_lock(&fp->fi_lock); -+ nf = find_any_file_locked(fp); - if (!nf) { - /* Any valid lock stateid should have some sort of access */ - WARN_ON_ONCE(1); -- return status; -+ goto out; - } - - inode = locks_inode(nf->nf_file); -@@ -7759,7 +7760,8 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - } - spin_unlock(&flctx->flc_lock); - } -- nfsd_file_put(nf); -+out: -+ spin_unlock(&fp->fi_lock); - return status; - } - -@@ -7769,10 +7771,8 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - * @cstate: NFSv4 COMPOUND state - * @u: RELEASE_LOCKOWNER arguments - * -- * The lockowner's so_count is bumped when a lock record is added -- * or when copying a conflicting lock. The latter case is brief, -- * but can lead to fleeting false positives when looking for -- * locks-in-use. -+ * Check if theree are any locks still held and if not - free the lockowner -+ * and any lock state that is owned. - * - * Return values: - * %nfs_ok: lockowner released or not found -@@ -7808,10 +7808,13 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, - spin_unlock(&clp->cl_lock); - return nfs_ok; - } -- if (atomic_read(&lo->lo_owner.so_count) != 2) { -- spin_unlock(&clp->cl_lock); -- nfs4_put_stateowner(&lo->lo_owner); -- return nfserr_locks_held; -+ -+ list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) { -+ if (check_for_locks(stp->st_stid.sc_file, lo)) { -+ spin_unlock(&clp->cl_lock); -+ nfs4_put_stateowner(&lo->lo_owner); -+ return nfserr_locks_held; -+ } - } - unhash_lockowner_locked(lo); - while (!list_empty(&lo->lo_owner.so_stateids)) { -diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c -index 9930fa901039f..1e7f653c1df7e 100644 ---- a/fs/nilfs2/dat.c -+++ b/fs/nilfs2/dat.c -@@ -40,8 +40,21 @@ static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat) - static int nilfs_dat_prepare_entry(struct inode *dat, - struct nilfs_palloc_req *req, int create) - { -- return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr, -- create, &req->pr_entry_bh); -+ int ret; -+ -+ ret = nilfs_palloc_get_entry_block(dat, req->pr_entry_nr, -+ create, &req->pr_entry_bh); -+ if (unlikely(ret == -ENOENT)) { -+ nilfs_err(dat->i_sb, -+ "DAT doesn't have a block to manage vblocknr = %llu", -+ (unsigned long long)req->pr_entry_nr); -+ /* -+ * Return internal code -EINVAL to notify bmap layer of -+ * metadata corruption. -+ */ -+ ret = -EINVAL; -+ } -+ return ret; - } - - static void nilfs_dat_commit_entry(struct inode *dat, -@@ -123,11 +136,7 @@ static void nilfs_dat_commit_free(struct inode *dat, - - int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req) - { -- int ret; -- -- ret = nilfs_dat_prepare_entry(dat, req, 0); -- WARN_ON(ret == -ENOENT); -- return ret; -+ return nilfs_dat_prepare_entry(dat, req, 0); - } - - void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, -@@ -154,10 +163,8 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) - int ret; - - ret = nilfs_dat_prepare_entry(dat, req, 0); -- if (ret < 0) { -- WARN_ON(ret == -ENOENT); -+ if (ret < 0) - return ret; -- } - - kaddr = kmap_atomic(req->pr_entry_bh->b_page); - entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, -diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c -index a265d391ffe92..822e8d95d31ef 100644 ---- a/fs/nilfs2/file.c -+++ b/fs/nilfs2/file.c -@@ -105,7 +105,13 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf) - nilfs_transaction_commit(inode->i_sb); - - mapped: -- wait_for_stable_page(page); -+ /* -+ * Since checksumming including data blocks is performed to determine -+ * the validity of the log to be written and used for recovery, it is -+ * necessary to wait for writeback to finish here, regardless of the -+ * stable write requirement of the backing device. -+ */ -+ wait_on_page_writeback(page); - out: - sb_end_pagefault(inode->i_sb); - return block_page_mkwrite_return(ret); -diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c -index 0955b657938ff..a9b8d77c8c1d5 100644 ---- a/fs/nilfs2/recovery.c -+++ b/fs/nilfs2/recovery.c -@@ -472,9 +472,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, - - static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, - struct nilfs_recovery_block *rb, -- struct page *page) -+ loff_t pos, struct page *page) - { - struct buffer_head *bh_org; -+ size_t from = pos & ~PAGE_MASK; - void *kaddr; - - bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize); -@@ -482,7 +483,7 @@ static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, - return -EIO; - - kaddr = kmap_atomic(page); -- memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size); -+ memcpy(kaddr + from, bh_org->b_data, bh_org->b_size); - kunmap_atomic(kaddr); - brelse(bh_org); - return 0; -@@ -521,7 +522,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, - goto failed_inode; - } - -- err = nilfs_recovery_copy_block(nilfs, rb, page); -+ err = nilfs_recovery_copy_block(nilfs, rb, pos, page); - if (unlikely(err)) - goto failed_page; - -diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c -index a4a147a983e0a..0a84613960dbf 100644 ---- a/fs/nilfs2/segment.c -+++ b/fs/nilfs2/segment.c -@@ -1702,7 +1702,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) - - list_for_each_entry(bh, &segbuf->sb_payload_buffers, - b_assoc_buffers) { -- set_buffer_async_write(bh); - if (bh == segbuf->sb_super_root) { - if (bh->b_page != bd_page) { - lock_page(bd_page); -@@ -1713,6 +1712,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) - } - break; - } -+ set_buffer_async_write(bh); - if (bh->b_page != fs_page) { - nilfs_begin_page_io(fs_page); - fs_page = bh->b_page; -@@ -1798,7 +1798,6 @@ static void nilfs_abort_logs(struct list_head *logs, int err) - - list_for_each_entry(bh, &segbuf->sb_payload_buffers, - b_assoc_buffers) { -- clear_buffer_async_write(bh); - if (bh == segbuf->sb_super_root) { - clear_buffer_uptodate(bh); - if (bh->b_page != bd_page) { -@@ -1807,6 +1806,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) - } - break; - } -+ clear_buffer_async_write(bh); - if (bh->b_page != fs_page) { - nilfs_end_page_io(fs_page, err); - fs_page = bh->b_page; -@@ -1894,8 +1894,9 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) - BIT(BH_Delay) | BIT(BH_NILFS_Volatile) | - BIT(BH_NILFS_Redirected)); - -- set_mask_bits(&bh->b_state, clear_bits, set_bits); - if (bh == segbuf->sb_super_root) { -+ set_buffer_uptodate(bh); -+ clear_buffer_dirty(bh); - if (bh->b_page != bd_page) { - end_page_writeback(bd_page); - bd_page = bh->b_page; -@@ -1903,6 +1904,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) - update_sr = true; - break; - } -+ set_mask_bits(&bh->b_state, clear_bits, set_bits); - if (bh->b_page != fs_page) { - nilfs_end_page_io(fs_page, 0); - fs_page = bh->b_page; -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index 873b1434a9989..4b72bc7f12ca3 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -1842,10 +1842,12 @@ int ntfs_security_init(struct ntfs_sb_info *sbi) - goto out; - } - -- root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT)); -- if (root_sdh->type != ATTR_ZERO || -+ if(!(root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT))) || -+ root_sdh->type != ATTR_ZERO || - root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH || -- offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) { -+ offsetof(struct INDEX_ROOT, ihdr) + -+ le32_to_cpu(root_sdh->ihdr.used) > -+ le32_to_cpu(attr->res.data_size)) { - err = -EINVAL; - goto out; - } -@@ -1861,10 +1863,12 @@ int ntfs_security_init(struct ntfs_sb_info *sbi) - goto out; - } - -- root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT)); -- if (root_sii->type != ATTR_ZERO || -+ if(!(root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT))) || -+ root_sii->type != ATTR_ZERO || - root_sii->rule != NTFS_COLLATION_TYPE_UINT || -- offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) { -+ offsetof(struct INDEX_ROOT, ihdr) + -+ le32_to_cpu(root_sii->ihdr.used) > -+ le32_to_cpu(attr->res.data_size)) { - err = -EINVAL; - goto out; - } -diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c -index b89a33f5761ef..7371f7855e4c4 100644 ---- a/fs/ntfs3/index.c -+++ b/fs/ntfs3/index.c -@@ -1097,7 +1097,8 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, - } - - /* check for index header length */ -- if (offsetof(struct INDEX_BUFFER, ihdr) + ib->ihdr.used > bytes) { -+ if (offsetof(struct INDEX_BUFFER, ihdr) + le32_to_cpu(ib->ihdr.used) > -+ bytes) { - err = -EINVAL; - goto out; - } -diff --git a/fs/proc/array.c b/fs/proc/array.c -index 49283b8103c7e..1b0d78dfd20f9 100644 ---- a/fs/proc/array.c -+++ b/fs/proc/array.c -@@ -501,7 +501,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, - - sigemptyset(&sigign); - sigemptyset(&sigcatch); -- cutime = cstime = utime = stime = 0; -+ cutime = cstime = 0; - cgtime = gtime = 0; - - if (lock_task_sighand(task, &flags)) { -@@ -535,7 +535,6 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, - - min_flt += sig->min_flt; - maj_flt += sig->maj_flt; -- thread_group_cputime_adjusted(task, &utime, &stime); - gtime += sig->gtime; - - if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED)) -@@ -551,10 +550,13 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, - - if (permitted && (!whole || num_threads < 2)) - wchan = !task_is_running(task); -- if (!whole) { -+ -+ if (whole) { -+ thread_group_cputime_adjusted(task, &utime, &stime); -+ } else { -+ task_cputime_adjusted(task, &utime, &stime); - min_flt = task->min_flt; - maj_flt = task->maj_flt; -- task_cputime_adjusted(task, &utime, &stime); - gtime = task_gtime(task); - } - -diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c -index 5a132c1e6f6c4..6f4d7aa70e5a2 100644 ---- a/fs/smb/client/cached_dir.c -+++ b/fs/smb/client/cached_dir.c -@@ -268,10 +268,12 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, - if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) - goto oshr_free; - -- smb2_parse_contexts(server, o_rsp, -+ rc = smb2_parse_contexts(server, rsp_iov, - &oparms.fid->epoch, -- oparms.fid->lease_key, &oplock, -- NULL, NULL); -+ oparms.fid->lease_key, -+ &oplock, NULL, NULL); -+ if (rc) -+ goto oshr_free; - if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) - goto oshr_free; - qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 5a157000bdfe6..34d1262004dfb 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -613,7 +613,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, - goto out; - } - -- while (bytes_left >= sizeof(*p)) { -+ while (bytes_left >= (ssize_t)sizeof(*p)) { - memset(&tmp_iface, 0, sizeof(tmp_iface)); - tmp_iface.speed = le64_to_cpu(p->LinkSpeed); - tmp_iface.rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0; -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index e65f998ea4cfc..c1fc1651d8b69 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -2145,17 +2145,18 @@ parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info, - posix->nlink, posix->mode, posix->reparse_tag); - } - --void --smb2_parse_contexts(struct TCP_Server_Info *server, -- struct smb2_create_rsp *rsp, -- unsigned int *epoch, char *lease_key, __u8 *oplock, -- struct smb2_file_all_info *buf, -- struct create_posix_rsp *posix) -+int smb2_parse_contexts(struct TCP_Server_Info *server, -+ struct kvec *rsp_iov, -+ unsigned int *epoch, -+ char *lease_key, __u8 *oplock, -+ struct smb2_file_all_info *buf, -+ struct create_posix_rsp *posix) - { -- char *data_offset; -+ struct smb2_create_rsp *rsp = rsp_iov->iov_base; - struct create_context *cc; -- unsigned int next; -- unsigned int remaining; -+ size_t rem, off, len; -+ size_t doff, dlen; -+ size_t noff, nlen; - char *name; - static const char smb3_create_tag_posix[] = { - 0x93, 0xAD, 0x25, 0x50, 0x9C, -@@ -2164,45 +2165,63 @@ smb2_parse_contexts(struct TCP_Server_Info *server, - }; - - *oplock = 0; -- data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset); -- remaining = le32_to_cpu(rsp->CreateContextsLength); -- cc = (struct create_context *)data_offset; -+ -+ off = le32_to_cpu(rsp->CreateContextsOffset); -+ rem = le32_to_cpu(rsp->CreateContextsLength); -+ if (check_add_overflow(off, rem, &len) || len > rsp_iov->iov_len) -+ return -EINVAL; -+ cc = (struct create_context *)((u8 *)rsp + off); - - /* Initialize inode number to 0 in case no valid data in qfid context */ - if (buf) - buf->IndexNumber = 0; - -- while (remaining >= sizeof(struct create_context)) { -- name = le16_to_cpu(cc->NameOffset) + (char *)cc; -- if (le16_to_cpu(cc->NameLength) == 4 && -- strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0) -- *oplock = server->ops->parse_lease_buf(cc, epoch, -- lease_key); -- else if (buf && (le16_to_cpu(cc->NameLength) == 4) && -- strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0) -- parse_query_id_ctxt(cc, buf); -- else if ((le16_to_cpu(cc->NameLength) == 16)) { -- if (posix && -- memcmp(name, smb3_create_tag_posix, 16) == 0) -+ while (rem >= sizeof(*cc)) { -+ doff = le16_to_cpu(cc->DataOffset); -+ dlen = le32_to_cpu(cc->DataLength); -+ if (check_add_overflow(doff, dlen, &len) || len > rem) -+ return -EINVAL; -+ -+ noff = le16_to_cpu(cc->NameOffset); -+ nlen = le16_to_cpu(cc->NameLength); -+ if (noff + nlen > doff) -+ return -EINVAL; -+ -+ name = (char *)cc + noff; -+ switch (nlen) { -+ case 4: -+ if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) { -+ *oplock = server->ops->parse_lease_buf(cc, epoch, -+ lease_key); -+ } else if (buf && -+ !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) { -+ parse_query_id_ctxt(cc, buf); -+ } -+ break; -+ case 16: -+ if (posix && !memcmp(name, smb3_create_tag_posix, 16)) - parse_posix_ctxt(cc, buf, posix); -+ break; -+ default: -+ cifs_dbg(FYI, "%s: unhandled context (nlen=%zu dlen=%zu)\n", -+ __func__, nlen, dlen); -+ if (IS_ENABLED(CONFIG_CIFS_DEBUG2)) -+ cifs_dump_mem("context data: ", cc, dlen); -+ break; - } -- /* else { -- cifs_dbg(FYI, "Context not matched with len %d\n", -- le16_to_cpu(cc->NameLength)); -- cifs_dump_mem("Cctxt name: ", name, 4); -- } */ -- -- next = le32_to_cpu(cc->Next); -- if (!next) -+ -+ off = le32_to_cpu(cc->Next); -+ if (!off) - break; -- remaining -= next; -- cc = (struct create_context *)((char *)cc + next); -+ if (check_sub_overflow(rem, off, &rem)) -+ return -EINVAL; -+ cc = (struct create_context *)((u8 *)cc + off); - } - - if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) - *oplock = rsp->OplockLevel; - -- return; -+ return 0; - } - - static int -@@ -3082,8 +3101,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, - } - - -- smb2_parse_contexts(server, rsp, &oparms->fid->epoch, -- oparms->fid->lease_key, oplock, buf, posix); -+ rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch, -+ oparms->fid->lease_key, oplock, buf, posix); - creat_exit: - SMB2_open_free(&rqst); - free_rsp_buf(resp_buftype, rsp); -diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h -index be21b5d26f67e..b325fde010adc 100644 ---- a/fs/smb/client/smb2proto.h -+++ b/fs/smb/client/smb2proto.h -@@ -249,11 +249,13 @@ extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); - - extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, - enum securityEnum); --extern void smb2_parse_contexts(struct TCP_Server_Info *server, -- struct smb2_create_rsp *rsp, -- unsigned int *epoch, char *lease_key, -- __u8 *oplock, struct smb2_file_all_info *buf, -- struct create_posix_rsp *posix); -+int smb2_parse_contexts(struct TCP_Server_Info *server, -+ struct kvec *rsp_iov, -+ unsigned int *epoch, -+ char *lease_key, __u8 *oplock, -+ struct smb2_file_all_info *buf, -+ struct create_posix_rsp *posix); -+ - extern int smb3_encryption_required(const struct cifs_tcon *tcon); - extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length, - struct kvec *iov, unsigned int min_buf_size); -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 4cfa45c2727ea..66d25d0e34d8b 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -6171,8 +6171,10 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) - err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, - offsetof(struct smb2_read_rsp, Buffer), - aux_payload_buf, nbytes); -- if (err) -+ if (err) { -+ kvfree(aux_payload_buf); - goto out; -+ } - kvfree(rpc_resp); - } else { - err = ksmbd_iov_pin_rsp(work, (void *)rsp, -@@ -6382,8 +6384,10 @@ int smb2_read(struct ksmbd_work *work) - err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, - offsetof(struct smb2_read_rsp, Buffer), - aux_payload_buf, nbytes); -- if (err) -+ if (err) { -+ kvfree(aux_payload_buf); - goto out; -+ } - ksmbd_fd_put(work, fp); - return 0; - -diff --git a/fs/zonefs/file.c b/fs/zonefs/file.c -index 63cd50840419c..8d5f4a5a74e65 100644 ---- a/fs/zonefs/file.c -+++ b/fs/zonefs/file.c -@@ -349,7 +349,12 @@ static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size, - struct zonefs_inode_info *zi = ZONEFS_I(inode); - - if (error) { -- zonefs_io_error(inode, true); -+ /* -+ * For Sync IOs, error recovery is called from -+ * zonefs_file_dio_write(). -+ */ -+ if (!is_sync_kiocb(iocb)) -+ zonefs_io_error(inode, true); - return error; - } - -@@ -577,6 +582,14 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) - ret = -EINVAL; - goto inode_unlock; - } -+ /* -+ * Advance the zone write pointer offset. This assumes that the -+ * IO will succeed, which is OK to do because we do not allow -+ * partial writes (IOMAP_DIO_PARTIAL is not set) and if the IO -+ * fails, the error path will correct the write pointer offset. -+ */ -+ z->z_wpoffset += count; -+ zonefs_inode_account_active(inode); - mutex_unlock(&zi->i_truncate_mutex); - append = sync; - } -@@ -596,20 +609,19 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) - ret = -EBUSY; - } - -- if (zonefs_zone_is_seq(z) && -- (ret > 0 || ret == -EIOCBQUEUED)) { -- if (ret > 0) -- count = ret; -- -- /* -- * Update the zone write pointer offset assuming the write -- * operation succeeded. If it did not, the error recovery path -- * will correct it. Also do active seq file accounting. -- */ -- mutex_lock(&zi->i_truncate_mutex); -- z->z_wpoffset += count; -- zonefs_inode_account_active(inode); -- mutex_unlock(&zi->i_truncate_mutex); -+ /* -+ * For a failed IO or partial completion, trigger error recovery -+ * to update the zone write pointer offset to a correct value. -+ * For asynchronous IOs, zonefs_file_write_dio_end_io() may already -+ * have executed error recovery if the IO already completed when we -+ * reach here. However, we cannot know that and execute error recovery -+ * again (that will not change anything). -+ */ -+ if (zonefs_zone_is_seq(z)) { -+ if (ret > 0 && ret != count) -+ ret = -EIO; -+ if (ret < 0 && ret != -EIOCBQUEUED) -+ zonefs_io_error(inode, true); - } - - inode_unlock: -diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c -index 270ded209dde5..f6b701261078c 100644 ---- a/fs/zonefs/super.c -+++ b/fs/zonefs/super.c -@@ -245,16 +245,18 @@ static void zonefs_inode_update_mode(struct inode *inode) - z->z_flags &= ~ZONEFS_ZONE_INIT_MODE; - } - --struct zonefs_ioerr_data { -- struct inode *inode; -- bool write; --}; -- - static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, - void *data) - { -- struct zonefs_ioerr_data *err = data; -- struct inode *inode = err->inode; -+ struct blk_zone *z = data; -+ -+ *z = *zone; -+ return 0; -+} -+ -+static void zonefs_handle_io_error(struct inode *inode, struct blk_zone *zone, -+ bool write) -+{ - struct zonefs_zone *z = zonefs_inode_zone(inode); - struct super_block *sb = inode->i_sb; - struct zonefs_sb_info *sbi = ZONEFS_SB(sb); -@@ -269,8 +271,8 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, - data_size = zonefs_check_zone_condition(sb, z, zone); - isize = i_size_read(inode); - if (!(z->z_flags & (ZONEFS_ZONE_READONLY | ZONEFS_ZONE_OFFLINE)) && -- !err->write && isize == data_size) -- return 0; -+ !write && isize == data_size) -+ return; - - /* - * At this point, we detected either a bad zone or an inconsistency -@@ -291,7 +293,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, - * In all cases, warn about inode size inconsistency and handle the - * IO error according to the zone condition and to the mount options. - */ -- if (zonefs_zone_is_seq(z) && isize != data_size) -+ if (isize != data_size) - zonefs_warn(sb, - "inode %lu: invalid size %lld (should be %lld)\n", - inode->i_ino, isize, data_size); -@@ -351,8 +353,6 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, - zonefs_i_size_write(inode, data_size); - z->z_wpoffset = data_size; - zonefs_inode_account_active(inode); -- -- return 0; - } - - /* -@@ -366,23 +366,25 @@ void __zonefs_io_error(struct inode *inode, bool write) - { - struct zonefs_zone *z = zonefs_inode_zone(inode); - struct super_block *sb = inode->i_sb; -- struct zonefs_sb_info *sbi = ZONEFS_SB(sb); - unsigned int noio_flag; -- unsigned int nr_zones = 1; -- struct zonefs_ioerr_data err = { -- .inode = inode, -- .write = write, -- }; -+ struct blk_zone zone; - int ret; - - /* -- * The only files that have more than one zone are conventional zone -- * files with aggregated conventional zones, for which the inode zone -- * size is always larger than the device zone size. -+ * Conventional zone have no write pointer and cannot become read-only -+ * or offline. So simply fake a report for a single or aggregated zone -+ * and let zonefs_handle_io_error() correct the zone inode information -+ * according to the mount options. - */ -- if (z->z_size > bdev_zone_sectors(sb->s_bdev)) -- nr_zones = z->z_size >> -- (sbi->s_zone_sectors_shift + SECTOR_SHIFT); -+ if (!zonefs_zone_is_seq(z)) { -+ zone.start = z->z_sector; -+ zone.len = z->z_size >> SECTOR_SHIFT; -+ zone.wp = zone.start + zone.len; -+ zone.type = BLK_ZONE_TYPE_CONVENTIONAL; -+ zone.cond = BLK_ZONE_COND_NOT_WP; -+ zone.capacity = zone.len; -+ goto handle_io_error; -+ } - - /* - * Memory allocations in blkdev_report_zones() can trigger a memory -@@ -393,12 +395,20 @@ void __zonefs_io_error(struct inode *inode, bool write) - * the GFP_NOIO context avoids both problems. - */ - noio_flag = memalloc_noio_save(); -- ret = blkdev_report_zones(sb->s_bdev, z->z_sector, nr_zones, -- zonefs_io_error_cb, &err); -- if (ret != nr_zones) -+ ret = blkdev_report_zones(sb->s_bdev, z->z_sector, 1, -+ zonefs_io_error_cb, &zone); -+ memalloc_noio_restore(noio_flag); -+ -+ if (ret != 1) { - zonefs_err(sb, "Get inode %lu zone information failed %d\n", - inode->i_ino, ret); -- memalloc_noio_restore(noio_flag); -+ zonefs_warn(sb, "remounting filesystem read-only\n"); -+ sb->s_flags |= SB_RDONLY; -+ return; -+ } -+ -+handle_io_error: -+ zonefs_handle_io_error(inode, &zone, write); - } - - static struct kmem_cache *zonefs_inode_cachep; -diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -index 7ad6f51b3d914..1d1f480a5e9e4 100644 ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -351,7 +351,6 @@ - *(.ref.data) \ - *(.data..shared_aligned) /* percpu related */ \ - MEM_KEEP(init.data*) \ -- MEM_KEEP(exit.data*) \ - *(.data.unlikely) \ - __start_once = .; \ - *(.data.once) \ -@@ -546,7 +545,6 @@ - __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ - *(.ref.rodata) \ - MEM_KEEP(init.rodata) \ -- MEM_KEEP(exit.rodata) \ - } \ - \ - /* Built-in module parameters. */ \ -@@ -601,7 +599,6 @@ - *(.ref.text) \ - *(.text.asan.* .text.tsan.*) \ - MEM_KEEP(init.text*) \ -- MEM_KEEP(exit.text*) \ - - - /* sched.text is aling to function alignment to secure we have same -@@ -751,13 +748,10 @@ - *(.exit.data .exit.data.*) \ - *(.fini_array .fini_array.*) \ - *(.dtors .dtors.*) \ -- MEM_DISCARD(exit.data*) \ -- MEM_DISCARD(exit.rodata*) - - #define EXIT_TEXT \ - *(.exit.text) \ - *(.text.exit) \ -- MEM_DISCARD(exit.text) - - #define EXIT_CALL \ - *(.exitcall.exit) -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index c04a61ffac8ae..1ca1902af23e9 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -2739,10 +2739,18 @@ struct btf_id_set; - bool btf_id_set_contains(const struct btf_id_set *set, u32 id); - - #define MAX_BPRINTF_VARARGS 12 -+#define MAX_BPRINTF_BUF 1024 -+ -+struct bpf_bprintf_data { -+ u32 *bin_args; -+ char *buf; -+ bool get_bin_args; -+ bool get_buf; -+}; - - int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, -- u32 **bin_buf, u32 num_args); --void bpf_bprintf_cleanup(void); -+ u32 num_args, struct bpf_bprintf_data *data); -+void bpf_bprintf_cleanup(struct bpf_bprintf_data *data); - - /* the implementation of the opaque uapi struct bpf_dynptr */ - struct bpf_dynptr_kern { -diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h -new file mode 100644 -index 0000000000000..53f1a7a932b08 ---- /dev/null -+++ b/include/linux/cleanup.h -@@ -0,0 +1,171 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __LINUX_GUARDS_H -+#define __LINUX_GUARDS_H -+ -+#include -+ -+/* -+ * DEFINE_FREE(name, type, free): -+ * simple helper macro that defines the required wrapper for a __free() -+ * based cleanup function. @free is an expression using '_T' to access -+ * the variable. -+ * -+ * __free(name): -+ * variable attribute to add a scoped based cleanup to the variable. -+ * -+ * no_free_ptr(var): -+ * like a non-atomic xchg(var, NULL), such that the cleanup function will -+ * be inhibited -- provided it sanely deals with a NULL value. -+ * -+ * return_ptr(p): -+ * returns p while inhibiting the __free(). -+ * -+ * Ex. -+ * -+ * DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) -+ * -+ * struct obj *p __free(kfree) = kmalloc(...); -+ * if (!p) -+ * return NULL; -+ * -+ * if (!init_obj(p)) -+ * return NULL; -+ * -+ * return_ptr(p); -+ */ -+ -+#define DEFINE_FREE(_name, _type, _free) \ -+ static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; } -+ -+#define __free(_name) __cleanup(__free_##_name) -+ -+#define no_free_ptr(p) \ -+ ({ __auto_type __ptr = (p); (p) = NULL; __ptr; }) -+ -+#define return_ptr(p) return no_free_ptr(p) -+ -+ -+/* -+ * DEFINE_CLASS(name, type, exit, init, init_args...): -+ * helper to define the destructor and constructor for a type. -+ * @exit is an expression using '_T' -- similar to FREE above. -+ * @init is an expression in @init_args resulting in @type -+ * -+ * EXTEND_CLASS(name, ext, init, init_args...): -+ * extends class @name to @name@ext with the new constructor -+ * -+ * CLASS(name, var)(args...): -+ * declare the variable @var as an instance of the named class -+ * -+ * Ex. -+ * -+ * DEFINE_CLASS(fdget, struct fd, fdput(_T), fdget(fd), int fd) -+ * -+ * CLASS(fdget, f)(fd); -+ * if (!f.file) -+ * return -EBADF; -+ * -+ * // use 'f' without concern -+ */ -+ -+#define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...) \ -+typedef _type class_##_name##_t; \ -+static inline void class_##_name##_destructor(_type *p) \ -+{ _type _T = *p; _exit; } \ -+static inline _type class_##_name##_constructor(_init_args) \ -+{ _type t = _init; return t; } -+ -+#define EXTEND_CLASS(_name, ext, _init, _init_args...) \ -+typedef class_##_name##_t class_##_name##ext##_t; \ -+static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\ -+{ class_##_name##_destructor(p); } \ -+static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ -+{ class_##_name##_t t = _init; return t; } -+ -+#define CLASS(_name, var) \ -+ class_##_name##_t var __cleanup(class_##_name##_destructor) = \ -+ class_##_name##_constructor -+ -+ -+/* -+ * DEFINE_GUARD(name, type, lock, unlock): -+ * trivial wrapper around DEFINE_CLASS() above specifically -+ * for locks. -+ * -+ * guard(name): -+ * an anonymous instance of the (guard) class -+ * -+ * scoped_guard (name, args...) { }: -+ * similar to CLASS(name, scope)(args), except the variable (with the -+ * explicit name 'scope') is declard in a for-loop such that its scope is -+ * bound to the next (compound) statement. -+ * -+ */ -+ -+#define DEFINE_GUARD(_name, _type, _lock, _unlock) \ -+ DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T) -+ -+#define guard(_name) \ -+ CLASS(_name, __UNIQUE_ID(guard)) -+ -+#define scoped_guard(_name, args...) \ -+ for (CLASS(_name, scope)(args), \ -+ *done = NULL; !done; done = (void *)1) -+ -+/* -+ * Additional helper macros for generating lock guards with types, either for -+ * locks that don't have a native type (eg. RCU, preempt) or those that need a -+ * 'fat' pointer (eg. spin_lock_irqsave). -+ * -+ * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...) -+ * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...) -+ * -+ * will result in the following type: -+ * -+ * typedef struct { -+ * type *lock; // 'type := void' for the _0 variant -+ * __VA_ARGS__; -+ * } class_##name##_t; -+ * -+ * As above, both _lock and _unlock are statements, except this time '_T' will -+ * be a pointer to the above struct. -+ */ -+ -+#define __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, ...) \ -+typedef struct { \ -+ _type *lock; \ -+ __VA_ARGS__; \ -+} class_##_name##_t; \ -+ \ -+static inline void class_##_name##_destructor(class_##_name##_t *_T) \ -+{ \ -+ if (_T->lock) { _unlock; } \ -+} -+ -+ -+#define __DEFINE_LOCK_GUARD_1(_name, _type, _lock) \ -+static inline class_##_name##_t class_##_name##_constructor(_type *l) \ -+{ \ -+ class_##_name##_t _t = { .lock = l }, *_T = &_t; \ -+ _lock; \ -+ return _t; \ -+} -+ -+#define __DEFINE_LOCK_GUARD_0(_name, _lock) \ -+static inline class_##_name##_t class_##_name##_constructor(void) \ -+{ \ -+ class_##_name##_t _t = { .lock = (void*)1 }, \ -+ *_T __maybe_unused = &_t; \ -+ _lock; \ -+ return _t; \ -+} -+ -+#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ -+__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ -+__DEFINE_LOCK_GUARD_1(_name, _type, _lock) -+ -+#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ -+__DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ -+__DEFINE_LOCK_GUARD_0(_name, _lock) -+ -+#endif /* __LINUX_GUARDS_H */ -diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h -index 6cfd6902bd5b9..9b673fefcef8a 100644 ---- a/include/linux/compiler-clang.h -+++ b/include/linux/compiler-clang.h -@@ -5,6 +5,15 @@ - - /* Compiler specific definitions for Clang compiler */ - -+/* -+ * Clang prior to 17 is being silly and considers many __cleanup() variables -+ * as unused (because they are, their sole purpose is to go out of scope). -+ * -+ * https://reviews.llvm.org/D152180 -+ */ -+#undef __cleanup -+#define __cleanup(func) __maybe_unused __attribute__((__cleanup__(func))) -+ - /* same as gcc, this was present in clang-2.6 so we can assume it works - * with any version that can compile the kernel - */ -diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h -index f55a37efdb974..149a520515e1d 100644 ---- a/include/linux/compiler-gcc.h -+++ b/include/linux/compiler-gcc.h -@@ -66,6 +66,26 @@ - __builtin_unreachable(); \ - } while (0) - -+/* -+ * GCC 'asm goto' with outputs miscompiles certain code sequences: -+ * -+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921 -+ * -+ * Work around it via the same compiler barrier quirk that we used -+ * to use for the old 'asm goto' workaround. -+ * -+ * Also, always mark such 'asm goto' statements as volatile: all -+ * asm goto statements are supposed to be volatile as per the -+ * documentation, but some versions of gcc didn't actually do -+ * that for asms with outputs: -+ * -+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98619 -+ */ -+#ifdef CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND -+#define asm_goto_output(x...) \ -+ do { asm volatile goto(x); asm (""); } while (0) -+#endif -+ - #if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) - #define __HAVE_BUILTIN_BSWAP32__ - #define __HAVE_BUILTIN_BSWAP64__ -diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h -index 898b3458b24a0..ae4c9579ca5f0 100644 ---- a/include/linux/compiler_attributes.h -+++ b/include/linux/compiler_attributes.h -@@ -75,6 +75,12 @@ - # define __assume_aligned(a, ...) - #endif - -+/* -+ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute -+ * clang: https://clang.llvm.org/docs/AttributeReference.html#cleanup -+ */ -+#define __cleanup(func) __attribute__((__cleanup__(func))) -+ - /* - * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute - * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute -diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h -index eb0466236661f..574b4121ebe3e 100644 ---- a/include/linux/compiler_types.h -+++ b/include/linux/compiler_types.h -@@ -284,8 +284,15 @@ struct ftrace_likely_data { - # define __realloc_size(x, ...) - #endif - --#ifndef asm_volatile_goto --#define asm_volatile_goto(x...) asm goto(x) -+/* -+ * Some versions of gcc do not mark 'asm goto' volatile: -+ * -+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103979 -+ * -+ * We do it here by hand, because it doesn't hurt. -+ */ -+#ifndef asm_goto_output -+#define asm_goto_output(x...) asm volatile goto(x) - #endif - - #ifdef CONFIG_CC_HAS_ASM_INLINE -diff --git a/include/linux/device.h b/include/linux/device.h -index 7cf24330d6814..5520bb546a4ac 100644 ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - - struct device; -@@ -898,6 +899,9 @@ void device_unregister(struct device *dev); - void device_initialize(struct device *dev); - int __must_check device_add(struct device *dev); - void device_del(struct device *dev); -+ -+DEFINE_FREE(device_del, struct device *, if (_T) device_del(_T)) -+ - int device_for_each_child(struct device *dev, void *data, - int (*fn)(struct device *dev, void *data)); - int device_for_each_child_reverse(struct device *dev, void *data, -@@ -1071,6 +1075,9 @@ extern int (*platform_notify_remove)(struct device *dev); - */ - struct device *get_device(struct device *dev); - void put_device(struct device *dev); -+ -+DEFINE_FREE(put_device, struct device *, if (_T) put_device(_T)) -+ - bool kill_device(struct device *dev); - - #ifdef CONFIG_DEVTMPFS -diff --git a/include/linux/file.h b/include/linux/file.h -index 39704eae83e27..6e9099d293436 100644 ---- a/include/linux/file.h -+++ b/include/linux/file.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - struct file; - -@@ -80,6 +81,8 @@ static inline void fdput_pos(struct fd f) - fdput(f); - } - -+DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd) -+ - extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); - extern int replace_fd(unsigned fd, struct file *file, unsigned flags); - extern void set_close_on_exec(unsigned int fd, int flag); -@@ -88,6 +91,9 @@ extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile); - extern int get_unused_fd_flags(unsigned flags); - extern void put_unused_fd(unsigned int fd); - -+DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T), -+ get_unused_fd_flags(flags), unsigned flags) -+ - extern void fd_install(unsigned int fd, struct file *file); - - extern int __receive_fd(struct file *file, int __user *ufd, -diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h -index 7852f6c9a714c..719cf9cc6e1ac 100644 ---- a/include/linux/iio/adc/ad_sigma_delta.h -+++ b/include/linux/iio/adc/ad_sigma_delta.h -@@ -8,6 +8,8 @@ - #ifndef __AD_SIGMA_DELTA_H__ - #define __AD_SIGMA_DELTA_H__ - -+#include -+ - enum ad_sigma_delta_mode { - AD_SD_MODE_CONTINUOUS = 0, - AD_SD_MODE_SINGLE = 1, -@@ -99,7 +101,7 @@ struct ad_sigma_delta { - * 'rx_buf' is up to 32 bits per sample + 64 bit timestamp, - * rounded to 16 bytes to take into account padding. - */ -- uint8_t tx_buf[4] ____cacheline_aligned; -+ uint8_t tx_buf[4] __aligned(IIO_DMA_MINALIGN); - uint8_t rx_buf[16] __aligned(8); - }; - -diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h -index db4a1b260348c..c34e648f07e28 100644 ---- a/include/linux/iio/common/st_sensors.h -+++ b/include/linux/iio/common/st_sensors.h -@@ -261,9 +261,9 @@ struct st_sensor_data { - bool hw_irq_trigger; - s64 hw_timestamp; - -- char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE] ____cacheline_aligned; -- - struct mutex odr_lock; -+ -+ char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE] __aligned(IIO_DMA_MINALIGN); - }; - - #ifdef CONFIG_IIO_BUFFER -diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h -index bcbefb7574751..af083aa0c4317 100644 ---- a/include/linux/iio/imu/adis.h -+++ b/include/linux/iio/imu/adis.h -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - - #define ADIS_WRITE_REG(reg) ((0x80 | (reg))) -@@ -131,7 +132,7 @@ struct adis { - unsigned long irq_flag; - void *buffer; - -- u8 tx[10] ____cacheline_aligned; -+ u8 tx[10] __aligned(IIO_DMA_MINALIGN); - u8 rx[4]; - }; - -diff --git a/include/linux/init.h b/include/linux/init.h -index 077d7f93b402f..c96aea3229ca1 100644 ---- a/include/linux/init.h -+++ b/include/linux/init.h -@@ -87,9 +87,6 @@ - __latent_entropy - #define __meminitdata __section(".meminit.data") - #define __meminitconst __section(".meminit.rodata") --#define __memexit __section(".memexit.text") __exitused __cold notrace --#define __memexitdata __section(".memexit.data") --#define __memexitconst __section(".memexit.rodata") - - /* For assembly routines */ - #define __HEAD .section ".head.text","ax" -diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h -index 5ec0fa71399e4..2b665c32f5fe6 100644 ---- a/include/linux/irqflags.h -+++ b/include/linux/irqflags.h -@@ -13,6 +13,7 @@ - #define _LINUX_TRACE_IRQFLAGS_H - - #include -+#include - #include - #include - -@@ -267,4 +268,10 @@ extern void warn_bogus_irq_restore(void); - - #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) - -+DEFINE_LOCK_GUARD_0(irq, local_irq_disable(), local_irq_enable()) -+DEFINE_LOCK_GUARD_0(irqsave, -+ local_irq_save(_T->flags), -+ local_irq_restore(_T->flags), -+ unsigned long flags) -+ - #endif -diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h -index 74f9d9a6d3307..0e4ef9c5127ad 100644 ---- a/include/linux/mmc/sdio_ids.h -+++ b/include/linux/mmc/sdio_ids.h -@@ -102,6 +102,7 @@ - #define SDIO_DEVICE_ID_MARVELL_8977_BT 0x9146 - #define SDIO_DEVICE_ID_MARVELL_8987_WLAN 0x9149 - #define SDIO_DEVICE_ID_MARVELL_8987_BT 0x914a -+#define SDIO_DEVICE_ID_MARVELL_8978_WLAN 0x9159 - - #define SDIO_VENDOR_ID_MEDIATEK 0x037a - #define SDIO_DEVICE_ID_MEDIATEK_MT7663 0x7663 -diff --git a/include/linux/mutex.h b/include/linux/mutex.h -index 8f226d460f51c..a33aa9eb9fc3b 100644 ---- a/include/linux/mutex.h -+++ b/include/linux/mutex.h -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_DEBUG_LOCK_ALLOC - # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ -@@ -219,4 +220,7 @@ extern void mutex_unlock(struct mutex *lock); - - extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); - -+DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) -+DEFINE_FREE(mutex, struct mutex *, if (_T) mutex_unlock(_T)) -+ - #endif /* __LINUX_MUTEX_H */ -diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h -index 72f5ebc5c97a9..0b217d4ae2a48 100644 ---- a/include/linux/netfilter/ipset/ip_set.h -+++ b/include/linux/netfilter/ipset/ip_set.h -@@ -186,6 +186,8 @@ struct ip_set_type_variant { - /* Return true if "b" set is the same as "a" - * according to the create set parameters */ - bool (*same_set)(const struct ip_set *a, const struct ip_set *b); -+ /* Cancel ongoing garbage collectors before destroying the set*/ -+ void (*cancel_gc)(struct ip_set *set); - /* Region-locking is used */ - bool region_lock; - }; -@@ -242,6 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type); - - /* A generic IP set */ - struct ip_set { -+ /* For call_cru in destroy */ -+ struct rcu_head rcu; - /* The name of the set */ - char name[IPSET_MAXNAMELEN]; - /* Lock protecting the set data */ -diff --git a/include/linux/percpu.h b/include/linux/percpu.h -index f1ec5ad1351cc..ba00a49369cae 100644 ---- a/include/linux/percpu.h -+++ b/include/linux/percpu.h -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include - -@@ -128,6 +129,9 @@ extern void __init setup_per_cpu_areas(void); - extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1); - extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1); - extern void free_percpu(void __percpu *__pdata); -+ -+DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T)) -+ - extern phys_addr_t per_cpu_ptr_to_phys(void *addr); - - #define alloc_percpu_gfp(type, gfp) \ -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 8cfcc5d454512..9aa6358a1a16b 100644 ---- a/include/linux/preempt.h -+++ b/include/linux/preempt.h -@@ -8,6 +8,7 @@ - */ - - #include -+#include - #include - - /* -@@ -474,4 +475,8 @@ static __always_inline void preempt_enable_nested(void) - preempt_enable(); - } - -+DEFINE_LOCK_GUARD_0(preempt, preempt_disable(), preempt_enable()) -+DEFINE_LOCK_GUARD_0(preempt_notrace, preempt_disable_notrace(), preempt_enable_notrace()) -+DEFINE_LOCK_GUARD_0(migrate, migrate_disable(), migrate_enable()) -+ - #endif /* __LINUX_PREEMPT_H */ -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index 46bd9a331fd5d..d2507168b9c7b 100644 ---- a/include/linux/rcupdate.h -+++ b/include/linux/rcupdate.h -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1077,4 +1078,6 @@ rcu_head_after_call_rcu(struct rcu_head *rhp, rcu_callback_t f) - extern int rcu_expedited; - extern int rcu_normal; - -+DEFINE_LOCK_GUARD_0(rcu, rcu_read_lock(), rcu_read_unlock()) -+ - #endif /* __LINUX_RCUPDATE_H */ -diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h -index efa5c324369a2..1dd530ce8b45b 100644 ---- a/include/linux/rwsem.h -+++ b/include/linux/rwsem.h -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_DEBUG_LOCK_ALLOC - # define __RWSEM_DEP_MAP_INIT(lockname) \ -@@ -201,6 +202,13 @@ extern void up_read(struct rw_semaphore *sem); - */ - extern void up_write(struct rw_semaphore *sem); - -+DEFINE_GUARD(rwsem_read, struct rw_semaphore *, down_read(_T), up_read(_T)) -+DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) -+ -+DEFINE_FREE(up_read, struct rw_semaphore *, if (_T) up_read(_T)) -+DEFINE_FREE(up_write, struct rw_semaphore *, if (_T) up_write(_T)) -+ -+ - /* - * downgrade write lock to read lock - */ -diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index 7291fb6399d2a..aaa25ed1a8fe0 100644 ---- a/include/linux/sched/task.h -+++ b/include/linux/sched/task.h -@@ -145,6 +145,8 @@ static inline void put_task_struct(struct task_struct *t) - __put_task_struct(t); - } - -+DEFINE_FREE(put_task, struct task_struct *, if (_T) put_task_struct(_T)) -+ - static inline void put_task_struct_many(struct task_struct *t, int nr) - { - if (refcount_sub_and_test(nr, &t->usage)) -diff --git a/include/linux/slab.h b/include/linux/slab.h -index 45efc6c553b82..cb4b5deca9a9c 100644 ---- a/include/linux/slab.h -+++ b/include/linux/slab.h -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - - /* -@@ -197,6 +198,8 @@ void kfree(const void *objp); - void kfree_sensitive(const void *objp); - size_t __ksize(const void *objp); - -+DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) -+ - /** - * ksize - Report actual allocation size of associated object - * -diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h -index 1341f7d62da44..83377540c369a 100644 ---- a/include/linux/spinlock.h -+++ b/include/linux/spinlock.h -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -493,5 +494,35 @@ int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, - - void free_bucket_spinlocks(spinlock_t *locks); - -+DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, -+ raw_spin_lock(_T->lock), -+ raw_spin_unlock(_T->lock)) -+ -+DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, -+ raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), -+ raw_spin_unlock(_T->lock)) -+ -+DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, -+ raw_spin_lock_irq(_T->lock), -+ raw_spin_unlock_irq(_T->lock)) -+ -+DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, -+ raw_spin_lock_irqsave(_T->lock, _T->flags), -+ raw_spin_unlock_irqrestore(_T->lock, _T->flags), -+ unsigned long flags) -+ -+DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, -+ spin_lock(_T->lock), -+ spin_unlock(_T->lock)) -+ -+DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, -+ spin_lock_irq(_T->lock), -+ spin_unlock_irq(_T->lock)) -+ -+DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, -+ spin_lock_irqsave(_T->lock, _T->flags), -+ spin_unlock_irqrestore(_T->lock, _T->flags), -+ unsigned long flags) -+ - #undef __LINUX_INSIDE_SPINLOCK_H - #endif /* __LINUX_SPINLOCK_H */ -diff --git a/include/linux/srcu.h b/include/linux/srcu.h -index 01226e4d960a0..f9e1fa7ff86fc 100644 ---- a/include/linux/srcu.h -+++ b/include/linux/srcu.h -@@ -212,4 +212,9 @@ static inline void smp_mb__after_srcu_read_unlock(void) - /* __srcu_read_unlock has smp_mb() internally so nothing to do here. */ - } - -+DEFINE_LOCK_GUARD_1(srcu, struct srcu_struct, -+ _T->idx = srcu_read_lock(_T->lock), -+ srcu_read_unlock(_T->lock, _T->idx), -+ int idx) -+ - #endif -diff --git a/include/net/tls.h b/include/net/tls.h -index c36bf4c50027e..899c863aba02c 100644 ---- a/include/net/tls.h -+++ b/include/net/tls.h -@@ -108,9 +108,6 @@ struct tls_sw_context_tx { - struct tls_rec *open_rec; - struct list_head tx_list; - atomic_t encrypt_pending; -- /* protect crypto_wait with encrypt_pending */ -- spinlock_t encrypt_compl_lock; -- int async_notify; - u8 async_capable:1; - - #define BIT_TX_SCHEDULED 0 -@@ -147,8 +144,6 @@ struct tls_sw_context_rx { - struct tls_strparser strp; - - atomic_t decrypt_pending; -- /* protect crypto_wait with decrypt_pending*/ -- spinlock_t decrypt_compl_lock; - struct sk_buff_head async_hold; - struct wait_queue_head wq; - }; -diff --git a/init/Kconfig b/init/Kconfig -index 148704640252e..ffb927bf6034f 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -89,6 +89,15 @@ config CC_HAS_ASM_GOTO_TIED_OUTPUT - # Detect buggy gcc and clang, fixed in gcc-11 clang-14. - def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null) - -+config GCC_ASM_GOTO_OUTPUT_WORKAROUND -+ bool -+ depends on CC_IS_GCC && CC_HAS_ASM_GOTO_OUTPUT -+ # Fixed in GCC 14, 13.3, 12.4 and 11.5 -+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921 -+ default y if GCC_VERSION < 110500 -+ default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400 -+ default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300 -+ - config TOOLS_SUPPORT_RELR - def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh) - -diff --git a/io_uring/net.c b/io_uring/net.c -index 618ab186fe036..c062ce66af12c 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -1326,7 +1326,7 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags) - * has already been done - */ - if (issue_flags & IO_URING_F_MULTISHOT) -- ret = IOU_ISSUE_SKIP_COMPLETE; -+ return IOU_ISSUE_SKIP_COMPLETE; - return ret; - } - if (ret == -ERESTARTSYS) -@@ -1350,7 +1350,8 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags) - if (io_post_aux_cqe(ctx, req->cqe.user_data, ret, IORING_CQE_F_MORE, false)) - goto retry; - -- return -ECANCELED; -+ io_req_set_res(req, ret, 0); -+ return IOU_STOP_MULTISHOT; - } - - int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) -diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c -index 34135fbd6097e..6a61a98d602cd 100644 ---- a/kernel/bpf/helpers.c -+++ b/kernel/bpf/helpers.c -@@ -753,19 +753,20 @@ static int bpf_trace_copy_string(char *buf, void *unsafe_ptr, char fmt_ptype, - /* Per-cpu temp buffers used by printf-like helpers to store the bprintf binary - * arguments representation. - */ --#define MAX_BPRINTF_BUF_LEN 512 -+#define MAX_BPRINTF_BIN_ARGS 512 - - /* Support executing three nested bprintf helper calls on a given CPU */ - #define MAX_BPRINTF_NEST_LEVEL 3 - struct bpf_bprintf_buffers { -- char tmp_bufs[MAX_BPRINTF_NEST_LEVEL][MAX_BPRINTF_BUF_LEN]; -+ char bin_args[MAX_BPRINTF_BIN_ARGS]; -+ char buf[MAX_BPRINTF_BUF]; - }; --static DEFINE_PER_CPU(struct bpf_bprintf_buffers, bpf_bprintf_bufs); -+ -+static DEFINE_PER_CPU(struct bpf_bprintf_buffers[MAX_BPRINTF_NEST_LEVEL], bpf_bprintf_bufs); - static DEFINE_PER_CPU(int, bpf_bprintf_nest_level); - --static int try_get_fmt_tmp_buf(char **tmp_buf) -+static int try_get_buffers(struct bpf_bprintf_buffers **bufs) - { -- struct bpf_bprintf_buffers *bufs; - int nest_level; - - preempt_disable(); -@@ -775,18 +776,19 @@ static int try_get_fmt_tmp_buf(char **tmp_buf) - preempt_enable(); - return -EBUSY; - } -- bufs = this_cpu_ptr(&bpf_bprintf_bufs); -- *tmp_buf = bufs->tmp_bufs[nest_level - 1]; -+ *bufs = this_cpu_ptr(&bpf_bprintf_bufs[nest_level - 1]); - - return 0; - } - --void bpf_bprintf_cleanup(void) -+void bpf_bprintf_cleanup(struct bpf_bprintf_data *data) - { -- if (this_cpu_read(bpf_bprintf_nest_level)) { -- this_cpu_dec(bpf_bprintf_nest_level); -- preempt_enable(); -- } -+ if (!data->bin_args && !data->buf) -+ return; -+ if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0)) -+ return; -+ this_cpu_dec(bpf_bprintf_nest_level); -+ preempt_enable(); - } - - /* -@@ -795,18 +797,20 @@ void bpf_bprintf_cleanup(void) - * Returns a negative value if fmt is an invalid format string or 0 otherwise. - * - * This can be used in two ways: -- * - Format string verification only: when bin_args is NULL -+ * - Format string verification only: when data->get_bin_args is false - * - Arguments preparation: in addition to the above verification, it writes in -- * bin_args a binary representation of arguments usable by bstr_printf where -- * pointers from BPF have been sanitized. -+ * data->bin_args a binary representation of arguments usable by bstr_printf -+ * where pointers from BPF have been sanitized. - * - * In argument preparation mode, if 0 is returned, safe temporary buffers are - * allocated and bpf_bprintf_cleanup should be called to free them after use. - */ - int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, -- u32 **bin_args, u32 num_args) -+ u32 num_args, struct bpf_bprintf_data *data) - { -+ bool get_buffers = (data->get_bin_args && num_args) || data->get_buf; - char *unsafe_ptr = NULL, *tmp_buf = NULL, *tmp_buf_end, *fmt_end; -+ struct bpf_bprintf_buffers *buffers = NULL; - size_t sizeof_cur_arg, sizeof_cur_ip; - int err, i, num_spec = 0; - u64 cur_arg; -@@ -817,14 +821,19 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, - return -EINVAL; - fmt_size = fmt_end - fmt; - -- if (bin_args) { -- if (num_args && try_get_fmt_tmp_buf(&tmp_buf)) -- return -EBUSY; -+ if (get_buffers && try_get_buffers(&buffers)) -+ return -EBUSY; - -- tmp_buf_end = tmp_buf + MAX_BPRINTF_BUF_LEN; -- *bin_args = (u32 *)tmp_buf; -+ if (data->get_bin_args) { -+ if (num_args) -+ tmp_buf = buffers->bin_args; -+ tmp_buf_end = tmp_buf + MAX_BPRINTF_BIN_ARGS; -+ data->bin_args = (u32 *)tmp_buf; - } - -+ if (data->get_buf) -+ data->buf = buffers->buf; -+ - for (i = 0; i < fmt_size; i++) { - if ((!isprint(fmt[i]) && !isspace(fmt[i])) || !isascii(fmt[i])) { - err = -EINVAL; -@@ -1018,31 +1027,33 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, - err = 0; - out: - if (err) -- bpf_bprintf_cleanup(); -+ bpf_bprintf_cleanup(data); - return err; - } - - BPF_CALL_5(bpf_snprintf, char *, str, u32, str_size, char *, fmt, -- const void *, data, u32, data_len) -+ const void *, args, u32, data_len) - { -+ struct bpf_bprintf_data data = { -+ .get_bin_args = true, -+ }; - int err, num_args; -- u32 *bin_args; - - if (data_len % 8 || data_len > MAX_BPRINTF_VARARGS * 8 || -- (data_len && !data)) -+ (data_len && !args)) - return -EINVAL; - num_args = data_len / 8; - - /* ARG_PTR_TO_CONST_STR guarantees that fmt is zero-terminated so we - * can safely give an unbounded size. - */ -- err = bpf_bprintf_prepare(fmt, UINT_MAX, data, &bin_args, num_args); -+ err = bpf_bprintf_prepare(fmt, UINT_MAX, args, num_args, &data); - if (err < 0) - return err; - -- err = bstr_printf(str, str_size, fmt, bin_args); -+ err = bstr_printf(str, str_size, fmt, data.bin_args); - -- bpf_bprintf_cleanup(); -+ bpf_bprintf_cleanup(&data); - - return err + 1; - } -diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c -index 23b6d57b5eef2..1a29ac4db6eae 100644 ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -7448,6 +7448,7 @@ static int check_bpf_snprintf_call(struct bpf_verifier_env *env, - struct bpf_reg_state *fmt_reg = ®s[BPF_REG_3]; - struct bpf_reg_state *data_len_reg = ®s[BPF_REG_5]; - struct bpf_map *fmt_map = fmt_reg->map_ptr; -+ struct bpf_bprintf_data data = {}; - int err, fmt_map_off, num_args; - u64 fmt_addr; - char *fmt; -@@ -7472,7 +7473,7 @@ static int check_bpf_snprintf_call(struct bpf_verifier_env *env, - /* We are also guaranteed that fmt+fmt_map_off is NULL terminated, we - * can focus on validating the format specifiers. - */ -- err = bpf_bprintf_prepare(fmt, UINT_MAX, NULL, NULL, num_args); -+ err = bpf_bprintf_prepare(fmt, UINT_MAX, NULL, num_args, &data); - if (err < 0) - verbose(env, "Invalid format string\n"); - -diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c -index 0c5be7ebb1dca..08b16d20c85bb 100644 ---- a/kernel/sched/membarrier.c -+++ b/kernel/sched/membarrier.c -@@ -161,6 +161,9 @@ - | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \ - | MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK) - -+static DEFINE_MUTEX(membarrier_ipi_mutex); -+#define SERIALIZE_IPI() guard(mutex)(&membarrier_ipi_mutex) -+ - static void ipi_mb(void *info) - { - smp_mb(); /* IPIs should be serializing but paranoid. */ -@@ -258,6 +261,7 @@ static int membarrier_global_expedited(void) - if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) - return -ENOMEM; - -+ SERIALIZE_IPI(); - cpus_read_lock(); - rcu_read_lock(); - for_each_online_cpu(cpu) { -@@ -346,6 +350,7 @@ static int membarrier_private_expedited(int flags, int cpu_id) - if (cpu_id < 0 && !zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) - return -ENOMEM; - -+ SERIALIZE_IPI(); - cpus_read_lock(); - - if (cpu_id >= 0) { -@@ -459,6 +464,7 @@ static int sync_runqueues_membarrier_state(struct mm_struct *mm) - * between threads which are users of @mm has its membarrier state - * updated. - */ -+ SERIALIZE_IPI(); - cpus_read_lock(); - rcu_read_lock(); - for_each_online_cpu(cpu) { -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index 8e0aff1d1ea4f..9bb88836c42e6 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -2266,7 +2266,7 @@ void __init hrtimers_init(void) - /** - * schedule_hrtimeout_range_clock - sleep until timeout - * @expires: timeout value (ktime_t) -- * @delta: slack in expires timeout (ktime_t) -+ * @delta: slack in expires timeout (ktime_t) for SCHED_OTHER tasks - * @mode: timer mode - * @clock_id: timer clock to be used - */ -@@ -2293,6 +2293,13 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, - return -EINTR; - } - -+ /* -+ * Override any slack passed by the user if under -+ * rt contraints. -+ */ -+ if (rt_task(current)) -+ delta = 0; -+ - hrtimer_init_sleeper_on_stack(&t, clock_id, mode); - hrtimer_set_expires_range_ns(&t.timer, *expires, delta); - hrtimer_sleeper_start_expires(&t, mode); -@@ -2312,7 +2319,7 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock); - /** - * schedule_hrtimeout_range - sleep until timeout - * @expires: timeout value (ktime_t) -- * @delta: slack in expires timeout (ktime_t) -+ * @delta: slack in expires timeout (ktime_t) for SCHED_OTHER tasks - * @mode: timer mode - * - * Make the current task sleep until the given expiry time has -@@ -2320,7 +2327,8 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock); - * the current task state has been set (see set_current_state()). - * - * The @delta argument gives the kernel the freedom to schedule the -- * actual wakeup to a time that is both power and performance friendly. -+ * actual wakeup to a time that is both power and performance friendly -+ * for regular (non RT/DL) tasks. - * The kernel give the normal best effort behavior for "@expires+@delta", - * but may decide to fire the timer earlier, but no earlier than @expires. - * -diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c -index f4a494a457c52..3fdde232eaa92 100644 ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -368,8 +368,6 @@ static const struct bpf_func_proto *bpf_get_probe_write_proto(void) - return &bpf_probe_write_user_proto; - } - --static DEFINE_RAW_SPINLOCK(trace_printk_lock); -- - #define MAX_TRACE_PRINTK_VARARGS 3 - #define BPF_TRACE_PRINTK_SIZE 1024 - -@@ -377,23 +375,22 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, - u64, arg2, u64, arg3) - { - u64 args[MAX_TRACE_PRINTK_VARARGS] = { arg1, arg2, arg3 }; -- u32 *bin_args; -- static char buf[BPF_TRACE_PRINTK_SIZE]; -- unsigned long flags; -+ struct bpf_bprintf_data data = { -+ .get_bin_args = true, -+ .get_buf = true, -+ }; - int ret; - -- ret = bpf_bprintf_prepare(fmt, fmt_size, args, &bin_args, -- MAX_TRACE_PRINTK_VARARGS); -+ ret = bpf_bprintf_prepare(fmt, fmt_size, args, -+ MAX_TRACE_PRINTK_VARARGS, &data); - if (ret < 0) - return ret; - -- raw_spin_lock_irqsave(&trace_printk_lock, flags); -- ret = bstr_printf(buf, sizeof(buf), fmt, bin_args); -+ ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args); - -- trace_bpf_trace_printk(buf); -- raw_spin_unlock_irqrestore(&trace_printk_lock, flags); -+ trace_bpf_trace_printk(data.buf); - -- bpf_bprintf_cleanup(); -+ bpf_bprintf_cleanup(&data); - - return ret; - } -@@ -426,30 +423,29 @@ const struct bpf_func_proto *bpf_get_trace_printk_proto(void) - return &bpf_trace_printk_proto; - } - --BPF_CALL_4(bpf_trace_vprintk, char *, fmt, u32, fmt_size, const void *, data, -+BPF_CALL_4(bpf_trace_vprintk, char *, fmt, u32, fmt_size, const void *, args, - u32, data_len) - { -- static char buf[BPF_TRACE_PRINTK_SIZE]; -- unsigned long flags; -+ struct bpf_bprintf_data data = { -+ .get_bin_args = true, -+ .get_buf = true, -+ }; - int ret, num_args; -- u32 *bin_args; - - if (data_len & 7 || data_len > MAX_BPRINTF_VARARGS * 8 || -- (data_len && !data)) -+ (data_len && !args)) - return -EINVAL; - num_args = data_len / 8; - -- ret = bpf_bprintf_prepare(fmt, fmt_size, data, &bin_args, num_args); -+ ret = bpf_bprintf_prepare(fmt, fmt_size, args, num_args, &data); - if (ret < 0) - return ret; - -- raw_spin_lock_irqsave(&trace_printk_lock, flags); -- ret = bstr_printf(buf, sizeof(buf), fmt, bin_args); -+ ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args); - -- trace_bpf_trace_printk(buf); -- raw_spin_unlock_irqrestore(&trace_printk_lock, flags); -+ trace_bpf_trace_printk(data.buf); - -- bpf_bprintf_cleanup(); -+ bpf_bprintf_cleanup(&data); - - return ret; - } -@@ -471,23 +467,25 @@ const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void) - } - - BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size, -- const void *, data, u32, data_len) -+ const void *, args, u32, data_len) - { -+ struct bpf_bprintf_data data = { -+ .get_bin_args = true, -+ }; - int err, num_args; -- u32 *bin_args; - - if (data_len & 7 || data_len > MAX_BPRINTF_VARARGS * 8 || -- (data_len && !data)) -+ (data_len && !args)) - return -EINVAL; - num_args = data_len / 8; - -- err = bpf_bprintf_prepare(fmt, fmt_size, data, &bin_args, num_args); -+ err = bpf_bprintf_prepare(fmt, fmt_size, args, num_args, &data); - if (err < 0) - return err; - -- seq_bprintf(m, fmt, bin_args); -+ seq_bprintf(m, fmt, data.bin_args); - -- bpf_bprintf_cleanup(); -+ bpf_bprintf_cleanup(&data); - - return seq_has_overflowed(m) ? -EOVERFLOW : 0; - } -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 1285e7fb597ee..e019a9278794f 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -1095,7 +1095,7 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, - full = 0; - } else { - if (!cpumask_test_cpu(cpu, buffer->cpumask)) -- return -EINVAL; -+ return EPOLLERR; - - cpu_buffer = buffer->buffers[cpu]; - work = &cpu_buffer->irq_work; -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 2b3c4cd8382b3..f667d6bdddda5 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2249,7 +2250,7 @@ struct saved_cmdlines_buffer { - unsigned *map_cmdline_to_pid; - unsigned cmdline_num; - int cmdline_idx; -- char *saved_cmdlines; -+ char saved_cmdlines[]; - }; - static struct saved_cmdlines_buffer *savedcmd; - -@@ -2263,47 +2264,60 @@ static inline void set_cmdline(int idx, const char *cmdline) - strncpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN); - } - --static int allocate_cmdlines_buffer(unsigned int val, -- struct saved_cmdlines_buffer *s) -+static void free_saved_cmdlines_buffer(struct saved_cmdlines_buffer *s) - { -+ int order = get_order(sizeof(*s) + s->cmdline_num * TASK_COMM_LEN); -+ -+ kfree(s->map_cmdline_to_pid); -+ kmemleak_free(s); -+ free_pages((unsigned long)s, order); -+} -+ -+static struct saved_cmdlines_buffer *allocate_cmdlines_buffer(unsigned int val) -+{ -+ struct saved_cmdlines_buffer *s; -+ struct page *page; -+ int orig_size, size; -+ int order; -+ -+ /* Figure out how much is needed to hold the given number of cmdlines */ -+ orig_size = sizeof(*s) + val * TASK_COMM_LEN; -+ order = get_order(orig_size); -+ size = 1 << (order + PAGE_SHIFT); -+ page = alloc_pages(GFP_KERNEL, order); -+ if (!page) -+ return NULL; -+ -+ s = page_address(page); -+ kmemleak_alloc(s, size, 1, GFP_KERNEL); -+ memset(s, 0, sizeof(*s)); -+ -+ /* Round up to actual allocation */ -+ val = (size - sizeof(*s)) / TASK_COMM_LEN; -+ s->cmdline_num = val; -+ - s->map_cmdline_to_pid = kmalloc_array(val, - sizeof(*s->map_cmdline_to_pid), - GFP_KERNEL); -- if (!s->map_cmdline_to_pid) -- return -ENOMEM; -- -- s->saved_cmdlines = kmalloc_array(TASK_COMM_LEN, val, GFP_KERNEL); -- if (!s->saved_cmdlines) { -- kfree(s->map_cmdline_to_pid); -- return -ENOMEM; -+ if (!s->map_cmdline_to_pid) { -+ free_saved_cmdlines_buffer(s); -+ return NULL; - } - - s->cmdline_idx = 0; -- s->cmdline_num = val; - memset(&s->map_pid_to_cmdline, NO_CMDLINE_MAP, - sizeof(s->map_pid_to_cmdline)); - memset(s->map_cmdline_to_pid, NO_CMDLINE_MAP, - val * sizeof(*s->map_cmdline_to_pid)); - -- return 0; -+ return s; - } - - static int trace_create_savedcmd(void) - { -- int ret; -- -- savedcmd = kmalloc(sizeof(*savedcmd), GFP_KERNEL); -- if (!savedcmd) -- return -ENOMEM; -+ savedcmd = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT); - -- ret = allocate_cmdlines_buffer(SAVED_CMDLINES_DEFAULT, savedcmd); -- if (ret < 0) { -- kfree(savedcmd); -- savedcmd = NULL; -- return -ENOMEM; -- } -- -- return 0; -+ return savedcmd ? 0 : -ENOMEM; - } - - int is_tracing_stopped(void) -@@ -5972,26 +5986,14 @@ tracing_saved_cmdlines_size_read(struct file *filp, char __user *ubuf, - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); - } - --static void free_saved_cmdlines_buffer(struct saved_cmdlines_buffer *s) --{ -- kfree(s->saved_cmdlines); -- kfree(s->map_cmdline_to_pid); -- kfree(s); --} -- - static int tracing_resize_saved_cmdlines(unsigned int val) - { - struct saved_cmdlines_buffer *s, *savedcmd_temp; - -- s = kmalloc(sizeof(*s), GFP_KERNEL); -+ s = allocate_cmdlines_buffer(val); - if (!s) - return -ENOMEM; - -- if (allocate_cmdlines_buffer(val, s) < 0) { -- kfree(s); -- return -ENOMEM; -- } -- - preempt_disable(); - arch_spin_lock(&trace_cmdline_lock); - savedcmd_temp = savedcmd; -diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c -index 918730d749325..f941ce01ee351 100644 ---- a/kernel/trace/trace_events_trigger.c -+++ b/kernel/trace/trace_events_trigger.c -@@ -1455,8 +1455,10 @@ register_snapshot_trigger(char *glob, - struct event_trigger_data *data, - struct trace_event_file *file) - { -- if (tracing_alloc_snapshot_instance(file->tr) != 0) -- return 0; -+ int ret = tracing_alloc_snapshot_instance(file->tr); -+ -+ if (ret < 0) -+ return ret; - - return register_trigger(glob, data, file); - } -diff --git a/lib/mpi/ec.c b/lib/mpi/ec.c -index 40f5908e57a4f..e16dca1e23d52 100644 ---- a/lib/mpi/ec.c -+++ b/lib/mpi/ec.c -@@ -584,6 +584,9 @@ void mpi_ec_init(struct mpi_ec_ctx *ctx, enum gcry_mpi_ec_models model, - ctx->a = mpi_copy(a); - ctx->b = mpi_copy(b); - -+ ctx->d = NULL; -+ ctx->t.two_inv_p = NULL; -+ - ctx->t.p_barrett = use_barrett > 0 ? mpi_barrett_init(ctx->p, 0) : NULL; - - mpi_ec_get_reset(ctx); -diff --git a/mm/page-writeback.c b/mm/page-writeback.c -index de5f69921b946..d3e9d12860b9f 100644 ---- a/mm/page-writeback.c -+++ b/mm/page-writeback.c -@@ -1526,7 +1526,7 @@ static inline void wb_dirty_limits(struct dirty_throttle_control *dtc) - */ - dtc->wb_thresh = __wb_calc_thresh(dtc); - dtc->wb_bg_thresh = dtc->thresh ? -- div_u64((u64)dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0; -+ div64_u64(dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0; - - /* - * In order to avoid the stacked BDI deadlock we need -diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c -index 650ab6cfd5f49..992a0a16846f7 100644 ---- a/mm/userfaultfd.c -+++ b/mm/userfaultfd.c -@@ -327,6 +327,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, - unsigned long dst_start, - unsigned long src_start, - unsigned long len, -+ atomic_t *mmap_changing, - enum mcopy_atomic_mode mode, - bool wp_copy) - { -@@ -445,6 +446,15 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, - goto out; - } - mmap_read_lock(dst_mm); -+ /* -+ * If memory mappings are changing because of non-cooperative -+ * operation (e.g. mremap) running in parallel, bail out and -+ * request the user to retry later -+ */ -+ if (mmap_changing && atomic_read(mmap_changing)) { -+ err = -EAGAIN; -+ break; -+ } - - dst_vma = NULL; - goto retry; -@@ -480,6 +490,7 @@ extern ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, - unsigned long dst_start, - unsigned long src_start, - unsigned long len, -+ atomic_t *mmap_changing, - enum mcopy_atomic_mode mode, - bool wp_copy); - #endif /* CONFIG_HUGETLB_PAGE */ -@@ -601,8 +612,8 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, - */ - if (is_vm_hugetlb_page(dst_vma)) - return __mcopy_atomic_hugetlb(dst_mm, dst_vma, dst_start, -- src_start, len, mcopy_mode, -- wp_copy); -+ src_start, len, mmap_changing, -+ mcopy_mode, wp_copy); - - if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma)) - goto out_unlock; -diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h -index 16af1a7f80f60..31a93cae5111b 100644 ---- a/net/can/j1939/j1939-priv.h -+++ b/net/can/j1939/j1939-priv.h -@@ -86,7 +86,7 @@ struct j1939_priv { - unsigned int tp_max_packet_size; - - /* lock for j1939_socks list */ -- spinlock_t j1939_socks_lock; -+ rwlock_t j1939_socks_lock; - struct list_head j1939_socks; - - struct kref rx_kref; -@@ -301,6 +301,7 @@ struct j1939_sock { - - int ifindex; - struct j1939_addr addr; -+ spinlock_t filters_lock; - struct j1939_filter *filters; - int nfilters; - pgn_t pgn_rx_filter; -diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c -index ecff1c947d683..a6fb89fa62785 100644 ---- a/net/can/j1939/main.c -+++ b/net/can/j1939/main.c -@@ -274,7 +274,7 @@ struct j1939_priv *j1939_netdev_start(struct net_device *ndev) - return ERR_PTR(-ENOMEM); - - j1939_tp_init(priv); -- spin_lock_init(&priv->j1939_socks_lock); -+ rwlock_init(&priv->j1939_socks_lock); - INIT_LIST_HEAD(&priv->j1939_socks); - - mutex_lock(&j1939_netdev_lock); -diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c -index b0be23559243c..58909b36561a6 100644 ---- a/net/can/j1939/socket.c -+++ b/net/can/j1939/socket.c -@@ -80,16 +80,16 @@ static void j1939_jsk_add(struct j1939_priv *priv, struct j1939_sock *jsk) - jsk->state |= J1939_SOCK_BOUND; - j1939_priv_get(priv); - -- spin_lock_bh(&priv->j1939_socks_lock); -+ write_lock_bh(&priv->j1939_socks_lock); - list_add_tail(&jsk->list, &priv->j1939_socks); -- spin_unlock_bh(&priv->j1939_socks_lock); -+ write_unlock_bh(&priv->j1939_socks_lock); - } - - static void j1939_jsk_del(struct j1939_priv *priv, struct j1939_sock *jsk) - { -- spin_lock_bh(&priv->j1939_socks_lock); -+ write_lock_bh(&priv->j1939_socks_lock); - list_del_init(&jsk->list); -- spin_unlock_bh(&priv->j1939_socks_lock); -+ write_unlock_bh(&priv->j1939_socks_lock); - - j1939_priv_put(priv); - jsk->state &= ~J1939_SOCK_BOUND; -@@ -262,12 +262,17 @@ static bool j1939_sk_match_dst(struct j1939_sock *jsk, - static bool j1939_sk_match_filter(struct j1939_sock *jsk, - const struct j1939_sk_buff_cb *skcb) - { -- const struct j1939_filter *f = jsk->filters; -- int nfilter = jsk->nfilters; -+ const struct j1939_filter *f; -+ int nfilter; -+ -+ spin_lock_bh(&jsk->filters_lock); -+ -+ f = jsk->filters; -+ nfilter = jsk->nfilters; - - if (!nfilter) - /* receive all when no filters are assigned */ -- return true; -+ goto filter_match_found; - - for (; nfilter; ++f, --nfilter) { - if ((skcb->addr.pgn & f->pgn_mask) != f->pgn) -@@ -276,9 +281,15 @@ static bool j1939_sk_match_filter(struct j1939_sock *jsk, - continue; - if ((skcb->addr.src_name & f->name_mask) != f->name) - continue; -- return true; -+ goto filter_match_found; - } -+ -+ spin_unlock_bh(&jsk->filters_lock); - return false; -+ -+filter_match_found: -+ spin_unlock_bh(&jsk->filters_lock); -+ return true; - } - - static bool j1939_sk_recv_match_one(struct j1939_sock *jsk, -@@ -329,13 +340,13 @@ bool j1939_sk_recv_match(struct j1939_priv *priv, struct j1939_sk_buff_cb *skcb) - struct j1939_sock *jsk; - bool match = false; - -- spin_lock_bh(&priv->j1939_socks_lock); -+ read_lock_bh(&priv->j1939_socks_lock); - list_for_each_entry(jsk, &priv->j1939_socks, list) { - match = j1939_sk_recv_match_one(jsk, skcb); - if (match) - break; - } -- spin_unlock_bh(&priv->j1939_socks_lock); -+ read_unlock_bh(&priv->j1939_socks_lock); - - return match; - } -@@ -344,11 +355,11 @@ void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb) - { - struct j1939_sock *jsk; - -- spin_lock_bh(&priv->j1939_socks_lock); -+ read_lock_bh(&priv->j1939_socks_lock); - list_for_each_entry(jsk, &priv->j1939_socks, list) { - j1939_sk_recv_one(jsk, skb); - } -- spin_unlock_bh(&priv->j1939_socks_lock); -+ read_unlock_bh(&priv->j1939_socks_lock); - } - - static void j1939_sk_sock_destruct(struct sock *sk) -@@ -401,6 +412,7 @@ static int j1939_sk_init(struct sock *sk) - atomic_set(&jsk->skb_pending, 0); - spin_lock_init(&jsk->sk_session_queue_lock); - INIT_LIST_HEAD(&jsk->sk_session_queue); -+ spin_lock_init(&jsk->filters_lock); - - /* j1939_sk_sock_destruct() depends on SOCK_RCU_FREE flag */ - sock_set_flag(sk, SOCK_RCU_FREE); -@@ -703,9 +715,11 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname, - } - - lock_sock(&jsk->sk); -+ spin_lock_bh(&jsk->filters_lock); - ofilters = jsk->filters; - jsk->filters = filters; - jsk->nfilters = count; -+ spin_unlock_bh(&jsk->filters_lock); - release_sock(&jsk->sk); - kfree(ofilters); - return 0; -@@ -1080,12 +1094,12 @@ void j1939_sk_errqueue(struct j1939_session *session, - } - - /* spread RX notifications to all sockets subscribed to this session */ -- spin_lock_bh(&priv->j1939_socks_lock); -+ read_lock_bh(&priv->j1939_socks_lock); - list_for_each_entry(jsk, &priv->j1939_socks, list) { - if (j1939_sk_recv_match_one(jsk, &session->skcb)) - __j1939_sk_errqueue(session, &jsk->sk, type); - } -- spin_unlock_bh(&priv->j1939_socks_lock); -+ read_unlock_bh(&priv->j1939_socks_lock); - }; - - void j1939_sk_send_loop_abort(struct sock *sk, int err) -@@ -1273,7 +1287,7 @@ void j1939_sk_netdev_event_netdown(struct j1939_priv *priv) - struct j1939_sock *jsk; - int error_code = ENETDOWN; - -- spin_lock_bh(&priv->j1939_socks_lock); -+ read_lock_bh(&priv->j1939_socks_lock); - list_for_each_entry(jsk, &priv->j1939_socks, list) { - jsk->sk.sk_err = error_code; - if (!sock_flag(&jsk->sk, SOCK_DEAD)) -@@ -1281,7 +1295,7 @@ void j1939_sk_netdev_event_netdown(struct j1939_priv *priv) - - j1939_sk_queue_drop_all(priv, jsk, error_code); - } -- spin_unlock_bh(&priv->j1939_socks_lock); -+ read_unlock_bh(&priv->j1939_socks_lock); - } - - static int j1939_sk_no_ioctlcmd(struct socket *sock, unsigned int cmd, -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 8a819d0a7bfb0..d4bd10f8723df 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -4213,8 +4213,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/hsr/hsr_device.c b/net/hsr/hsr_device.c -index b1e86a7265b32..83906d093f0ae 100644 ---- a/net/hsr/hsr_device.c -+++ b/net/hsr/hsr_device.c -@@ -291,7 +291,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master, - - skb = hsr_init_skb(master); - if (!skb) { -- WARN_ONCE(1, "HSR: Could not send supervision frame\n"); -+ netdev_warn_once(master->dev, "HSR: Could not send supervision frame\n"); - return; - } - -@@ -338,7 +338,7 @@ static void send_prp_supervision_frame(struct hsr_port *master, - - skb = hsr_init_skb(master); - if (!skb) { -- WARN_ONCE(1, "PRP: Could not send supervision frame\n"); -+ netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n"); - return; - } - -diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c -index 2db103a56a28f..322a035f75929 100644 ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -5,7 +5,7 @@ - * Copyright 2006-2007 Jiri Benc - * Copyright 2007 Johannes Berg - * Copyright 2013-2014 Intel Mobile Communications GmbH -- * Copyright (C) 2018-2022 Intel Corporation -+ * Copyright (C) 2018-2024 Intel Corporation - * - * Transmit and frame generation functions. - */ -@@ -3838,6 +3838,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, - goto begin; - - skb = __skb_dequeue(&tx.skbs); -+ info = IEEE80211_SKB_CB(skb); - - if (!skb_queue_empty(&tx.skbs)) { - spin_lock_bh(&fq->lock); -@@ -3882,7 +3883,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, - } - - encap_out: -- IEEE80211_SKB_CB(skb)->control.vif = vif; -+ info->control.vif = vif; - - if (tx.sta && - wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) { -diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c -index 38cbdc66d8bff..2e1e0d0e3ec60 100644 ---- a/net/mptcp/pm_userspace.c -+++ b/net/mptcp/pm_userspace.c -@@ -132,10 +132,21 @@ int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, - int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - struct mptcp_addr_info *skc) - { -- struct mptcp_pm_addr_entry new_entry; -+ struct mptcp_pm_addr_entry *entry = NULL, *e, new_entry; - __be16 msk_sport = ((struct inet_sock *) - inet_sk((struct sock *)msk))->inet_sport; - -+ spin_lock_bh(&msk->pm.lock); -+ list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) { -+ if (mptcp_addresses_equal(&e->addr, skc, false)) { -+ entry = e; -+ break; -+ } -+ } -+ spin_unlock_bh(&msk->pm.lock); -+ if (entry) -+ return entry->addr.id; -+ - memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry)); - new_entry.addr = *skc; - new_entry.addr.id = 0; -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 76539d1004ebb..859b18cb8e4f6 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -1582,8 +1582,11 @@ static void mptcp_update_post_push(struct mptcp_sock *msk, - - void mptcp_check_and_set_pending(struct sock *sk) - { -- if (mptcp_send_head(sk)) -- mptcp_sk(sk)->push_pending |= BIT(MPTCP_PUSH_PENDING); -+ if (mptcp_send_head(sk)) { -+ mptcp_data_lock(sk); -+ mptcp_sk(sk)->cb_flags |= BIT(MPTCP_PUSH_PENDING); -+ mptcp_data_unlock(sk); -+ } - } - - void __mptcp_push_pending(struct sock *sk, unsigned int flags) -@@ -2336,9 +2339,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) - if (__mptcp_check_fallback(mptcp_sk(sk))) - return false; - -- if (tcp_rtx_and_write_queues_empty(sk)) -- return false; -- - /* the closing socket has some data untransmitted and/or unacked: - * some data in the mptcp rtx queue has not really xmitted yet. - * keep it simple and re-inject the whole mptcp level rtx queue -@@ -2422,7 +2422,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - goto out_release; - } - -- dispose_it = !msk->subflow || ssk != msk->subflow->sk; -+ dispose_it = msk->free_first || ssk != msk->first; - if (dispose_it) - list_del(&subflow->node); - -@@ -2440,7 +2440,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); - if (!dispose_it) { - __mptcp_subflow_disconnect(ssk, subflow, flags); -- msk->subflow->state = SS_UNCONNECTED; - release_sock(ssk); - - goto out; -@@ -3144,7 +3143,6 @@ static int mptcp_disconnect(struct sock *sk, int flags) - msk->last_snd = NULL; - WRITE_ONCE(msk->flags, 0); - msk->cb_flags = 0; -- msk->push_pending = 0; - msk->recovery = false; - msk->can_ack = false; - msk->fully_established = false; -@@ -3341,10 +3339,10 @@ static void mptcp_destroy(struct sock *sk) - { - struct mptcp_sock *msk = mptcp_sk(sk); - -- /* clears msk->subflow, allowing the following to close -- * even the initial subflow -- */ - mptcp_dispose_initial_subflow(msk); -+ -+ /* allow the following to close even the initial subflow */ -+ msk->free_first = 1; - mptcp_destroy_common(msk, 0); - sk_sockets_allocated_dec(sk); - } -@@ -3388,8 +3386,7 @@ static void mptcp_release_cb(struct sock *sk) - struct mptcp_sock *msk = mptcp_sk(sk); - - for (;;) { -- unsigned long flags = (msk->cb_flags & MPTCP_FLAGS_PROCESS_CTX_NEED) | -- msk->push_pending; -+ unsigned long flags = (msk->cb_flags & MPTCP_FLAGS_PROCESS_CTX_NEED); - struct list_head join_list; - - if (!flags) -@@ -3405,7 +3402,6 @@ static void mptcp_release_cb(struct sock *sk) - * datapath acquires the msk socket spinlock while helding - * the subflow socket lock - */ -- msk->push_pending = 0; - msk->cb_flags &= ~flags; - spin_unlock_bh(&sk->sk_lock.slock); - -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index 4ec8e0a81b5a4..259672cc344f3 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -272,7 +272,6 @@ struct mptcp_sock { - int rmem_released; - unsigned long flags; - unsigned long cb_flags; -- unsigned long push_pending; - bool recovery; /* closing subflow write queue reinjected */ - bool can_ack; - bool fully_established; -@@ -287,7 +286,8 @@ struct mptcp_sock { - cork:1, - nodelay:1, - fastopening:1, -- in_accept_queue:1; -+ in_accept_queue:1, -+ free_first:1; - struct work_struct work; - struct sk_buff *ooo_last_skb; - struct rb_root out_of_order_queue; -diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h -index 26ab0e9612d82..9523104a90da4 100644 ---- a/net/netfilter/ipset/ip_set_bitmap_gen.h -+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h -@@ -28,6 +28,7 @@ - #define mtype_del IPSET_TOKEN(MTYPE, _del) - #define mtype_list IPSET_TOKEN(MTYPE, _list) - #define mtype_gc IPSET_TOKEN(MTYPE, _gc) -+#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) - #define mtype MTYPE - - #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id))) -@@ -57,9 +58,6 @@ mtype_destroy(struct ip_set *set) - { - struct mtype *map = set->data; - -- if (SET_WITH_TIMEOUT(set)) -- del_timer_sync(&map->gc); -- - if (set->dsize && set->extensions & IPSET_EXT_DESTROY) - mtype_ext_cleanup(set); - ip_set_free(map->members); -@@ -288,6 +286,15 @@ mtype_gc(struct timer_list *t) - add_timer(&map->gc); - } - -+static void -+mtype_cancel_gc(struct ip_set *set) -+{ -+ struct mtype *map = set->data; -+ -+ if (SET_WITH_TIMEOUT(set)) -+ del_timer_sync(&map->gc); -+} -+ - static const struct ip_set_type_variant mtype = { - .kadt = mtype_kadt, - .uadt = mtype_uadt, -@@ -301,6 +308,7 @@ static const struct ip_set_type_variant mtype = { - .head = mtype_head, - .list = mtype_list, - .same_set = mtype_same_set, -+ .cancel_gc = mtype_cancel_gc, - }; - - #endif /* __IP_SET_BITMAP_IP_GEN_H */ -diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c -index d47dfdcb899b0..f645da82d826e 100644 ---- a/net/netfilter/ipset/ip_set_core.c -+++ b/net/netfilter/ipset/ip_set_core.c -@@ -1156,6 +1156,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, - return ret; - - cleanup: -+ set->variant->cancel_gc(set); - set->variant->destroy(set); - put_out: - module_put(set->type->me); -@@ -1184,6 +1185,14 @@ ip_set_destroy_set(struct ip_set *set) - kfree(set); - } - -+static void -+ip_set_destroy_set_rcu(struct rcu_head *head) -+{ -+ struct ip_set *set = container_of(head, struct ip_set, rcu); -+ -+ ip_set_destroy_set(set); -+} -+ - static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - const struct nlattr * const attr[]) - { -@@ -1195,8 +1204,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - if (unlikely(protocol_min_failed(attr))) - return -IPSET_ERR_PROTOCOL; - -- /* Must wait for flush to be really finished in list:set */ -- rcu_barrier(); - - /* Commands are serialized and references are - * protected by the ip_set_ref_lock. -@@ -1208,8 +1215,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - * counter, so if it's already zero, we can proceed - * without holding the lock. - */ -- read_lock_bh(&ip_set_ref_lock); - if (!attr[IPSET_ATTR_SETNAME]) { -+ /* Must wait for flush to be really finished in list:set */ -+ rcu_barrier(); -+ read_lock_bh(&ip_set_ref_lock); - for (i = 0; i < inst->ip_set_max; i++) { - s = ip_set(inst, i); - if (s && (s->ref || s->ref_netlink)) { -@@ -1223,6 +1232,8 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - s = ip_set(inst, i); - if (s) { - ip_set(inst, i) = NULL; -+ /* Must cancel garbage collectors */ -+ s->variant->cancel_gc(s); - ip_set_destroy_set(s); - } - } -@@ -1230,6 +1241,9 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - inst->is_destroyed = false; - } else { - u32 flags = flag_exist(info->nlh); -+ u16 features = 0; -+ -+ read_lock_bh(&ip_set_ref_lock); - s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]), - &i); - if (!s) { -@@ -1240,10 +1254,16 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, - ret = -IPSET_ERR_BUSY; - goto out; - } -+ features = s->type->features; - ip_set(inst, i) = NULL; - read_unlock_bh(&ip_set_ref_lock); -- -- ip_set_destroy_set(s); -+ if (features & IPSET_TYPE_NAME) { -+ /* Must wait for flush to be really finished */ -+ rcu_barrier(); -+ } -+ /* Must cancel garbage collectors */ -+ s->variant->cancel_gc(s); -+ call_rcu(&s->rcu, ip_set_destroy_set_rcu); - } - return 0; - out: -@@ -1396,9 +1416,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info, - ip_set(inst, to_id) = from; - write_unlock_bh(&ip_set_ref_lock); - -- /* Make sure all readers of the old set pointers are completed. */ -- synchronize_rcu(); -- - return 0; - } - -@@ -2364,6 +2381,7 @@ ip_set_net_exit(struct net *net) - set = ip_set(inst, i); - if (set) { - ip_set(inst, i) = NULL; -+ set->variant->cancel_gc(set); - ip_set_destroy_set(set); - } - } -@@ -2411,8 +2429,11 @@ ip_set_fini(void) - { - nf_unregister_sockopt(&so_set); - nfnetlink_subsys_unregister(&ip_set_netlink_subsys); -- - unregister_pernet_subsys(&ip_set_net_ops); -+ -+ /* Wait for call_rcu() in destroy */ -+ rcu_barrier(); -+ - pr_debug("these are the famous last words\n"); - } - -diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h -index 7499192af5866..ef04e556aadb4 100644 ---- a/net/netfilter/ipset/ip_set_hash_gen.h -+++ b/net/netfilter/ipset/ip_set_hash_gen.h -@@ -210,6 +210,7 @@ htable_size(u8 hbits) - #undef mtype_gc_do - #undef mtype_gc - #undef mtype_gc_init -+#undef mtype_cancel_gc - #undef mtype_variant - #undef mtype_data_match - -@@ -254,6 +255,7 @@ htable_size(u8 hbits) - #define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) - #define mtype_gc IPSET_TOKEN(MTYPE, _gc) - #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) -+#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) - #define mtype_variant IPSET_TOKEN(MTYPE, _variant) - #define mtype_data_match IPSET_TOKEN(MTYPE, _data_match) - -@@ -417,7 +419,7 @@ mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy) - u32 i; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { -- n = __ipset_dereference(hbucket(t, i)); -+ n = (__force struct hbucket *)hbucket(t, i); - if (!n) - continue; - if (set->extensions & IPSET_EXT_DESTROY && ext_destroy) -@@ -437,10 +439,7 @@ mtype_destroy(struct ip_set *set) - struct htype *h = set->data; - struct list_head *l, *lt; - -- if (SET_WITH_TIMEOUT(set)) -- cancel_delayed_work_sync(&h->gc.dwork); -- -- mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); -+ mtype_ahash_destroy(set, (__force struct htable *)h->table, true); - list_for_each_safe(l, lt, &h->ad) { - list_del(l); - kfree(l); -@@ -586,6 +585,15 @@ mtype_gc_init(struct htable_gc *gc) - queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ); - } - -+static void -+mtype_cancel_gc(struct ip_set *set) -+{ -+ struct htype *h = set->data; -+ -+ if (SET_WITH_TIMEOUT(set)) -+ cancel_delayed_work_sync(&h->gc.dwork); -+} -+ - static int - mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, - struct ip_set_ext *mext, u32 flags); -@@ -1416,6 +1424,7 @@ static const struct ip_set_type_variant mtype_variant = { - .uref = mtype_uref, - .resize = mtype_resize, - .same_set = mtype_same_set, -+ .cancel_gc = mtype_cancel_gc, - .region_lock = true, - }; - -diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c -index 5a67f79665742..6bc7019982b05 100644 ---- a/net/netfilter/ipset/ip_set_list_set.c -+++ b/net/netfilter/ipset/ip_set_list_set.c -@@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set) - struct list_set *map = set->data; - struct set_elem *e, *n; - -- if (SET_WITH_TIMEOUT(set)) -- del_timer_sync(&map->gc); -- - list_for_each_entry_safe(e, n, &map->members, list) { - list_del(&e->list); - ip_set_put_byindex(map->net, e->id); -@@ -545,6 +542,15 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b) - a->extensions == b->extensions; - } - -+static void -+list_set_cancel_gc(struct ip_set *set) -+{ -+ struct list_set *map = set->data; -+ -+ if (SET_WITH_TIMEOUT(set)) -+ del_timer_sync(&map->gc); -+} -+ - static const struct ip_set_type_variant set_variant = { - .kadt = list_set_kadt, - .uadt = list_set_uadt, -@@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = { - .head = list_set_head, - .list = list_set_list, - .same_set = list_set_same_set, -+ .cancel_gc = list_set_cancel_gc, - }; - - static void -diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c -index 90e275bb3e5d7..a3a8ddca99189 100644 ---- a/net/netfilter/nft_set_pipapo_avx2.c -+++ b/net/netfilter/nft_set_pipapo_avx2.c -@@ -57,7 +57,7 @@ - - /* Jump to label if @reg is zero */ - #define NFT_PIPAPO_AVX2_NOMATCH_GOTO(reg, label) \ -- asm_volatile_goto("vptest %%ymm" #reg ", %%ymm" #reg ";" \ -+ asm goto("vptest %%ymm" #reg ", %%ymm" #reg ";" \ - "je %l[" #label "]" : : : : label) - - /* Store 256 bits from YMM register into memory. Contrary to bucket load -diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c -index 7535afd1537e9..b5071a2f597d4 100644 ---- a/net/nfc/nci/core.c -+++ b/net/nfc/nci/core.c -@@ -1207,6 +1207,10 @@ void nci_free_device(struct nci_dev *ndev) - { - nfc_free_device(ndev->nfc_dev); - nci_hci_deallocate(ndev); -+ -+ /* drop partial rx data packet if present */ -+ if (ndev->rx_data_reassembly) -+ kfree_skb(ndev->rx_data_reassembly); - kfree(ndev); - } - EXPORT_SYMBOL(nci_free_device); -diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c -index ead5418c126e3..e3c85ceb1f0a5 100644 ---- a/net/openvswitch/flow_netlink.c -+++ b/net/openvswitch/flow_netlink.c -@@ -47,6 +47,7 @@ struct ovs_len_tbl { - - #define OVS_ATTR_NESTED -1 - #define OVS_ATTR_VARIABLE -2 -+#define OVS_COPY_ACTIONS_MAX_DEPTH 16 - - static bool actions_may_change_flow(const struct nlattr *actions) - { -@@ -2543,13 +2544,15 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - const struct sw_flow_key *key, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, -- u32 mpls_label_count, bool log); -+ u32 mpls_label_count, bool log, -+ u32 depth); - - static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, - const struct sw_flow_key *key, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, -- u32 mpls_label_count, bool log, bool last) -+ u32 mpls_label_count, bool log, bool last, -+ u32 depth) - { - const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1]; - const struct nlattr *probability, *actions; -@@ -2600,7 +2603,8 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr, - return err; - - err = __ovs_nla_copy_actions(net, actions, key, sfa, -- eth_type, vlan_tci, mpls_label_count, log); -+ eth_type, vlan_tci, mpls_label_count, log, -+ depth + 1); - - if (err) - return err; -@@ -2615,7 +2619,8 @@ static int validate_and_copy_dec_ttl(struct net *net, - const struct sw_flow_key *key, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, -- u32 mpls_label_count, bool log) -+ u32 mpls_label_count, bool log, -+ u32 depth) - { - const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1]; - int start, action_start, err, rem; -@@ -2658,7 +2663,8 @@ static int validate_and_copy_dec_ttl(struct net *net, - return action_start; - - err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type, -- vlan_tci, mpls_label_count, log); -+ vlan_tci, mpls_label_count, log, -+ depth + 1); - if (err) - return err; - -@@ -2672,7 +2678,8 @@ static int validate_and_copy_clone(struct net *net, - const struct sw_flow_key *key, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, -- u32 mpls_label_count, bool log, bool last) -+ u32 mpls_label_count, bool log, bool last, -+ u32 depth) - { - int start, err; - u32 exec; -@@ -2692,7 +2699,8 @@ static int validate_and_copy_clone(struct net *net, - return err; - - err = __ovs_nla_copy_actions(net, attr, key, sfa, -- eth_type, vlan_tci, mpls_label_count, log); -+ eth_type, vlan_tci, mpls_label_count, log, -+ depth + 1); - if (err) - return err; - -@@ -3061,7 +3069,7 @@ static int validate_and_copy_check_pkt_len(struct net *net, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, - u32 mpls_label_count, -- bool log, bool last) -+ bool log, bool last, u32 depth) - { - const struct nlattr *acts_if_greater, *acts_if_lesser_eq; - struct nlattr *a[OVS_CHECK_PKT_LEN_ATTR_MAX + 1]; -@@ -3109,7 +3117,8 @@ static int validate_and_copy_check_pkt_len(struct net *net, - return nested_acts_start; - - err = __ovs_nla_copy_actions(net, acts_if_lesser_eq, key, sfa, -- eth_type, vlan_tci, mpls_label_count, log); -+ eth_type, vlan_tci, mpls_label_count, log, -+ depth + 1); - - if (err) - return err; -@@ -3122,7 +3131,8 @@ static int validate_and_copy_check_pkt_len(struct net *net, - return nested_acts_start; - - err = __ovs_nla_copy_actions(net, acts_if_greater, key, sfa, -- eth_type, vlan_tci, mpls_label_count, log); -+ eth_type, vlan_tci, mpls_label_count, log, -+ depth + 1); - - if (err) - return err; -@@ -3150,12 +3160,16 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - const struct sw_flow_key *key, - struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci, -- u32 mpls_label_count, bool log) -+ u32 mpls_label_count, bool log, -+ u32 depth) - { - u8 mac_proto = ovs_key_mac_proto(key); - const struct nlattr *a; - int rem, err; - -+ if (depth > OVS_COPY_ACTIONS_MAX_DEPTH) -+ return -EOVERFLOW; -+ - nla_for_each_nested(a, attr, rem) { - /* Expected argument lengths, (u32)-1 for variable length. */ - static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = { -@@ -3350,7 +3364,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - err = validate_and_copy_sample(net, a, key, sfa, - eth_type, vlan_tci, - mpls_label_count, -- log, last); -+ log, last, depth); - if (err) - return err; - skip_copy = true; -@@ -3421,7 +3435,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - err = validate_and_copy_clone(net, a, key, sfa, - eth_type, vlan_tci, - mpls_label_count, -- log, last); -+ log, last, depth); - if (err) - return err; - skip_copy = true; -@@ -3435,7 +3449,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - eth_type, - vlan_tci, - mpls_label_count, -- log, last); -+ log, last, -+ depth); - if (err) - return err; - skip_copy = true; -@@ -3445,7 +3460,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - case OVS_ACTION_ATTR_DEC_TTL: - err = validate_and_copy_dec_ttl(net, a, key, sfa, - eth_type, vlan_tci, -- mpls_label_count, log); -+ mpls_label_count, log, -+ depth); - if (err) - return err; - skip_copy = true; -@@ -3485,7 +3501,8 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, - - (*sfa)->orig_len = nla_len(attr); - err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type, -- key->eth.vlan.tci, mpls_label_count, log); -+ key->eth.vlan.tci, mpls_label_count, log, -+ 0); - if (err) - ovs_nla_free_flow_actions(*sfa); - -diff --git a/net/tls/tls.h b/net/tls/tls.h -index 0672acab27731..4922668fefaa8 100644 ---- a/net/tls/tls.h -+++ b/net/tls/tls.h -@@ -97,6 +97,7 @@ void tls_update_rx_zc_capable(struct tls_context *tls_ctx); - void tls_sw_strparser_arm(struct sock *sk, struct tls_context *ctx); - void tls_sw_strparser_done(struct tls_context *tls_ctx); - int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); -+void tls_sw_splice_eof(struct socket *sock); - int tls_sw_sendpage_locked(struct sock *sk, struct page *page, - int offset, size_t size, int flags); - int tls_sw_sendpage(struct sock *sk, struct page *page, -diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c -index 338a443fa47b2..80b42a3e78830 100644 ---- a/net/tls/tls_main.c -+++ b/net/tls/tls_main.c -@@ -922,6 +922,7 @@ static void build_proto_ops(struct proto_ops ops[TLS_NUM_CONFIG][TLS_NUM_CONFIG] - ops[TLS_BASE][TLS_BASE] = *base; - - ops[TLS_SW ][TLS_BASE] = ops[TLS_BASE][TLS_BASE]; -+ ops[TLS_SW ][TLS_BASE].splice_eof = tls_sw_splice_eof; - ops[TLS_SW ][TLS_BASE].sendpage_locked = tls_sw_sendpage_locked; - - ops[TLS_BASE][TLS_SW ] = ops[TLS_BASE][TLS_BASE]; -@@ -990,6 +991,7 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG], - - prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE]; - prot[TLS_SW][TLS_BASE].sendmsg = tls_sw_sendmsg; -+ prot[TLS_SW][TLS_BASE].splice_eof = tls_sw_splice_eof; - prot[TLS_SW][TLS_BASE].sendpage = tls_sw_sendpage; - - prot[TLS_BASE][TLS_SW] = prot[TLS_BASE][TLS_BASE]; -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 0323040d34bc6..c8cbdd02a784e 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -62,6 +62,7 @@ struct tls_decrypt_ctx { - u8 iv[MAX_IV_SIZE]; - u8 aad[TLS_MAX_AAD_SIZE]; - u8 tail; -+ bool free_sgout; - struct scatterlist sg[]; - }; - -@@ -186,7 +187,6 @@ static void tls_decrypt_done(crypto_completion_data_t *data, int err) - struct aead_request *aead_req = crypto_get_completion_data(data); - struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); - struct scatterlist *sgout = aead_req->dst; -- struct scatterlist *sgin = aead_req->src; - struct tls_sw_context_rx *ctx; - struct tls_decrypt_ctx *dctx; - struct tls_context *tls_ctx; -@@ -212,7 +212,7 @@ static void tls_decrypt_done(crypto_completion_data_t *data, int err) - } - - /* Free the destination pages if skb was not decrypted inplace */ -- if (sgout != sgin) { -+ if (dctx->free_sgout) { - /* Skip the first S/G entry as it points to AAD */ - for_each_sg(sg_next(sgout), sg, UINT_MAX, pages) { - if (!sg) -@@ -223,10 +223,17 @@ static void tls_decrypt_done(crypto_completion_data_t *data, int err) - - kfree(aead_req); - -- spin_lock_bh(&ctx->decrypt_compl_lock); -- if (!atomic_dec_return(&ctx->decrypt_pending)) -+ if (atomic_dec_and_test(&ctx->decrypt_pending)) - complete(&ctx->async_wait.completion); -- spin_unlock_bh(&ctx->decrypt_compl_lock); -+} -+ -+static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx) -+{ -+ if (!atomic_dec_and_test(&ctx->decrypt_pending)) -+ crypto_wait_req(-EINPROGRESS, &ctx->async_wait); -+ atomic_inc(&ctx->decrypt_pending); -+ -+ return ctx->async_wait.err; - } - - static int tls_do_decryption(struct sock *sk, -@@ -252,6 +259,7 @@ static int tls_do_decryption(struct sock *sk, - aead_request_set_callback(aead_req, - CRYPTO_TFM_REQ_MAY_BACKLOG, - tls_decrypt_done, aead_req); -+ DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->decrypt_pending) < 1); - atomic_inc(&ctx->decrypt_pending); - } else { - aead_request_set_callback(aead_req, -@@ -441,7 +449,6 @@ static void tls_encrypt_done(crypto_completion_data_t *data, int err) - struct tls_rec *rec; - bool ready = false; - struct sock *sk; -- int pending; - - rec = container_of(aead_req, struct tls_rec, aead_req); - msg_en = &rec->msg_encrypted; -@@ -481,12 +488,8 @@ static void tls_encrypt_done(crypto_completion_data_t *data, int err) - ready = true; - } - -- spin_lock_bh(&ctx->encrypt_compl_lock); -- pending = atomic_dec_return(&ctx->encrypt_pending); -- -- if (!pending && ctx->async_notify) -+ if (atomic_dec_and_test(&ctx->encrypt_pending)) - complete(&ctx->async_wait.completion); -- spin_unlock_bh(&ctx->encrypt_compl_lock); - - if (!ready) - return; -@@ -496,6 +499,15 @@ static void tls_encrypt_done(crypto_completion_data_t *data, int err) - schedule_delayed_work(&ctx->tx_work.work, 1); - } - -+static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx) -+{ -+ if (!atomic_dec_and_test(&ctx->encrypt_pending)) -+ crypto_wait_req(-EINPROGRESS, &ctx->async_wait); -+ atomic_inc(&ctx->encrypt_pending); -+ -+ return ctx->async_wait.err; -+} -+ - static int tls_do_encryption(struct sock *sk, - struct tls_context *tls_ctx, - struct tls_sw_context_tx *ctx, -@@ -542,6 +554,7 @@ static int tls_do_encryption(struct sock *sk, - - /* Add the record in tx_list */ - list_add_tail((struct list_head *)&rec->list, &ctx->tx_list); -+ DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->encrypt_pending) < 1); - atomic_inc(&ctx->encrypt_pending); - - rc = crypto_aead_encrypt(aead_req); -@@ -953,7 +966,6 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) - int num_zc = 0; - int orig_size; - int ret = 0; -- int pending; - - if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_CMSG_COMPAT)) -@@ -1122,24 +1134,12 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) - if (!num_async) { - goto send_end; - } else if (num_zc) { -- /* Wait for pending encryptions to get completed */ -- spin_lock_bh(&ctx->encrypt_compl_lock); -- ctx->async_notify = true; -- -- pending = atomic_read(&ctx->encrypt_pending); -- spin_unlock_bh(&ctx->encrypt_compl_lock); -- if (pending) -- crypto_wait_req(-EINPROGRESS, &ctx->async_wait); -- else -- reinit_completion(&ctx->async_wait.completion); -- -- /* There can be no concurrent accesses, since we have no -- * pending encrypt operations -- */ -- WRITE_ONCE(ctx->async_notify, false); -+ int err; - -- if (ctx->async_wait.err) { -- ret = ctx->async_wait.err; -+ /* Wait for pending encryptions to get completed */ -+ err = tls_encrypt_async_wait(ctx); -+ if (err) { -+ ret = err; - copied = 0; - } - } -@@ -1158,6 +1158,67 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) - return copied > 0 ? copied : ret; - } - -+/* -+ * Handle unexpected EOF during splice without SPLICE_F_MORE set. -+ */ -+void tls_sw_splice_eof(struct socket *sock) -+{ -+ struct sock *sk = sock->sk; -+ struct tls_context *tls_ctx = tls_get_ctx(sk); -+ struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); -+ struct tls_rec *rec; -+ struct sk_msg *msg_pl; -+ ssize_t copied = 0; -+ bool retrying = false; -+ int ret = 0; -+ -+ if (!ctx->open_rec) -+ return; -+ -+ mutex_lock(&tls_ctx->tx_lock); -+ lock_sock(sk); -+ -+retry: -+ /* same checks as in tls_sw_push_pending_record() */ -+ rec = ctx->open_rec; -+ if (!rec) -+ goto unlock; -+ -+ msg_pl = &rec->msg_plaintext; -+ if (msg_pl->sg.size == 0) -+ goto unlock; -+ -+ /* Check the BPF advisor and perform transmission. */ -+ ret = bpf_exec_tx_verdict(msg_pl, sk, false, TLS_RECORD_TYPE_DATA, -+ &copied, 0); -+ switch (ret) { -+ case 0: -+ case -EAGAIN: -+ if (retrying) -+ goto unlock; -+ retrying = true; -+ goto retry; -+ case -EINPROGRESS: -+ break; -+ default: -+ goto unlock; -+ } -+ -+ /* Wait for pending encryptions to get completed */ -+ if (tls_encrypt_async_wait(ctx)) -+ goto unlock; -+ -+ /* Transmit if any encryptions have completed */ -+ if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { -+ cancel_delayed_work(&ctx->tx_work.work); -+ tls_tx_records(sk, 0); -+ } -+ -+unlock: -+ release_sock(sk); -+ mutex_unlock(&tls_ctx->tx_lock); -+} -+ - static int tls_sw_do_sendpage(struct sock *sk, struct page *page, - int offset, size_t size, int flags) - { -@@ -1595,6 +1656,7 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov, - } else if (out_sg) { - memcpy(sgout, out_sg, n_sgout * sizeof(*sgout)); - } -+ dctx->free_sgout = !!pages; - - /* Prepare and submit AEAD request */ - err = tls_do_decryption(sk, sgin, sgout, dctx->iv, -@@ -2123,16 +2185,10 @@ int tls_sw_recvmsg(struct sock *sk, - - recv_end: - if (async) { -- int ret, pending; -+ int ret; - - /* Wait for all previously submitted records to be decrypted */ -- spin_lock_bh(&ctx->decrypt_compl_lock); -- reinit_completion(&ctx->async_wait.completion); -- pending = atomic_read(&ctx->decrypt_pending); -- spin_unlock_bh(&ctx->decrypt_compl_lock); -- ret = 0; -- if (pending) -- ret = crypto_wait_req(-EINPROGRESS, &ctx->async_wait); -+ ret = tls_decrypt_async_wait(ctx); - __skb_queue_purge(&ctx->async_hold); - - if (ret) { -@@ -2149,7 +2205,6 @@ int tls_sw_recvmsg(struct sock *sk, - else - err = process_rx_list(ctx, msg, &control, 0, - async_copy_bytes, is_peek); -- decrypted += max(err, 0); - } - - copied += decrypted; -@@ -2351,16 +2406,9 @@ void tls_sw_release_resources_tx(struct sock *sk) - struct tls_context *tls_ctx = tls_get_ctx(sk); - struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); - struct tls_rec *rec, *tmp; -- int pending; - - /* Wait for any pending async encryptions to complete */ -- spin_lock_bh(&ctx->encrypt_compl_lock); -- ctx->async_notify = true; -- pending = atomic_read(&ctx->encrypt_pending); -- spin_unlock_bh(&ctx->encrypt_compl_lock); -- -- if (pending) -- crypto_wait_req(-EINPROGRESS, &ctx->async_wait); -+ tls_encrypt_async_wait(ctx); - - tls_tx_records(sk, -1); - -@@ -2513,6 +2561,48 @@ void tls_update_rx_zc_capable(struct tls_context *tls_ctx) - tls_ctx->prot_info.version != TLS_1_3_VERSION; - } - -+static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct sock *sk) -+{ -+ struct tls_sw_context_tx *sw_ctx_tx; -+ -+ if (!ctx->priv_ctx_tx) { -+ sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); -+ if (!sw_ctx_tx) -+ return NULL; -+ } else { -+ sw_ctx_tx = ctx->priv_ctx_tx; -+ } -+ -+ crypto_init_wait(&sw_ctx_tx->async_wait); -+ atomic_set(&sw_ctx_tx->encrypt_pending, 1); -+ INIT_LIST_HEAD(&sw_ctx_tx->tx_list); -+ INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); -+ sw_ctx_tx->tx_work.sk = sk; -+ -+ return sw_ctx_tx; -+} -+ -+static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx) -+{ -+ struct tls_sw_context_rx *sw_ctx_rx; -+ -+ if (!ctx->priv_ctx_rx) { -+ sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); -+ if (!sw_ctx_rx) -+ return NULL; -+ } else { -+ sw_ctx_rx = ctx->priv_ctx_rx; -+ } -+ -+ crypto_init_wait(&sw_ctx_rx->async_wait); -+ atomic_set(&sw_ctx_rx->decrypt_pending, 1); -+ init_waitqueue_head(&sw_ctx_rx->wq); -+ skb_queue_head_init(&sw_ctx_rx->rx_list); -+ skb_queue_head_init(&sw_ctx_rx->async_hold); -+ -+ return sw_ctx_rx; -+} -+ - int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) - { - struct tls_context *tls_ctx = tls_get_ctx(sk); -@@ -2534,48 +2624,22 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) - } - - if (tx) { -- if (!ctx->priv_ctx_tx) { -- sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); -- if (!sw_ctx_tx) { -- rc = -ENOMEM; -- goto out; -- } -- ctx->priv_ctx_tx = sw_ctx_tx; -- } else { -- sw_ctx_tx = -- (struct tls_sw_context_tx *)ctx->priv_ctx_tx; -- } -- } else { -- if (!ctx->priv_ctx_rx) { -- sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); -- if (!sw_ctx_rx) { -- rc = -ENOMEM; -- goto out; -- } -- ctx->priv_ctx_rx = sw_ctx_rx; -- } else { -- sw_ctx_rx = -- (struct tls_sw_context_rx *)ctx->priv_ctx_rx; -- } -- } -+ ctx->priv_ctx_tx = init_ctx_tx(ctx, sk); -+ if (!ctx->priv_ctx_tx) -+ return -ENOMEM; - -- if (tx) { -- crypto_init_wait(&sw_ctx_tx->async_wait); -- spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); -+ sw_ctx_tx = ctx->priv_ctx_tx; - crypto_info = &ctx->crypto_send.info; - cctx = &ctx->tx; - aead = &sw_ctx_tx->aead_send; -- INIT_LIST_HEAD(&sw_ctx_tx->tx_list); -- INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); -- sw_ctx_tx->tx_work.sk = sk; - } else { -- crypto_init_wait(&sw_ctx_rx->async_wait); -- spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); -- init_waitqueue_head(&sw_ctx_rx->wq); -+ ctx->priv_ctx_rx = init_ctx_rx(ctx); -+ if (!ctx->priv_ctx_rx) -+ return -ENOMEM; -+ -+ sw_ctx_rx = ctx->priv_ctx_rx; - crypto_info = &ctx->crypto_recv.info; - cctx = &ctx->rx; -- skb_queue_head_init(&sw_ctx_rx->rx_list); -- skb_queue_head_init(&sw_ctx_rx->async_hold); - aead = &sw_ctx_rx->aead_recv; - } - -diff --git a/net/wireless/core.c b/net/wireless/core.c -index 8809e668ed912..3fcddc8687ed4 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -1671,6 +1671,7 @@ void wiphy_delayed_work_queue(struct wiphy *wiphy, - unsigned long delay) - { - if (!delay) { -+ del_timer(&dwork->timer); - wiphy_work_queue(wiphy, &dwork->work); - return; - } -diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c -index ac1a645afa8df..d0320e35accbf 100644 ---- a/net/xfrm/xfrm_input.c -+++ b/net/xfrm/xfrm_input.c -@@ -180,6 +180,8 @@ static int xfrm4_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb) - int optlen = 0; - int err = -EINVAL; - -+ skb->protocol = htons(ETH_P_IP); -+ - if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { - struct ip_beet_phdr *ph; - int phlen; -@@ -232,8 +234,7 @@ static int xfrm4_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb) - { - int err = -EINVAL; - -- if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) -- goto out; -+ skb->protocol = htons(ETH_P_IP); - - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - goto out; -@@ -270,8 +271,8 @@ static int xfrm6_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb) - { - int err = -EINVAL; - -- if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) -- goto out; -+ skb->protocol = htons(ETH_P_IPV6); -+ - if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) - goto out; - -@@ -301,6 +302,8 @@ static int xfrm6_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb) - int size = sizeof(struct ipv6hdr); - int err; - -+ skb->protocol = htons(ETH_P_IPV6); -+ - err = skb_cow_head(skb, size + skb->mac_len); - if (err) - goto out; -@@ -332,22 +335,26 @@ static int xfrm6_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb) - */ - static int - xfrm_inner_mode_encap_remove(struct xfrm_state *x, -- const struct xfrm_mode *inner_mode, - struct sk_buff *skb) - { -- switch (inner_mode->encap) { -+ switch (x->props.mode) { - case XFRM_MODE_BEET: -- if (inner_mode->family == AF_INET) -+ switch (x->sel.family) { -+ case AF_INET: - return xfrm4_remove_beet_encap(x, skb); -- if (inner_mode->family == AF_INET6) -+ case AF_INET6: - return xfrm6_remove_beet_encap(x, skb); -+ } - break; - case XFRM_MODE_TUNNEL: -- if (inner_mode->family == AF_INET) -+ switch (XFRM_MODE_SKB_CB(skb)->protocol) { -+ case IPPROTO_IPIP: - return xfrm4_remove_tunnel_encap(x, skb); -- if (inner_mode->family == AF_INET6) -+ case IPPROTO_IPV6: - return xfrm6_remove_tunnel_encap(x, skb); - break; -+ } -+ return -EINVAL; - } - - WARN_ON_ONCE(1); -@@ -356,9 +363,7 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x, - - static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) - { -- const struct xfrm_mode *inner_mode = &x->inner_mode; -- -- switch (x->outer_mode.family) { -+ switch (x->props.family) { - case AF_INET: - xfrm4_extract_header(skb); - break; -@@ -370,25 +375,7 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) - return -EAFNOSUPPORT; - } - -- if (x->sel.family == AF_UNSPEC) { -- inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); -- if (!inner_mode) -- return -EAFNOSUPPORT; -- } -- -- switch (inner_mode->family) { -- case AF_INET: -- skb->protocol = htons(ETH_P_IP); -- break; -- case AF_INET6: -- skb->protocol = htons(ETH_P_IPV6); -- break; -- default: -- WARN_ON_ONCE(1); -- break; -- } -- -- return xfrm_inner_mode_encap_remove(x, inner_mode, skb); -+ return xfrm_inner_mode_encap_remove(x, skb); - } - - /* Remove encapsulation header. -@@ -434,17 +421,16 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) - } - - static int xfrm_inner_mode_input(struct xfrm_state *x, -- const struct xfrm_mode *inner_mode, - struct sk_buff *skb) - { -- switch (inner_mode->encap) { -+ switch (x->props.mode) { - case XFRM_MODE_BEET: - case XFRM_MODE_TUNNEL: - return xfrm_prepare_input(x, skb); - case XFRM_MODE_TRANSPORT: -- if (inner_mode->family == AF_INET) -+ if (x->props.family == AF_INET) - return xfrm4_transport_input(x, skb); -- if (inner_mode->family == AF_INET6) -+ if (x->props.family == AF_INET6) - return xfrm6_transport_input(x, skb); - break; - case XFRM_MODE_ROUTEOPTIMIZATION: -@@ -462,7 +448,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) - { - const struct xfrm_state_afinfo *afinfo; - struct net *net = dev_net(skb->dev); -- const struct xfrm_mode *inner_mode; - int err; - __be32 seq; - __be32 seq_hi; -@@ -492,7 +477,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) - goto drop; - } - -- family = x->outer_mode.family; -+ family = x->props.family; - - /* An encap_type of -1 indicates async resumption. */ - if (encap_type == -1) { -@@ -676,17 +661,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) - - XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; - -- inner_mode = &x->inner_mode; -- -- if (x->sel.family == AF_UNSPEC) { -- inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); -- if (inner_mode == NULL) { -- XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); -- goto drop; -- } -- } -- -- if (xfrm_inner_mode_input(x, inner_mode, skb)) { -+ if (xfrm_inner_mode_input(x, skb)) { - XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); - goto drop; - } -@@ -701,7 +676,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) - * transport mode so the outer address is identical. - */ - daddr = &x->id.daddr; -- family = x->outer_mode.family; -+ family = x->props.family; - - err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); - if (err < 0) { -@@ -732,7 +707,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) - - err = -EAFNOSUPPORT; - rcu_read_lock(); -- afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode.family); -+ afinfo = xfrm_state_afinfo_get_rcu(x->props.family); - if (likely(afinfo)) - err = afinfo->transport_finish(skb, xfrm_gro || async); - rcu_read_unlock(); -diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c -index 9a5e79a38c679..07a7ee43b8ae2 100644 ---- a/net/xfrm/xfrm_output.c -+++ b/net/xfrm/xfrm_output.c -@@ -414,7 +414,7 @@ static int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) - IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; - skb->protocol = htons(ETH_P_IP); - -- switch (x->outer_mode.encap) { -+ switch (x->props.mode) { - case XFRM_MODE_BEET: - return xfrm4_beet_encap_add(x, skb); - case XFRM_MODE_TUNNEL: -@@ -437,7 +437,7 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) - skb->ignore_df = 1; - skb->protocol = htons(ETH_P_IPV6); - -- switch (x->outer_mode.encap) { -+ switch (x->props.mode) { - case XFRM_MODE_BEET: - return xfrm6_beet_encap_add(x, skb); - case XFRM_MODE_TUNNEL: -@@ -453,22 +453,22 @@ static int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) - - static int xfrm_outer_mode_output(struct xfrm_state *x, struct sk_buff *skb) - { -- switch (x->outer_mode.encap) { -+ switch (x->props.mode) { - case XFRM_MODE_BEET: - case XFRM_MODE_TUNNEL: -- if (x->outer_mode.family == AF_INET) -+ if (x->props.family == AF_INET) - return xfrm4_prepare_output(x, skb); -- if (x->outer_mode.family == AF_INET6) -+ if (x->props.family == AF_INET6) - return xfrm6_prepare_output(x, skb); - break; - case XFRM_MODE_TRANSPORT: -- if (x->outer_mode.family == AF_INET) -+ if (x->props.family == AF_INET) - return xfrm4_transport_output(x, skb); -- if (x->outer_mode.family == AF_INET6) -+ if (x->props.family == AF_INET6) - return xfrm6_transport_output(x, skb); - break; - case XFRM_MODE_ROUTEOPTIMIZATION: -- if (x->outer_mode.family == AF_INET6) -+ if (x->props.family == AF_INET6) - return xfrm6_ro_output(x, skb); - WARN_ON_ONCE(1); - break; -@@ -866,21 +866,10 @@ static int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb) - - static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) - { -- const struct xfrm_mode *inner_mode; -- -- if (x->sel.family == AF_UNSPEC) -- inner_mode = xfrm_ip2inner_mode(x, -- xfrm_af2proto(skb_dst(skb)->ops->family)); -- else -- inner_mode = &x->inner_mode; -- -- if (inner_mode == NULL) -- return -EAFNOSUPPORT; -- -- switch (inner_mode->family) { -- case AF_INET: -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): - return xfrm4_extract_output(x, skb); -- case AF_INET6: -+ case htons(ETH_P_IPV6): - return xfrm6_extract_output(x, skb); - } - -diff --git a/samples/bpf/asm_goto_workaround.h b/samples/bpf/asm_goto_workaround.h -index 7048bb3594d65..634e81d83efd9 100644 ---- a/samples/bpf/asm_goto_workaround.h -+++ b/samples/bpf/asm_goto_workaround.h -@@ -4,14 +4,14 @@ - #define __ASM_GOTO_WORKAROUND_H - - /* -- * This will bring in asm_volatile_goto and asm_inline macro definitions -+ * This will bring in asm_goto_output and asm_inline macro definitions - * if enabled by compiler and config options. - */ - #include - --#ifdef asm_volatile_goto --#undef asm_volatile_goto --#define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto") -+#ifdef asm_goto_output -+#undef asm_goto_output -+#define asm_goto_output(x...) asm volatile("invalid use of asm_goto_output") - #endif - - /* -diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost -index e41dee64d429c..39aea753d0bdc 100644 ---- a/scripts/Makefile.modpost -+++ b/scripts/Makefile.modpost -@@ -44,6 +44,7 @@ modpost-args = \ - $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ - $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ -+ $(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \ - -o $@ - - # 'make -i -k' ignores compile errors, and builds as many modules as possible. -diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl -index 1e5e66ae5a522..ecf4250b0d2d2 100755 ---- a/scripts/checkpatch.pl -+++ b/scripts/checkpatch.pl -@@ -4971,7 +4971,7 @@ sub process { - if|for|while|switch|return|case| - volatile|__volatile__| - __attribute__|format|__extension__| -- asm|__asm__)$/x) -+ asm|__asm__|scoped_guard)$/x) - { - # cpp #define statements have non-optional spaces, ie - # if there is a space between the name and the open -diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh -index 32e573943cf03..458b2948b580d 100755 ---- a/scripts/link-vmlinux.sh -+++ b/scripts/link-vmlinux.sh -@@ -135,8 +135,13 @@ gen_btf() - ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \ - --strip-all ${1} ${2} 2>/dev/null - # Change e_type to ET_REL so that it can be used to link final vmlinux. -- # Unlike GNU ld, lld does not allow an ET_EXEC input. -- printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none -+ # GNU ld 2.35+ and lld do not allow an ET_EXEC input. -+ if is_enabled CONFIG_CPU_BIG_ENDIAN; then -+ et_rel='\0\1' -+ else -+ et_rel='\1\0' -+ fi -+ printf "${et_rel}" | dd of=${2} conv=notrunc bs=1 seek=16 status=none - } - - # Create ${2} .S file with all symbols from the ${1} object file -diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c -index e6be7fc2625fd..686eed37f9781 100644 ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -41,6 +41,8 @@ static bool allow_missing_ns_imports; - - static bool error_occurred; - -+static bool extra_warn; -+ - /* - * Cut off the warnings when there are too many. This typically occurs when - * vmlinux is missing. ('make modules' without building vmlinux.) -@@ -809,7 +811,7 @@ static void check_section(const char *modname, struct elf_info *elf, - #define ALL_INIT_TEXT_SECTIONS \ - ".init.text", ".meminit.text" - #define ALL_EXIT_TEXT_SECTIONS \ -- ".exit.text", ".memexit.text" -+ ".exit.text" - - #define ALL_PCI_INIT_SECTIONS \ - ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ -@@ -817,23 +819,22 @@ static void check_section(const char *modname, struct elf_info *elf, - ".pci_fixup_resume_early", ".pci_fixup_suspend" - - #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS --#define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS - - #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS --#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS -+#define ALL_EXIT_SECTIONS EXIT_SECTIONS - - #define DATA_SECTIONS ".data", ".data.rel" --#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \ -- ".kprobes.text", ".cpuidle.text", ".noinstr.text" -+#define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \ -+ ".kprobes.text", ".cpuidle.text", ".noinstr.text", \ -+ ".ltext", ".ltext.*" - #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ -- ".fixup", ".entry.text", ".exception.text", ".text.*", \ -+ ".fixup", ".entry.text", ".exception.text", \ - ".coldtext", ".softirqentry.text" - - #define INIT_SECTIONS ".init.*" - #define MEM_INIT_SECTIONS ".meminit.*" - - #define EXIT_SECTIONS ".exit.*" --#define MEM_EXIT_SECTIONS ".memexit.*" - - #define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \ - TEXT_SECTIONS, OTHER_TEXT_SECTIONS -@@ -862,7 +863,6 @@ enum mismatch { - TEXT_TO_ANY_EXIT, - DATA_TO_ANY_EXIT, - XXXINIT_TO_SOME_INIT, -- XXXEXIT_TO_SOME_EXIT, - ANY_INIT_TO_ANY_EXIT, - ANY_EXIT_TO_ANY_INIT, - EXPORT_TO_INIT_EXIT, -@@ -937,12 +937,6 @@ static const struct sectioncheck sectioncheck[] = { - .bad_tosec = { INIT_SECTIONS, NULL }, - .mismatch = XXXINIT_TO_SOME_INIT, - }, --/* Do not reference exit code/data from memexit code/data */ --{ -- .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, -- .bad_tosec = { EXIT_SECTIONS, NULL }, -- .mismatch = XXXEXIT_TO_SOME_EXIT, --}, - /* Do not use exit code/data from init code */ - { - .fromsec = { ALL_INIT_SECTIONS, NULL }, -@@ -1085,9 +1079,20 @@ static int secref_whitelist(const struct sectioncheck *mismatch, - "*_console"))) - return 0; - -- /* symbols in data sections that may refer to meminit/exit sections */ -+ /* symbols in data sections that may refer to meminit sections */ - if (match(fromsec, PATTERNS(DATA_SECTIONS)) && -- match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_EXIT_SECTIONS)) && -+ match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS)) && -+ match(fromsym, PATTERNS("*driver"))) -+ return 0; -+ -+ /* -+ * symbols in data sections must not refer to .exit.*, but there are -+ * quite a few offenders, so hide these unless for W=1 builds until -+ * these are fixed. -+ */ -+ if (!extra_warn && -+ match(fromsec, PATTERNS(DATA_SECTIONS)) && -+ match(tosec, PATTERNS(EXIT_SECTIONS)) && - match(fromsym, PATTERNS("*driver"))) - return 0; - -@@ -1254,7 +1259,6 @@ static void report_sec_mismatch(const char *modname, - case TEXT_TO_ANY_EXIT: - case DATA_TO_ANY_EXIT: - case XXXINIT_TO_SOME_INIT: -- case XXXEXIT_TO_SOME_EXIT: - case ANY_INIT_TO_ANY_EXIT: - case ANY_EXIT_TO_ANY_INIT: - warn("%s: section mismatch in reference: %s (section: %s) -> %s (section: %s)\n", -@@ -2290,7 +2294,7 @@ int main(int argc, char **argv) - LIST_HEAD(dump_lists); - struct dump_list *dl, *dl2; - -- while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { -+ while ((opt = getopt(argc, argv, "ei:mnT:o:aWwENd:")) != -1) { - switch (opt) { - case 'e': - external_module = true; -@@ -2315,6 +2319,9 @@ int main(int argc, char **argv) - case 'T': - files_source = optarg; - break; -+ case 'W': -+ extra_warn = true; -+ break; - case 'w': - warn_unresolved = true; - break; -diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c -index 6bf9caca09684..a72e6cf61a1f0 100644 ---- a/scripts/mod/sumversion.c -+++ b/scripts/mod/sumversion.c -@@ -326,7 +326,12 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) - - /* Sum all files in the same dir or subdirs. */ - while ((line = get_line(&pos))) { -- char* p = line; -+ char* p; -+ -+ /* trim the leading spaces away */ -+ while (isspace(*line)) -+ line++; -+ p = line; - - if (strncmp(line, "source_", sizeof("source_")-1) == 0) { - p = strrchr(line, ' '); -diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h -index f42359f58eb58..d468c8b90298d 100644 ---- a/security/apparmor/include/lib.h -+++ b/security/apparmor/include/lib.h -@@ -226,7 +226,7 @@ void aa_policy_destroy(struct aa_policy *policy); - */ - #define fn_label_build(L, P, GFP, FN) \ - ({ \ -- __label__ __cleanup, __done; \ -+ __label__ __do_cleanup, __done; \ - struct aa_label *__new_; \ - \ - if ((L)->size > 1) { \ -@@ -244,7 +244,7 @@ void aa_policy_destroy(struct aa_policy *policy); - __new_ = (FN); \ - AA_BUG(!__new_); \ - if (IS_ERR(__new_)) \ -- goto __cleanup; \ -+ goto __do_cleanup; \ - __lvec[__j++] = __new_; \ - } \ - for (__j = __count = 0; __j < (L)->size; __j++) \ -@@ -266,7 +266,7 @@ void aa_policy_destroy(struct aa_policy *policy); - vec_cleanup(profile, __pvec, __count); \ - } else \ - __new_ = NULL; \ --__cleanup: \ -+__do_cleanup: \ - vec_cleanup(label, __lvec, (L)->size); \ - } else { \ - (P) = labels_profile(L); \ -diff --git a/security/security.c b/security/security.c -index fc15b963e1028..1b504c296551c 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -2186,7 +2186,19 @@ EXPORT_SYMBOL(security_inode_setsecctx); - - int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) - { -- return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); -+ struct security_hook_list *hp; -+ int rc; -+ -+ /* -+ * Only one module will provide a security context. -+ */ -+ hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) { -+ rc = hp->hook.inode_getsecctx(inode, ctx, ctxlen); -+ if (rc != LSM_RET_DEFAULT(inode_getsecctx)) -+ return rc; -+ } -+ -+ return LSM_RET_DEFAULT(inode_getsecctx); - } - EXPORT_SYMBOL(security_inode_getsecctx); - -diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c -index e8819e8a98763..e8209178d87bb 100644 ---- a/sound/pci/hda/patch_conexant.c -+++ b/sound/pci/hda/patch_conexant.c -@@ -344,6 +344,7 @@ enum { - CXT_FIXUP_HP_ZBOOK_MUTE_LED, - CXT_FIXUP_HEADSET_MIC, - CXT_FIXUP_HP_MIC_NO_PRESENCE, -+ CXT_PINCFG_SWS_JS201D, - }; - - /* for hda_fixup_thinkpad_acpi() */ -@@ -841,6 +842,17 @@ static const struct hda_pintbl cxt_pincfg_lemote[] = { - {} - }; - -+/* SuoWoSi/South-holding JS201D with sn6140 */ -+static const struct hda_pintbl cxt_pincfg_sws_js201d[] = { -+ { 0x16, 0x03211040 }, /* hp out */ -+ { 0x17, 0x91170110 }, /* SPK/Class_D */ -+ { 0x18, 0x95a70130 }, /* Internal mic */ -+ { 0x19, 0x03a11020 }, /* Headset Mic */ -+ { 0x1a, 0x40f001f0 }, /* Not used */ -+ { 0x21, 0x40f001f0 }, /* Not used */ -+ {} -+}; -+ - static const struct hda_fixup cxt_fixups[] = { - [CXT_PINCFG_LENOVO_X200] = { - .type = HDA_FIXUP_PINS, -@@ -996,6 +1008,10 @@ static const struct hda_fixup cxt_fixups[] = { - .chained = true, - .chain_id = CXT_FIXUP_HEADSET_MIC, - }, -+ [CXT_PINCFG_SWS_JS201D] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = cxt_pincfg_sws_js201d, -+ }, - }; - - static const struct snd_pci_quirk cxt5045_fixups[] = { -@@ -1069,6 +1085,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { - SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), -+ SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D), - SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), - SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), -@@ -1109,6 +1126,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { - { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, - { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, - { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, -+ { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, - {} - }; - -diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c -index 627899959ffe8..e41316e2e9833 100644 ---- a/sound/pci/hda/patch_cs8409.c -+++ b/sound/pci/hda/patch_cs8409.c -@@ -1371,6 +1371,7 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac - spec->scodecs[CS8409_CODEC1] = &dolphin_cs42l42_1; - spec->scodecs[CS8409_CODEC1]->codec = codec; - spec->num_scodecs = 2; -+ spec->gen.suppress_vmaster = 1; - - codec->patch_ops = cs8409_dolphin_patch_ops; - -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 62f2137044923..92a656fb53212 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9377,7 +9377,7 @@ static const struct hda_fixup alc269_fixups[] = { - .type = HDA_FIXUP_FUNC, - .v.func = cs35l41_fixup_i2c_two, - .chained = true, -- .chain_id = ALC269_FIXUP_THINKPAD_ACPI, -+ .chain_id = ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, - }, - [ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = { - .type = HDA_FIXUP_FUNC, -@@ -9392,6 +9392,8 @@ static const struct hda_fixup alc269_fixups[] = { - [ALC287_FIXUP_THINKPAD_I2S_SPK] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc287_fixup_bind_dacs, -+ .chained = true, -+ .chain_id = ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, - }, - [ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD] = { - .type = HDA_FIXUP_FUNC, -@@ -9431,6 +9433,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS), - SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1025, 0x1269, "Acer SWIFT SF314-54", ALC256_FIXUP_ACER_HEADSET_MIC), -+ SND_PCI_QUIRK(0x1025, 0x126a, "Acer Swift SF114-32", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), - SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), - SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), -@@ -9617,6 +9620,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8786, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x8787, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), -+ SND_PCI_QUIRK(0x103c, 0x87b7, "HP Laptop 14-fq0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), -@@ -9686,6 +9690,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -@@ -9693,6 +9698,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8b45, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b46, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8b59, "HP Elite mt645 G7 Mobile Thin Client U89", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b63, "HP Elite Dragonfly 13.5 inch G4", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), -@@ -9722,6 +9728,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - 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, 0x8c97, "HP ZBook", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), -+ SND_PCI_QUIRK(0x103c, 0x8ca1, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8ca2, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED), - 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), -@@ -10049,6 +10057,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), - SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), -+ SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME), - SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), - SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), - SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 808d002826233..28da4e1858d7e 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -241,6 +241,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "82YM"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "83AS"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -@@ -297,6 +304,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7VF"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index fd3dca08460ba..844d14d4c9a51 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -3288,6 +3288,7 @@ static void rt5645_jack_detect_work(struct work_struct *work) - report, SND_JACK_HEADPHONE); - snd_soc_jack_report(rt5645->mic_jack, - report, SND_JACK_MICROPHONE); -+ mutex_unlock(&rt5645->jd_mutex); - return; - case 4: - val = snd_soc_component_read(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; -diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c -index a2abd1a111612..e80be4e4fa8b4 100644 ---- a/sound/soc/codecs/wcd938x.c -+++ b/sound/soc/codecs/wcd938x.c -@@ -3588,7 +3588,7 @@ static int wcd938x_probe(struct platform_device *pdev) - ret = wcd938x_populate_dt_data(wcd938x, dev); - if (ret) { - dev_err(dev, "%s: Fail to obtain platform data\n", __func__); -- return -EINVAL; -+ return ret; - } - - ret = wcd938x_add_slave_components(wcd938x, dev, &match); -diff --git a/tools/arch/x86/include/asm/rmwcc.h b/tools/arch/x86/include/asm/rmwcc.h -index 11ff975242cac..e2ff22b379a44 100644 ---- a/tools/arch/x86/include/asm/rmwcc.h -+++ b/tools/arch/x86/include/asm/rmwcc.h -@@ -4,7 +4,7 @@ - - #define __GEN_RMWcc(fullop, var, cc, ...) \ - do { \ -- asm_volatile_goto (fullop "; j" cc " %l[cc_label]" \ -+ asm goto (fullop "; j" cc " %l[cc_label]" \ - : : "m" (var), ## __VA_ARGS__ \ - : "memory" : cc_label); \ - return 0; \ -diff --git a/tools/include/linux/compiler_types.h b/tools/include/linux/compiler_types.h -index 1bdd834bdd571..d09f9dc172a48 100644 ---- a/tools/include/linux/compiler_types.h -+++ b/tools/include/linux/compiler_types.h -@@ -36,8 +36,8 @@ - #include - #endif - --#ifndef asm_volatile_goto --#define asm_volatile_goto(x...) asm goto(x) -+#ifndef asm_goto_output -+#define asm_goto_output(x...) asm goto(x) - #endif - - #endif /* __LINUX_COMPILER_TYPES_H */ -diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh -index 7bf56ea161e35..616d3581419ca 100755 ---- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh -+++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh -@@ -11,7 +11,7 @@ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \ - multiple_masks_test ctcam_edge_cases_test delta_simple_test \ - delta_two_masks_one_key_test delta_simple_rehash_test \ - bloom_simple_test bloom_complex_test bloom_delta_test \ -- max_erp_entries_test" -+ max_erp_entries_test max_group_size_test" - NUM_NETIFS=2 - source $lib_dir/lib.sh - source $lib_dir/tc_common.sh -@@ -1033,6 +1033,60 @@ max_erp_entries_test() - "max chain $chain_failed, mask $mask_failed" - } - -+max_group_size_test() -+{ -+ # The number of ACLs in an ACL group is limited. Once the maximum -+ # number of ACLs has been reached, filters cannot be added. This test -+ # verifies that when this limit is reached, insertion fails without -+ # crashing. -+ -+ RET=0 -+ -+ local num_acls=32 -+ local max_size -+ local ret -+ -+ if [[ "$tcflags" != "skip_sw" ]]; then -+ return 0; -+ fi -+ -+ for ((i=1; i < $num_acls; i++)); do -+ if [[ $(( i % 2 )) == 1 ]]; then -+ tc filter add dev $h2 ingress pref $i proto ipv4 \ -+ flower $tcflags dst_ip 198.51.100.1/32 \ -+ ip_proto tcp tcp_flags 0x01/0x01 \ -+ action drop &> /dev/null -+ else -+ tc filter add dev $h2 ingress pref $i proto ipv6 \ -+ flower $tcflags dst_ip 2001:db8:1::1/128 \ -+ action drop &> /dev/null -+ fi -+ -+ ret=$? -+ [[ $ret -ne 0 ]] && max_size=$((i - 1)) && break -+ done -+ -+ # We expect to exceed the maximum number of ACLs in a group, so that -+ # insertion eventually fails. Otherwise, the test should be adjusted to -+ # add more filters. -+ check_fail $ret "expected to exceed number of ACLs in a group" -+ -+ for ((; i >= 1; i--)); do -+ if [[ $(( i % 2 )) == 1 ]]; then -+ tc filter del dev $h2 ingress pref $i proto ipv4 \ -+ flower $tcflags dst_ip 198.51.100.1/32 \ -+ ip_proto tcp tcp_flags 0x01/0x01 \ -+ action drop &> /dev/null -+ else -+ tc filter del dev $h2 ingress pref $i proto ipv6 \ -+ flower $tcflags dst_ip 2001:db8:1::1/128 \ -+ action drop &> /dev/null -+ fi -+ done -+ -+ log_test "max ACL group size test ($tcflags). max size $max_size" -+} -+ - setup_prepare() - { - h1=${NETIFS[p1]} -diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c -index b5234d6efbe15..ec40a33c29fda 100644 ---- a/tools/testing/selftests/kvm/dirty_log_test.c -+++ b/tools/testing/selftests/kvm/dirty_log_test.c -@@ -226,13 +226,15 @@ static void clear_log_create_vm_done(struct kvm_vm *vm) - } - - static void dirty_log_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot, -- void *bitmap, uint32_t num_pages) -+ void *bitmap, uint32_t num_pages, -+ uint32_t *unused) - { - kvm_vm_get_dirty_log(vcpu->vm, slot, bitmap); - } - - static void clear_log_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot, -- void *bitmap, uint32_t num_pages) -+ void *bitmap, uint32_t num_pages, -+ uint32_t *unused) - { - kvm_vm_get_dirty_log(vcpu->vm, slot, bitmap); - kvm_vm_clear_dirty_log(vcpu->vm, slot, bitmap, 0, num_pages); -@@ -329,10 +331,9 @@ static void dirty_ring_continue_vcpu(void) - } - - static void dirty_ring_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot, -- void *bitmap, uint32_t num_pages) -+ void *bitmap, uint32_t num_pages, -+ uint32_t *ring_buf_idx) - { -- /* We only have one vcpu */ -- static uint32_t fetch_index = 0; - uint32_t count = 0, cleared; - bool continued_vcpu = false; - -@@ -349,11 +350,15 @@ static void dirty_ring_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot, - - /* Only have one vcpu */ - count = dirty_ring_collect_one(vcpu_map_dirty_ring(vcpu), -- slot, bitmap, num_pages, &fetch_index); -+ slot, bitmap, num_pages, -+ ring_buf_idx); - - cleared = kvm_vm_reset_dirty_ring(vcpu->vm); - -- /* Cleared pages should be the same as collected */ -+ /* -+ * Cleared pages should be the same as collected, as KVM is supposed to -+ * clear only the entries that have been harvested. -+ */ - TEST_ASSERT(cleared == count, "Reset dirty pages (%u) mismatch " - "with collected (%u)", cleared, count); - -@@ -392,12 +397,6 @@ static void dirty_ring_after_vcpu_run(struct kvm_vcpu *vcpu, int ret, int err) - } - } - --static void dirty_ring_before_vcpu_join(void) --{ -- /* Kick another round of vcpu just to make sure it will quit */ -- sem_post(&sem_vcpu_cont); --} -- - struct log_mode { - const char *name; - /* Return true if this mode is supported, otherwise false */ -@@ -406,10 +405,10 @@ struct log_mode { - void (*create_vm_done)(struct kvm_vm *vm); - /* Hook to collect the dirty pages into the bitmap provided */ - void (*collect_dirty_pages) (struct kvm_vcpu *vcpu, int slot, -- void *bitmap, uint32_t num_pages); -+ void *bitmap, uint32_t num_pages, -+ uint32_t *ring_buf_idx); - /* Hook to call when after each vcpu run */ - void (*after_vcpu_run)(struct kvm_vcpu *vcpu, int ret, int err); -- void (*before_vcpu_join) (void); - } log_modes[LOG_MODE_NUM] = { - { - .name = "dirty-log", -@@ -428,7 +427,6 @@ struct log_mode { - .supported = dirty_ring_supported, - .create_vm_done = dirty_ring_create_vm_done, - .collect_dirty_pages = dirty_ring_collect_dirty_pages, -- .before_vcpu_join = dirty_ring_before_vcpu_join, - .after_vcpu_run = dirty_ring_after_vcpu_run, - }, - }; -@@ -471,13 +469,14 @@ static void log_mode_create_vm_done(struct kvm_vm *vm) - } - - static void log_mode_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot, -- void *bitmap, uint32_t num_pages) -+ void *bitmap, uint32_t num_pages, -+ uint32_t *ring_buf_idx) - { - struct log_mode *mode = &log_modes[host_log_mode]; - - TEST_ASSERT(mode->collect_dirty_pages != NULL, - "collect_dirty_pages() is required for any log mode!"); -- mode->collect_dirty_pages(vcpu, slot, bitmap, num_pages); -+ mode->collect_dirty_pages(vcpu, slot, bitmap, num_pages, ring_buf_idx); - } - - static void log_mode_after_vcpu_run(struct kvm_vcpu *vcpu, int ret, int err) -@@ -488,14 +487,6 @@ static void log_mode_after_vcpu_run(struct kvm_vcpu *vcpu, int ret, int err) - mode->after_vcpu_run(vcpu, ret, err); - } - --static void log_mode_before_vcpu_join(void) --{ -- struct log_mode *mode = &log_modes[host_log_mode]; -- -- if (mode->before_vcpu_join) -- mode->before_vcpu_join(); --} -- - static void generate_random_array(uint64_t *guest_array, uint64_t size) - { - uint64_t i; -@@ -696,6 +687,8 @@ static void run_test(enum vm_guest_mode mode, void *arg) - struct kvm_vcpu *vcpu; - struct kvm_vm *vm; - unsigned long *bmap; -+ uint32_t ring_buf_idx = 0; -+ int sem_val; - - if (!log_mode_supported()) { - print_skip("Log mode '%s' not supported", -@@ -767,10 +760,21 @@ static void run_test(enum vm_guest_mode mode, void *arg) - /* Start the iterations */ - iteration = 1; - sync_global_to_guest(vm, iteration); -- host_quit = false; -+ WRITE_ONCE(host_quit, false); - host_dirty_count = 0; - host_clear_count = 0; - host_track_next_count = 0; -+ WRITE_ONCE(dirty_ring_vcpu_ring_full, false); -+ -+ /* -+ * Ensure the previous iteration didn't leave a dangling semaphore, i.e. -+ * that the main task and vCPU worker were synchronized and completed -+ * verification of all iterations. -+ */ -+ sem_getvalue(&sem_vcpu_stop, &sem_val); -+ TEST_ASSERT_EQ(sem_val, 0); -+ sem_getvalue(&sem_vcpu_cont, &sem_val); -+ TEST_ASSERT_EQ(sem_val, 0); - - pthread_create(&vcpu_thread, NULL, vcpu_worker, vcpu); - -@@ -778,7 +782,8 @@ static void run_test(enum vm_guest_mode mode, void *arg) - /* Give the vcpu thread some time to dirty some pages */ - usleep(p->interval * 1000); - log_mode_collect_dirty_pages(vcpu, TEST_MEM_SLOT_INDEX, -- bmap, host_num_pages); -+ bmap, host_num_pages, -+ &ring_buf_idx); - - /* - * See vcpu_sync_stop_requested definition for details on why -@@ -796,15 +801,21 @@ static void run_test(enum vm_guest_mode mode, void *arg) - assert(host_log_mode == LOG_MODE_DIRTY_RING || - atomic_read(&vcpu_sync_stop_requested) == false); - vm_dirty_log_verify(mode, bmap); -- sem_post(&sem_vcpu_cont); - -- iteration++; -+ /* -+ * Set host_quit before sem_vcpu_cont in the final iteration to -+ * ensure that the vCPU worker doesn't resume the guest. As -+ * above, the dirty ring test may stop and wait even when not -+ * explicitly request to do so, i.e. would hang waiting for a -+ * "continue" if it's allowed to resume the guest. -+ */ -+ if (++iteration == p->iterations) -+ WRITE_ONCE(host_quit, true); -+ -+ sem_post(&sem_vcpu_cont); - sync_global_to_guest(vm, iteration); - } - -- /* Tell the vcpu thread to quit */ -- host_quit = true; -- log_mode_before_vcpu_join(); - pthread_join(vcpu_thread, NULL); - - pr_info("Total bits checked: dirty (%"PRIu64"), clear (%"PRIu64"), " -diff --git a/tools/testing/selftests/net/mptcp/config b/tools/testing/selftests/net/mptcp/config -index e317c2e44dae8..4f80014cae494 100644 ---- a/tools/testing/selftests/net/mptcp/config -+++ b/tools/testing/selftests/net/mptcp/config -@@ -22,8 +22,11 @@ CONFIG_NFT_TPROXY=m - CONFIG_NFT_SOCKET=m - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_MANGLE=m - CONFIG_IP_NF_TARGET_REJECT=m - CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IP6_NF_FILTER=m - CONFIG_NET_ACT_CSUM=m - CONFIG_NET_ACT_PEDIT=m - CONFIG_NET_CLS_ACT=y -diff --git a/tools/testing/selftests/net/mptcp/settings b/tools/testing/selftests/net/mptcp/settings -index 79b65bdf05db6..abc5648b59abd 100644 ---- a/tools/testing/selftests/net/mptcp/settings -+++ b/tools/testing/selftests/net/mptcp/settings -@@ -1 +1 @@ --timeout=1200 -+timeout=1800 -diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c -index 0d85be2350fa3..a811659307855 100644 ---- a/tools/testing/selftests/vm/ksm_tests.c -+++ b/tools/testing/selftests/vm/ksm_tests.c -@@ -470,7 +470,7 @@ static int ksm_merge_hugepages_time(int mapping, int prot, int timeout, size_t m - if (map_ptr_orig == MAP_FAILED) - err(2, "initial mmap"); - -- if (madvise(map_ptr, len + HPAGE_SIZE, MADV_HUGEPAGE)) -+ if (madvise(map_ptr, len, MADV_HUGEPAGE)) - err(2, "MADV_HUGEPAGE"); - - pagemap_fd = open("/proc/self/pagemap", O_RDONLY); -diff --git a/tools/testing/selftests/vm/va_128TBswitch.sh b/tools/testing/selftests/vm/va_128TBswitch.sh -index 41580751dc511..231622b3a2327 100755 ---- a/tools/testing/selftests/vm/va_128TBswitch.sh -+++ b/tools/testing/selftests/vm/va_128TBswitch.sh -@@ -29,9 +29,15 @@ check_supported_x86_64() - # See man 1 gzip under '-f'. - local pg_table_levels=$(gzip -dcfq "${config}" | grep PGTABLE_LEVELS | cut -d'=' -f 2) - -+ local cpu_supports_pl5=$(awk '/^flags/ {if (/la57/) {print 0;} -+ else {print 1}; exit}' /proc/cpuinfo 2>/dev/null) -+ - if [[ "${pg_table_levels}" -lt 5 ]]; then - echo "$0: PGTABLE_LEVELS=${pg_table_levels}, must be >= 5 to run this test" - exit $ksft_skip -+ elif [[ "${cpu_supports_pl5}" -ne 0 ]]; then -+ echo "$0: CPU does not have the necessary la57 flag to support page table level 5" -+ exit $ksft_skip - fi - } - -diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile -index 22e28b76f8004..6912e9577b658 100644 ---- a/tools/tracing/rtla/Makefile -+++ b/tools/tracing/rtla/Makefile -@@ -28,10 +28,15 @@ FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \ - -fasynchronous-unwind-tables -fstack-clash-protection - WOPTS := -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized - -+ifeq ($(CC),clang) -+ FOPTS := $(filter-out -ffat-lto-objects, $(FOPTS)) -+ WOPTS := $(filter-out -Wno-maybe-uninitialized, $(WOPTS)) -+endif -+ - TRACEFS_HEADERS := $$($(PKG_CONFIG) --cflags libtracefs) - - CFLAGS := -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS) $(EXTRA_CFLAGS) --LDFLAGS := -ggdb $(EXTRA_LDFLAGS) -+LDFLAGS := -flto=auto -ggdb $(EXTRA_LDFLAGS) - LIBS := $$($(PKG_CONFIG) --libs libtracefs) - - SRC := $(wildcard src/*.c) -diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c -index fe34452fc4ec0..b9658f213cb55 100644 ---- a/tools/tracing/rtla/src/osnoise_hist.c -+++ b/tools/tracing/rtla/src/osnoise_hist.c -@@ -129,8 +129,7 @@ static void osnoise_hist_update_multiple(struct osnoise_tool *tool, int cpu, - if (params->output_divisor) - duration = duration / params->output_divisor; - -- if (data->bucket_size) -- bucket = duration / data->bucket_size; -+ bucket = duration / data->bucket_size; - - total_duration = duration * count; - -@@ -472,7 +471,11 @@ static void osnoise_hist_usage(char *usage) - - for (i = 0; msg[i]; i++) - fprintf(stderr, "%s\n", msg[i]); -- exit(1); -+ -+ if (usage) -+ exit(EXIT_FAILURE); -+ -+ exit(EXIT_SUCCESS); - } - - /* -diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c -index 76479bfb29224..6c07f360de72c 100644 ---- a/tools/tracing/rtla/src/osnoise_top.c -+++ b/tools/tracing/rtla/src/osnoise_top.c -@@ -282,7 +282,11 @@ void osnoise_top_usage(char *usage) - - for (i = 0; msg[i]; i++) - fprintf(stderr, "%s\n", msg[i]); -- exit(1); -+ -+ if (usage) -+ exit(EXIT_FAILURE); -+ -+ exit(EXIT_SUCCESS); - } - - /* -diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c -index 4b48af8a83096..ed08295bfa12c 100644 ---- a/tools/tracing/rtla/src/timerlat_hist.c -+++ b/tools/tracing/rtla/src/timerlat_hist.c -@@ -151,8 +151,7 @@ timerlat_hist_update(struct osnoise_tool *tool, int cpu, - if (params->output_divisor) - latency = latency / params->output_divisor; - -- if (data->bucket_size) -- bucket = latency / data->bucket_size; -+ bucket = latency / data->bucket_size; - - if (!thread) { - hist = data->hist[cpu].irq; -@@ -475,7 +474,11 @@ static void timerlat_hist_usage(char *usage) - - for (i = 0; msg[i]; i++) - fprintf(stderr, "%s\n", msg[i]); -- exit(1); -+ -+ if (usage) -+ exit(EXIT_FAILURE); -+ -+ exit(EXIT_SUCCESS); - } - - /* -diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c -index 3342719352222..8fc0f6aa19dad 100644 ---- a/tools/tracing/rtla/src/timerlat_top.c -+++ b/tools/tracing/rtla/src/timerlat_top.c -@@ -305,7 +305,11 @@ static void timerlat_top_usage(char *usage) - - for (i = 0; msg[i]; i++) - fprintf(stderr, "%s\n", msg[i]); -- exit(1); -+ -+ if (usage) -+ exit(EXIT_FAILURE); -+ -+ exit(EXIT_SUCCESS); - } - - /* -diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c -index 663a047f794d2..8c8d63c7196cf 100644 ---- a/tools/tracing/rtla/src/utils.c -+++ b/tools/tracing/rtla/src/utils.c -@@ -243,12 +243,6 @@ static inline int sched_setattr(pid_t pid, const struct sched_attr *attr, - return syscall(__NR_sched_setattr, pid, attr, flags); - } - --static inline int sched_getattr(pid_t pid, struct sched_attr *attr, -- unsigned int size, unsigned int flags) --{ -- return syscall(__NR_sched_getattr, pid, attr, size, flags); --} -- - int __set_sched_attr(int pid, struct sched_attr *attr) - { - int flags = 0; -@@ -484,13 +478,13 @@ int parse_prio(char *arg, struct sched_attr *sched_param) - if (prio == INVALID_VAL) - return -1; - -- if (prio < sched_get_priority_min(SCHED_OTHER)) -+ if (prio < MIN_NICE) - return -1; -- if (prio > sched_get_priority_max(SCHED_OTHER)) -+ if (prio > MAX_NICE) - return -1; - - sched_param->sched_policy = SCHED_OTHER; -- sched_param->sched_priority = prio; -+ sched_param->sched_nice = prio; - break; - default: - return -1; -diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h -index 5571afd3b5498..92da41aaf4c4c 100644 ---- a/tools/tracing/rtla/src/utils.h -+++ b/tools/tracing/rtla/src/utils.h -@@ -7,6 +7,8 @@ - */ - #define BUFF_U64_STR_SIZE 24 - #define MAX_PATH 1024 -+#define MAX_NICE 20 -+#define MIN_NICE -19 - - #define container_of(ptr, type, member)({ \ - const typeof(((type *)0)->member) *__mptr = (ptr); \ diff --git a/patch/kernel/odroidxu4-current/patch-6.1.79-80.patch b/patch/kernel/odroidxu4-current/patch-6.1.79-80.patch deleted file mode 100644 index 33a573ebdf..0000000000 --- a/patch/kernel/odroidxu4-current/patch-6.1.79-80.patch +++ /dev/null @@ -1,10484 +0,0 @@ -diff --git a/Makefile b/Makefile -index d6bc9f597e8b8..bc4adb561a7cf 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 79 -+SUBLEVEL = 80 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c -index 95e731676cea4..961daac653261 100644 ---- a/arch/arm/mach-ep93xx/core.c -+++ b/arch/arm/mach-ep93xx/core.c -@@ -339,6 +339,7 @@ static struct gpiod_lookup_table ep93xx_i2c_gpiod_table = { - GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), - GPIO_LOOKUP_IDX("G", 0, NULL, 1, - GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), -+ { } - }, - }; - -diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi -index bfa3580429d10..61f0186447dad 100644 ---- a/arch/arm64/boot/dts/rockchip/px30.dtsi -+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi -@@ -607,6 +607,7 @@ spi0: spi@ff1d0000 { - clock-names = "spiclk", "apb_pclk"; - dmas = <&dmac 12>, <&dmac 13>; - dma-names = "tx", "rx"; -+ num-cs = <2>; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>; - #address-cells = <1>; -@@ -622,6 +623,7 @@ spi1: spi@ff1d8000 { - clock-names = "spiclk", "apb_pclk"; - dmas = <&dmac 14>, <&dmac 15>; - dma-names = "tx", "rx"; -+ num-cs = <2>; - pinctrl-names = "default"; - pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>; - #address-cells = <1>; -diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h -index d720b6f7e5f9c..da18413712c04 100644 ---- a/arch/arm64/include/asm/fpsimd.h -+++ b/arch/arm64/include/asm/fpsimd.h -@@ -343,6 +343,7 @@ extern void sme_alloc(struct task_struct *task, bool flush); - extern unsigned int sme_get_vl(void); - extern int sme_set_current_vl(unsigned long arg); - extern int sme_get_current_vl(void); -+extern void sme_suspend_exit(void); - - /* - * Return how many bytes of memory are required to store the full SME -@@ -372,6 +373,7 @@ static inline int sme_max_vl(void) { return 0; } - static inline int sme_max_virtualisable_vl(void) { return 0; } - static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; } - static inline int sme_get_current_vl(void) { return -EINVAL; } -+static inline void sme_suspend_exit(void) { } - - static inline size_t za_state_size(struct task_struct const *task) - { -diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c -index 8c226d79abdfc..59b5a16bab5d6 100644 ---- a/arch/arm64/kernel/fpsimd.c -+++ b/arch/arm64/kernel/fpsimd.c -@@ -1347,6 +1347,20 @@ void __init sme_setup(void) - get_sme_default_vl()); - } - -+void sme_suspend_exit(void) -+{ -+ u64 smcr = 0; -+ -+ if (!system_supports_sme()) -+ return; -+ -+ if (system_supports_fa64()) -+ smcr |= SMCR_ELx_FA64; -+ -+ write_sysreg_s(smcr, SYS_SMCR_EL1); -+ write_sysreg_s(0, SYS_SMPRI_EL1); -+} -+ - #endif /* CONFIG_ARM64_SME */ - - static void sve_init_regs(void) -diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c -index 8b02d310838f9..064d996cc55b2 100644 ---- a/arch/arm64/kernel/suspend.c -+++ b/arch/arm64/kernel/suspend.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -77,6 +78,8 @@ void notrace __cpu_suspend_exit(void) - */ - spectre_v4_enable_mitigation(NULL); - -+ sme_suspend_exit(); -+ - /* Restore additional feature-specific configuration */ - ptrauth_suspend_exit(); - } -diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c -index 3c344e4cd4cad..092327665a6ef 100644 ---- a/arch/arm64/kvm/vgic/vgic-its.c -+++ b/arch/arm64/kvm/vgic/vgic-its.c -@@ -462,6 +462,9 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) - } - - irq = vgic_get_irq(vcpu->kvm, NULL, intids[i]); -+ if (!irq) -+ continue; -+ - raw_spin_lock_irqsave(&irq->irq_lock, flags); - irq->pending_latch = pendmask & (1U << bit_nr); - vgic_queue_irq_unlock(vcpu->kvm, irq, flags); -@@ -1427,6 +1430,8 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its, - - for (i = 0; i < irq_count; i++) { - irq = vgic_get_irq(kvm, NULL, intids[i]); -+ if (!irq) -+ continue; - - update_affinity(irq, vcpu2); - -diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig -index e737dc8cd660c..fa3171f563274 100644 ---- a/arch/loongarch/Kconfig -+++ b/arch/loongarch/Kconfig -@@ -9,6 +9,7 @@ config LOONGARCH - select ARCH_BINFMT_ELF_STATE - select ARCH_ENABLE_MEMORY_HOTPLUG - select ARCH_ENABLE_MEMORY_HOTREMOVE -+ select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE - select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI - select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - select ARCH_HAS_PTE_SPECIAL -@@ -80,6 +81,7 @@ config LOONGARCH - select GPIOLIB - select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_MMAP_RND_BITS if MMU -+ select HAVE_ARCH_SECCOMP - select HAVE_ARCH_SECCOMP_FILTER - select HAVE_ARCH_TRACEHOOK - select HAVE_ARCH_TRANSPARENT_HUGEPAGE -@@ -461,23 +463,6 @@ config PHYSICAL_START - specified in the "crashkernel=YM@XM" command line boot parameter - passed to the panic-ed kernel). - --config SECCOMP -- bool "Enable seccomp to safely compute untrusted bytecode" -- depends on PROC_FS -- default y -- help -- This kernel feature is useful for number crunching applications -- that may need to compute untrusted bytecode during their -- execution. By using pipes or other transports made available to -- the process as file descriptors supporting the read/write -- syscalls, it's possible to isolate those applications in -- their own address space using seccomp. Once seccomp is -- enabled via /proc//seccomp, it cannot be disabled -- and the task is only allowed to execute a few safe syscalls -- defined by each seccomp mode. -- -- If unsure, say Y. Only embedded should say N here. -- - endmenu - - config ARCH_SELECT_MEMORY_MODEL -@@ -495,10 +480,6 @@ config ARCH_SPARSEMEM_ENABLE - or have huge holes in the physical address space for other reasons. - See for more. - --config ARCH_ENABLE_THP_MIGRATION -- def_bool y -- depends on TRANSPARENT_HUGEPAGE -- - config ARCH_MEMORY_PROBE - def_bool y - depends on MEMORY_HOTPLUG -diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c -index e0404df2c952f..18a2b37f4aea3 100644 ---- a/arch/loongarch/kernel/smp.c -+++ b/arch/loongarch/kernel/smp.c -@@ -297,6 +297,7 @@ void play_dead(void) - addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0); - } while (addr == 0); - -+ local_irq_disable(); - init_fn = (void *)TO_CACHE(addr); - iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR); - -diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c -index 246c6a6b02614..5b778995d4483 100644 ---- a/arch/mips/kernel/traps.c -+++ b/arch/mips/kernel/traps.c -@@ -2007,7 +2007,13 @@ unsigned long vi_handlers[64]; - - void reserve_exception_space(phys_addr_t addr, unsigned long size) - { -- memblock_reserve(addr, size); -+ /* -+ * reserve exception space on CPUs other than CPU0 -+ * is too late, since memblock is unavailable when APs -+ * up -+ */ -+ if (smp_processor_id() == 0) -+ memblock_reserve(addr, size); - } - - void __init *set_except_vector(int n, void *addr) -diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c -index 1f6c776d80813..c67883487ecd3 100644 ---- a/arch/parisc/kernel/processor.c -+++ b/arch/parisc/kernel/processor.c -@@ -171,7 +171,6 @@ static int __init processor_probe(struct parisc_device *dev) - p->cpu_num = cpu_info.cpu_num; - p->cpu_loc = cpu_info.cpu_loc; - -- set_cpu_possible(cpuid, true); - store_cpu_topology(cpuid); - - #ifdef CONFIG_SMP -@@ -466,13 +465,6 @@ static struct parisc_driver cpu_driver __refdata = { - */ - void __init processor_init(void) - { -- unsigned int cpu; -- - reset_cpu_topology(); -- -- /* reset possible mask. We will mark those which are possible. */ -- for_each_possible_cpu(cpu) -- set_cpu_possible(cpu, false); -- - register_parisc_driver(&cpu_driver); - } -diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c -index 2c99f9552b2f5..394c69fda399e 100644 ---- a/arch/s390/pci/pci.c -+++ b/arch/s390/pci/pci.c -@@ -241,7 +241,7 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - /* combine single writes by using store-block insn */ - void __iowrite64_copy(void __iomem *to, const void *from, size_t count) - { -- zpci_memcpy_toio(to, from, count); -+ zpci_memcpy_toio(to, from, count * 8); - } - - static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot) -diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h -index 2f123d4fb85b5..d3706de91a934 100644 ---- a/arch/x86/include/asm/nospec-branch.h -+++ b/arch/x86/include/asm/nospec-branch.h -@@ -222,6 +222,8 @@ extern void srso_alias_untrain_ret(void); - extern void entry_untrain_ret(void); - extern void entry_ibpb(void); - -+extern void (*x86_return_thunk)(void); -+ - #ifdef CONFIG_RETPOLINE - - #define GEN(reg) \ -diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c -index 6b8c93989aa31..69f85e2746119 100644 ---- a/arch/x86/kernel/alternative.c -+++ b/arch/x86/kernel/alternative.c -@@ -536,6 +536,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) - } - - #ifdef CONFIG_RETHUNK -+ - /* - * Rewrite the compiler generated return thunk tail-calls. - * -@@ -551,14 +552,18 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes) - { - int i = 0; - -- if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) -- return -1; -+ if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { -+ if (x86_return_thunk == __x86_return_thunk) -+ return -1; - -- bytes[i++] = RET_INSN_OPCODE; -+ i = JMP32_INSN_SIZE; -+ __text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i); -+ } else { -+ bytes[i++] = RET_INSN_OPCODE; -+ } - - for (; i < insn->length;) - bytes[i++] = INT3_INSN_OPCODE; -- - return i; - } - -diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c -index e07234ec7e237..ec51ce713dea4 100644 ---- a/arch/x86/kernel/ftrace.c -+++ b/arch/x86/kernel/ftrace.c -@@ -361,7 +361,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) - - ip = trampoline + size; - if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) -- __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, &__x86_return_thunk, JMP32_INSN_SIZE); -+ __text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE); - else - memcpy(ip, retq, sizeof(retq)); - -diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c -index 3fbb491688275..b32134b093ec8 100644 ---- a/arch/x86/kernel/static_call.c -+++ b/arch/x86/kernel/static_call.c -@@ -80,7 +80,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, - - case RET: - if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) -- code = text_gen_insn(JMP32_INSN_OPCODE, insn, &__x86_return_thunk); -+ code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk); - else - code = &retinsn; - break; -diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c -index aa39d678fe81d..dae5c952735c7 100644 ---- a/arch/x86/mm/numa.c -+++ b/arch/x86/mm/numa.c -@@ -961,7 +961,7 @@ static int __init cmp_memblk(const void *a, const void *b) - const struct numa_memblk *ma = *(const struct numa_memblk **)a; - const struct numa_memblk *mb = *(const struct numa_memblk **)b; - -- return ma->start - mb->start; -+ return (ma->start > mb->start) - (ma->start < mb->start); - } - - static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; -@@ -971,14 +971,12 @@ static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; - * @start: address to begin fill - * @end: address to end fill - * -- * Find and extend numa_meminfo memblks to cover the @start-@end -- * physical address range, such that the first memblk includes -- * @start, the last memblk includes @end, and any gaps in between -- * are filled. -+ * Find and extend numa_meminfo memblks to cover the physical -+ * address range @start-@end - * - * RETURNS: - * 0 : Success -- * NUMA_NO_MEMBLK : No memblk exists in @start-@end range -+ * NUMA_NO_MEMBLK : No memblks exist in address range @start-@end - */ - - int __init numa_fill_memblks(u64 start, u64 end) -@@ -990,17 +988,14 @@ int __init numa_fill_memblks(u64 start, u64 end) - - /* - * Create a list of pointers to numa_meminfo memblks that -- * overlap start, end. Exclude (start == bi->end) since -- * end addresses in both a CFMWS range and a memblk range -- * are exclusive. -- * -- * This list of pointers is used to make in-place changes -- * that fill out the numa_meminfo memblks. -+ * overlap start, end. The list is used to make in-place -+ * changes that fill out the numa_meminfo memblks. - */ - for (int i = 0; i < mi->nr_blks; i++) { - struct numa_memblk *bi = &mi->blk[i]; - -- if (start < bi->end && end >= bi->start) { -+ if (memblock_addrs_overlap(start, end - start, bi->start, -+ bi->end - bi->start)) { - blk[count] = &mi->blk[i]; - count++; - } -diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index b69aee6245e4a..7913440c0fd46 100644 ---- a/arch/x86/net/bpf_jit_comp.c -+++ b/arch/x86/net/bpf_jit_comp.c -@@ -432,7 +432,7 @@ static void emit_return(u8 **pprog, u8 *ip) - u8 *prog = *pprog; - - if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) { -- emit_jump(&prog, &__x86_return_thunk, ip); -+ emit_jump(&prog, x86_return_thunk, ip); - } else { - EMIT1(0xC3); /* ret */ - if (IS_ENABLED(CONFIG_SLS)) -diff --git a/block/blk-map.c b/block/blk-map.c -index 66da9e2b19abf..b337ae347bfa3 100644 ---- a/block/blk-map.c -+++ b/block/blk-map.c -@@ -203,12 +203,19 @@ static int bio_copy_user_iov(struct request *rq, struct rq_map_data *map_data, - /* - * success - */ -- if ((iov_iter_rw(iter) == WRITE && -- (!map_data || !map_data->null_mapped)) || -- (map_data && map_data->from_user)) { -+ if (iov_iter_rw(iter) == WRITE && -+ (!map_data || !map_data->null_mapped)) { - ret = bio_copy_from_iter(bio, iter); - if (ret) - goto cleanup; -+ } else if (map_data && map_data->from_user) { -+ struct iov_iter iter2 = *iter; -+ -+ /* This is the copy-in part of SG_DXFER_TO_FROM_DEV. */ -+ iter2.data_source = ITER_SOURCE; -+ ret = bio_copy_from_iter(bio, &iter2); -+ if (ret) -+ goto cleanup; - } else { - if (bmd->is_our_pages) - zero_fill_bio(bio); -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index 805645efb3ccf..1790a2ecb9fac 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -49,6 +49,7 @@ enum { - enum board_ids { - /* board IDs by feature in alphabetical order */ - board_ahci, -+ board_ahci_43bit_dma, - board_ahci_ign_iferr, - board_ahci_low_power, - board_ahci_no_debounce_delay, -@@ -129,6 +130,13 @@ static const struct ata_port_info ahci_port_info[] = { - .udma_mask = ATA_UDMA6, - .port_ops = &ahci_ops, - }, -+ [board_ahci_43bit_dma] = { -+ AHCI_HFLAGS (AHCI_HFLAG_43BIT_ONLY), -+ .flags = AHCI_FLAG_COMMON, -+ .pio_mask = ATA_PIO4, -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &ahci_ops, -+ }, - [board_ahci_ign_iferr] = { - AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), - .flags = AHCI_FLAG_COMMON, -@@ -597,14 +605,19 @@ static const struct pci_device_id ahci_pci_tbl[] = { - { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ - { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */ - -- /* Asmedia */ -- { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ -- { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ -- { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ -- { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ -- { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */ -- { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */ -- { PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci }, /* ASM1062+JMB575 */ -+ /* ASMedia */ -+ { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci_43bit_dma }, /* ASM1060 */ -+ { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci_43bit_dma }, /* ASM1060 */ -+ { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci_43bit_dma }, /* ASM1061 */ -+ { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci_43bit_dma }, /* ASM1061/1062 */ -+ { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci_43bit_dma }, /* ASM1061R */ -+ { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci_43bit_dma }, /* ASM1062R */ -+ { PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci_43bit_dma }, /* ASM1062+JMB575 */ -+ { PCI_VDEVICE(ASMEDIA, 0x1062), board_ahci }, /* ASM1062A */ -+ { PCI_VDEVICE(ASMEDIA, 0x1064), board_ahci }, /* ASM1064 */ -+ { PCI_VDEVICE(ASMEDIA, 0x1164), board_ahci }, /* ASM1164 */ -+ { PCI_VDEVICE(ASMEDIA, 0x1165), board_ahci }, /* ASM1165 */ -+ { PCI_VDEVICE(ASMEDIA, 0x1166), board_ahci }, /* ASM1166 */ - - /* - * Samsung SSDs found on some macbooks. NCQ times out if MSI is -@@ -658,6 +671,11 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets"); - static void ahci_pci_save_initial_config(struct pci_dev *pdev, - struct ahci_host_priv *hpriv) - { -+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) { -+ dev_info(&pdev->dev, "ASM1166 has only six ports\n"); -+ hpriv->saved_port_map = 0x3f; -+ } -+ - if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { - dev_info(&pdev->dev, "JMB361 has only one port\n"); - hpriv->saved_port_map = 1; -@@ -944,11 +962,20 @@ static int ahci_pci_device_resume(struct device *dev) - - #endif /* CONFIG_PM */ - --static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) -+static int ahci_configure_dma_masks(struct pci_dev *pdev, -+ struct ahci_host_priv *hpriv) - { -- const int dma_bits = using_dac ? 64 : 32; -+ int dma_bits; - int rc; - -+ if (hpriv->cap & HOST_CAP_64) { -+ dma_bits = 64; -+ if (hpriv->flags & AHCI_HFLAG_43BIT_ONLY) -+ dma_bits = 43; -+ } else { -+ dma_bits = 32; -+ } -+ - /* - * If the device fixup already set the dma_mask to some non-standard - * value, don't extend it here. This happens on STA2X11, for example. -@@ -1921,7 +1948,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - ahci_gtf_filter_workaround(host); - - /* initialize adapter */ -- rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); -+ rc = ahci_configure_dma_masks(pdev, hpriv); - if (rc) - return rc; - -diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h -index ff8e6ae1c6362..f9c5906a8afa8 100644 ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -247,6 +247,7 @@ enum { - AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during - suspend/resume */ - AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ -+ AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */ - - /* ap->flags bits */ - -diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c -index cb24ecf36fafe..50e07ea60e45c 100644 ---- a/drivers/ata/ahci_ceva.c -+++ b/drivers/ata/ahci_ceva.c -@@ -88,7 +88,6 @@ struct ceva_ahci_priv { - u32 axicc; - bool is_cci_enabled; - int flags; -- struct reset_control *rst; - }; - - static unsigned int ceva_ahci_read_id(struct ata_device *dev, -@@ -189,6 +188,60 @@ static struct scsi_host_template ahci_platform_sht = { - AHCI_SHT(DRV_NAME), - }; - -+static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv) -+{ -+ int rc, i; -+ -+ rc = ahci_platform_enable_regulators(hpriv); -+ if (rc) -+ return rc; -+ -+ rc = ahci_platform_enable_clks(hpriv); -+ if (rc) -+ goto disable_regulator; -+ -+ /* Assert the controller reset */ -+ rc = ahci_platform_assert_rsts(hpriv); -+ if (rc) -+ goto disable_clks; -+ -+ for (i = 0; i < hpriv->nports; i++) { -+ rc = phy_init(hpriv->phys[i]); -+ if (rc) -+ goto disable_rsts; -+ } -+ -+ /* De-assert the controller reset */ -+ ahci_platform_deassert_rsts(hpriv); -+ -+ for (i = 0; i < hpriv->nports; i++) { -+ rc = phy_power_on(hpriv->phys[i]); -+ if (rc) { -+ phy_exit(hpriv->phys[i]); -+ goto disable_phys; -+ } -+ } -+ -+ return 0; -+ -+disable_rsts: -+ ahci_platform_deassert_rsts(hpriv); -+ -+disable_phys: -+ while (--i >= 0) { -+ phy_power_off(hpriv->phys[i]); -+ phy_exit(hpriv->phys[i]); -+ } -+ -+disable_clks: -+ ahci_platform_disable_clks(hpriv); -+ -+disable_regulator: -+ ahci_platform_disable_regulators(hpriv); -+ -+ return rc; -+} -+ - static int ceva_ahci_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; -@@ -203,47 +256,19 @@ static int ceva_ahci_probe(struct platform_device *pdev) - return -ENOMEM; - - cevapriv->ahci_pdev = pdev; -- -- cevapriv->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, -- NULL); -- if (IS_ERR(cevapriv->rst)) -- dev_err_probe(&pdev->dev, PTR_ERR(cevapriv->rst), -- "failed to get reset\n"); -- - hpriv = ahci_platform_get_resources(pdev, 0); - if (IS_ERR(hpriv)) - return PTR_ERR(hpriv); - -- if (!cevapriv->rst) { -- rc = ahci_platform_enable_resources(hpriv); -- if (rc) -- return rc; -- } else { -- int i; -+ hpriv->rsts = devm_reset_control_get_optional_exclusive(&pdev->dev, -+ NULL); -+ if (IS_ERR(hpriv->rsts)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(hpriv->rsts), -+ "failed to get reset\n"); - -- rc = ahci_platform_enable_clks(hpriv); -- if (rc) -- return rc; -- /* Assert the controller reset */ -- reset_control_assert(cevapriv->rst); -- -- for (i = 0; i < hpriv->nports; i++) { -- rc = phy_init(hpriv->phys[i]); -- if (rc) -- return rc; -- } -- -- /* De-assert the controller reset */ -- reset_control_deassert(cevapriv->rst); -- -- for (i = 0; i < hpriv->nports; i++) { -- rc = phy_power_on(hpriv->phys[i]); -- if (rc) { -- phy_exit(hpriv->phys[i]); -- return rc; -- } -- } -- } -+ rc = ceva_ahci_platform_enable_resources(hpriv); -+ if (rc) -+ return rc; - - if (of_property_read_bool(np, "ceva,broken-gen2")) - cevapriv->flags = CEVA_FLAG_BROKEN_GEN2; -@@ -252,52 +277,60 @@ static int ceva_ahci_probe(struct platform_device *pdev) - if (of_property_read_u8_array(np, "ceva,p0-cominit-params", - (u8 *)&cevapriv->pp2c[0], 4) < 0) { - dev_warn(dev, "ceva,p0-cominit-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - if (of_property_read_u8_array(np, "ceva,p1-cominit-params", - (u8 *)&cevapriv->pp2c[1], 4) < 0) { - dev_warn(dev, "ceva,p1-cominit-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - /* Read OOB timing value for COMWAKE from device-tree*/ - if (of_property_read_u8_array(np, "ceva,p0-comwake-params", - (u8 *)&cevapriv->pp3c[0], 4) < 0) { - dev_warn(dev, "ceva,p0-comwake-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - if (of_property_read_u8_array(np, "ceva,p1-comwake-params", - (u8 *)&cevapriv->pp3c[1], 4) < 0) { - dev_warn(dev, "ceva,p1-comwake-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - /* Read phy BURST timing value from device-tree */ - if (of_property_read_u8_array(np, "ceva,p0-burst-params", - (u8 *)&cevapriv->pp4c[0], 4) < 0) { - dev_warn(dev, "ceva,p0-burst-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - if (of_property_read_u8_array(np, "ceva,p1-burst-params", - (u8 *)&cevapriv->pp4c[1], 4) < 0) { - dev_warn(dev, "ceva,p1-burst-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - /* Read phy RETRY interval timing value from device-tree */ - if (of_property_read_u16_array(np, "ceva,p0-retry-params", - (u16 *)&cevapriv->pp5c[0], 2) < 0) { - dev_warn(dev, "ceva,p0-retry-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - if (of_property_read_u16_array(np, "ceva,p1-retry-params", - (u16 *)&cevapriv->pp5c[1], 2) < 0) { - dev_warn(dev, "ceva,p1-retry-params property not defined\n"); -- return -EINVAL; -+ rc = -EINVAL; -+ goto disable_resources; - } - - /* -@@ -335,7 +368,7 @@ static int __maybe_unused ceva_ahci_resume(struct device *dev) - struct ahci_host_priv *hpriv = host->private_data; - int rc; - -- rc = ahci_platform_enable_resources(hpriv); -+ rc = ceva_ahci_platform_enable_resources(hpriv); - if (rc) - return rc; - -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index fa2fc1953fc26..f14e56a5cff6b 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -2005,6 +2005,10 @@ void ata_dev_power_set_active(struct ata_device *dev) - struct ata_taskfile tf; - unsigned int err_mask; - -+ /* If the device is already sleeping, do nothing. */ -+ if (dev->flags & ATA_DFLAG_SLEEPING) -+ return; -+ - /* - * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only - * if supported by the device. -diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c -index 128722cf6c3ca..827802e418dd3 100644 ---- a/drivers/block/aoe/aoeblk.c -+++ b/drivers/block/aoe/aoeblk.c -@@ -333,6 +333,7 @@ aoeblk_gdalloc(void *vp) - struct gendisk *gd; - mempool_t *mp; - struct blk_mq_tag_set *set; -+ sector_t ssize; - ulong flags; - int late = 0; - int err; -@@ -395,7 +396,7 @@ aoeblk_gdalloc(void *vp) - gd->minors = AOE_PARTITIONS; - gd->fops = &aoe_bdops; - gd->private_data = d; -- set_capacity(gd, d->ssize); -+ ssize = d->ssize; - snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", - d->aoemajor, d->aoeminor); - -@@ -404,6 +405,8 @@ aoeblk_gdalloc(void *vp) - - spin_unlock_irqrestore(&d->lock, flags); - -+ set_capacity(gd, ssize); -+ - err = device_add_disk(NULL, gd, aoe_attr_groups); - if (err) - goto out_disk_cleanup; -diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c -index 3124837aa406f..505026f0025c7 100644 ---- a/drivers/block/virtio_blk.c -+++ b/drivers/block/virtio_blk.c -@@ -1206,14 +1206,15 @@ static int virtblk_freeze(struct virtio_device *vdev) - { - struct virtio_blk *vblk = vdev->priv; - -+ /* Ensure no requests in virtqueues before deleting vqs. */ -+ blk_mq_freeze_queue(vblk->disk->queue); -+ - /* Ensure we don't receive any more interrupts */ - virtio_reset_device(vdev); - - /* Make sure no work handler is accessing the device. */ - flush_work(&vblk->config_work); - -- blk_mq_quiesce_queue(vblk->disk->queue); -- - vdev->config->del_vqs(vdev); - kfree(vblk->vqs); - -@@ -1231,7 +1232,7 @@ static int virtblk_restore(struct virtio_device *vdev) - - virtio_device_ready(vdev); - -- blk_mq_unquiesce_queue(vblk->disk->queue); -+ blk_mq_unfreeze_queue(vblk->disk->queue); - return 0; - } - #endif -diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c -index 168195672e2e1..d2df97cfcb294 100644 ---- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c -+++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c -@@ -104,7 +104,8 @@ static void virtio_crypto_dataq_akcipher_callback(struct virtio_crypto_request * - } - - static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher_ctx *ctx, -- struct virtio_crypto_ctrl_header *header, void *para, -+ struct virtio_crypto_ctrl_header *header, -+ struct virtio_crypto_akcipher_session_para *para, - const uint8_t *key, unsigned int keylen) - { - struct scatterlist outhdr_sg, key_sg, inhdr_sg, *sgs[3]; -@@ -128,7 +129,7 @@ static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher - - ctrl = &vc_ctrl_req->ctrl; - memcpy(&ctrl->header, header, sizeof(ctrl->header)); -- memcpy(&ctrl->u, para, sizeof(ctrl->u)); -+ memcpy(&ctrl->u.akcipher_create_session.para, para, sizeof(*para)); - input = &vc_ctrl_req->input; - input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR); - -diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c -index 003a44132418a..5584af15300a8 100644 ---- a/drivers/cxl/core/pci.c -+++ b/drivers/cxl/core/pci.c -@@ -376,9 +376,9 @@ static bool __cxl_hdm_decode_init(struct cxl_dev_state *cxlds, - allowed++; - } - -- if (!allowed) { -- cxl_set_mem_enable(cxlds, 0); -- info->mem_enabled = 0; -+ if (!allowed && info->mem_enabled) { -+ dev_err(dev, "Range register decodes outside platform defined CXL ranges.\n"); -+ return -ENXIO; - } - - /* -diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c -index 4cf8da77bdd91..cac4532fe23a9 100644 ---- a/drivers/dma/apple-admac.c -+++ b/drivers/dma/apple-admac.c -@@ -56,6 +56,8 @@ - - #define REG_BUS_WIDTH(ch) (0x8040 + (ch) * 0x200) - -+#define BUS_WIDTH_WORD_SIZE GENMASK(3, 0) -+#define BUS_WIDTH_FRAME_SIZE GENMASK(7, 4) - #define BUS_WIDTH_8BIT 0x00 - #define BUS_WIDTH_16BIT 0x01 - #define BUS_WIDTH_32BIT 0x02 -@@ -739,7 +741,8 @@ static int admac_device_config(struct dma_chan *chan, - struct admac_data *ad = adchan->host; - bool is_tx = admac_chan_direction(adchan->no) == DMA_MEM_TO_DEV; - int wordsize = 0; -- u32 bus_width = 0; -+ u32 bus_width = readl_relaxed(ad->base + REG_BUS_WIDTH(adchan->no)) & -+ ~(BUS_WIDTH_WORD_SIZE | BUS_WIDTH_FRAME_SIZE); - - switch (is_tx ? config->dst_addr_width : config->src_addr_width) { - case DMA_SLAVE_BUSWIDTH_1_BYTE: -diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c -index 69385f32e2756..f383f219ed008 100644 ---- a/drivers/dma/fsl-qdma.c -+++ b/drivers/dma/fsl-qdma.c -@@ -805,7 +805,7 @@ fsl_qdma_irq_init(struct platform_device *pdev, - int i; - int cpu; - int ret; -- char irq_name[20]; -+ char irq_name[32]; - - fsl_qdma->error_irq = - platform_get_irq_byname(pdev, "qdma-error"); -diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h -index 9c121a4b33ad8..f97d80343aea4 100644 ---- a/drivers/dma/sh/shdma.h -+++ b/drivers/dma/sh/shdma.h -@@ -25,7 +25,7 @@ struct sh_dmae_chan { - const struct sh_dmae_slave_config *config; /* Slave DMA configuration */ - int xmit_shift; /* log_2(bytes_per_xfer) */ - void __iomem *base; -- char dev_id[16]; /* unique name per DMAC of channel */ -+ char dev_id[32]; /* unique name per DMAC of channel */ - int pm_error; - dma_addr_t slave_addr; - }; -diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c -index 7ec6e5d728b03..9212ac9f978f2 100644 ---- a/drivers/dma/ti/edma.c -+++ b/drivers/dma/ti/edma.c -@@ -2413,6 +2413,11 @@ static int edma_probe(struct platform_device *pdev) - if (irq > 0) { - irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", - dev_name(dev)); -+ if (!irq_name) { -+ ret = -ENOMEM; -+ goto err_disable_pm; -+ } -+ - ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, - ecc); - if (ret) { -@@ -2429,6 +2434,11 @@ static int edma_probe(struct platform_device *pdev) - if (irq > 0) { - irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", - dev_name(dev)); -+ if (!irq_name) { -+ ret = -ENOMEM; -+ goto err_disable_pm; -+ } -+ - ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, - ecc); - if (ret) { -diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c -index 6ac5ff20a2fe2..8aaa7fcb2630d 100644 ---- a/drivers/firewire/core-card.c -+++ b/drivers/firewire/core-card.c -@@ -429,7 +429,23 @@ static void bm_work(struct work_struct *work) - */ - card->bm_generation = generation; - -- if (root_device == NULL) { -+ if (card->gap_count == 0) { -+ /* -+ * If self IDs have inconsistent gap counts, do a -+ * bus reset ASAP. The config rom read might never -+ * complete, so don't wait for it. However, still -+ * send a PHY configuration packet prior to the -+ * bus reset. The PHY configuration packet might -+ * fail, but 1394-2008 8.4.5.2 explicitly permits -+ * it in this case, so it should be safe to try. -+ */ -+ new_root_id = local_id; -+ /* -+ * We must always send a bus reset if the gap count -+ * is inconsistent, so bypass the 5-reset limit. -+ */ -+ card->bm_retries = 0; -+ } else if (root_device == NULL) { - /* - * Either link_on is false, or we failed to read the - * config rom. In either case, pick another root. -diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c -index 7c48c380d722c..1995f0a2e0fc0 100644 ---- a/drivers/firmware/efi/arm-runtime.c -+++ b/drivers/firmware/efi/arm-runtime.c -@@ -107,7 +107,7 @@ static int __init arm_enable_runtime_services(void) - efi_memory_desc_t *md; - - for_each_efi_memory_desc(md) { -- int md_size = md->num_pages << EFI_PAGE_SHIFT; -+ u64 md_size = md->num_pages << EFI_PAGE_SHIFT; - struct resource *res; - - if (!(md->attribute & EFI_MEMORY_SP)) -diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c -index 2fd770b499a35..ff9791ce2e156 100644 ---- a/drivers/firmware/efi/efi-init.c -+++ b/drivers/firmware/efi/efi-init.c -@@ -116,15 +116,6 @@ static __init int is_usable_memory(efi_memory_desc_t *md) - case EFI_BOOT_SERVICES_DATA: - case EFI_CONVENTIONAL_MEMORY: - case EFI_PERSISTENT_MEMORY: -- /* -- * Special purpose memory is 'soft reserved', which means it -- * is set aside initially, but can be hotplugged back in or -- * be assigned to the dax driver after boot. -- */ -- if (efi_soft_reserve_enabled() && -- (md->attribute & EFI_MEMORY_SP)) -- return false; -- - /* - * According to the spec, these regions are no longer reserved - * after calling ExitBootServices(). However, we can only use -@@ -169,6 +160,16 @@ static __init void reserve_regions(void) - size = npages << PAGE_SHIFT; - - if (is_memory(md)) { -+ /* -+ * Special purpose memory is 'soft reserved', which -+ * means it is set aside initially. Don't add a memblock -+ * for it now so that it can be hotplugged back in or -+ * be assigned to the dax driver after boot. -+ */ -+ if (efi_soft_reserve_enabled() && -+ (md->attribute & EFI_MEMORY_SP)) -+ continue; -+ - early_init_dt_add_memory_arch(paddr, size); - - if (!is_usable_memory(md)) -diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile -index ef5045a53ce09..b6e1dcb98a64c 100644 ---- a/drivers/firmware/efi/libstub/Makefile -+++ b/drivers/firmware/efi/libstub/Makefile -@@ -25,7 +25,7 @@ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ - -fno-builtin -fpic \ - $(call cc-option,-mno-single-pic-base) - cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ -- -fpic -+ -fpic -mno-relax - cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ - -fpie - -diff --git a/drivers/firmware/efi/riscv-runtime.c b/drivers/firmware/efi/riscv-runtime.c -index d0daacd2c903f..6b142aa35389e 100644 ---- a/drivers/firmware/efi/riscv-runtime.c -+++ b/drivers/firmware/efi/riscv-runtime.c -@@ -85,7 +85,7 @@ static int __init riscv_enable_runtime_services(void) - efi_memory_desc_t *md; - - for_each_efi_memory_desc(md) { -- int md_size = md->num_pages << EFI_PAGE_SHIFT; -+ u64 md_size = md->num_pages << EFI_PAGE_SHIFT; - struct resource *res; - - if (!(md->attribute & EFI_MEMORY_SP)) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -index c46c6fbd235e8..e636c7850f777 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -@@ -999,6 +999,8 @@ struct amdgpu_device { - bool in_s3; - bool in_s4; - bool in_s0ix; -+ /* indicate amdgpu suspension status */ -+ bool suspend_complete; - - enum pp_mp1_state mp1_state; - struct amdgpu_doorbell_index doorbell_index; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index b9983ca99eb7d..f24c3a20e901d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -2414,6 +2414,7 @@ static int amdgpu_pmops_suspend(struct device *dev) - struct drm_device *drm_dev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(drm_dev); - -+ adev->suspend_complete = false; - if (amdgpu_acpi_is_s0ix_active(adev)) - adev->in_s0ix = true; - else if (amdgpu_acpi_is_s3_active(adev)) -@@ -2428,6 +2429,7 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev) - struct drm_device *drm_dev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(drm_dev); - -+ adev->suspend_complete = true; - if (amdgpu_acpi_should_gpu_reset(adev)) - return amdgpu_asic_reset(adev); - -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -index 84ca601f7d5f3..195b298923543 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -@@ -3064,6 +3064,14 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev) - - gfx_v9_0_cp_gfx_enable(adev, true); - -+ /* Now only limit the quirk on the APU gfx9 series and already -+ * confirmed that the APU gfx10/gfx11 needn't such update. -+ */ -+ if (adev->flags & AMD_IS_APU && -+ adev->in_s3 && !adev->suspend_complete) { -+ DRM_INFO(" Will skip the CSB packet resubmit\n"); -+ return 0; -+ } - r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3); - if (r) { - DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); -diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c -index 811dd3ea63620..489c89465c78b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc15.c -+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c -@@ -1285,10 +1285,32 @@ static int soc15_common_suspend(void *handle) - return soc15_common_hw_fini(adev); - } - -+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev) -+{ -+ u32 sol_reg; -+ -+ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); -+ -+ /* Will reset for the following suspend abort cases. -+ * 1) Only reset limit on APU side, dGPU hasn't checked yet. -+ * 2) S3 suspend abort and TOS already launched. -+ */ -+ if (adev->flags & AMD_IS_APU && adev->in_s3 && -+ !adev->suspend_complete && -+ sol_reg) -+ return true; -+ -+ return false; -+} -+ - static int soc15_common_resume(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -+ if (soc15_need_reset_on_resume(adev)) { -+ dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n"); -+ soc15_asic_reset(adev); -+ } - return soc15_common_hw_init(adev); - } - -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 a826c92933199..da16048bf1004 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -2255,6 +2255,7 @@ static int dm_sw_fini(void *handle) - - if (adev->dm.dmub_srv) { - dmub_srv_destroy(adev->dm.dmub_srv); -+ kfree(adev->dm.dmub_srv); - adev->dm.dmub_srv = NULL; - } - -diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c -index da0145bc104a8..8f2737075dc2f 100644 ---- a/drivers/gpu/drm/drm_syncobj.c -+++ b/drivers/gpu/drm/drm_syncobj.c -@@ -980,7 +980,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, - uint64_t *points; - uint32_t signaled_count, i; - -- if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) -+ if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | -+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) - lockdep_assert_none_held_once(); - - points = kmalloc_array(count, sizeof(*points), GFP_KERNEL); -@@ -1049,7 +1050,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, - * fallthough and try a 0 timeout wait! - */ - -- if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { -+ if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | -+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { - for (i = 0; i < count; ++i) - drm_syncobj_fence_add_wait(syncobjs[i], &entries[i]); - } -diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c -index 19188683c8fca..8c2bf1c16f2a9 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c -+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c -@@ -154,11 +154,17 @@ shadow_fw_init(struct nvkm_bios *bios, const char *name) - return (void *)fw; - } - -+static void -+shadow_fw_release(void *fw) -+{ -+ release_firmware(fw); -+} -+ - static const struct nvbios_source - shadow_fw = { - .name = "firmware", - .init = shadow_fw_init, -- .fini = (void(*)(void *))release_firmware, -+ .fini = shadow_fw_release, - .read = shadow_fw_read, - .rw = false, - }; -diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c -index 86affe987a1cb..393b97b4a991f 100644 ---- a/drivers/gpu/drm/ttm/ttm_pool.c -+++ b/drivers/gpu/drm/ttm/ttm_pool.c -@@ -383,7 +383,7 @@ static void ttm_pool_free_range(struct ttm_pool *pool, struct ttm_tt *tt, - enum ttm_caching caching, - pgoff_t start_page, pgoff_t end_page) - { -- struct page **pages = tt->pages; -+ struct page **pages = &tt->pages[start_page]; - unsigned int order; - pgoff_t i, nr; - -diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c -index 59344ad62822d..c0aa6bfa66b24 100644 ---- a/drivers/hwmon/coretemp.c -+++ b/drivers/hwmon/coretemp.c -@@ -40,7 +40,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); - - #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ - #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ --#define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ -+#define NUM_REAL_CORES 512 /* Number of Real cores per cpu */ - #define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ - #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ - #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) -diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c -index fc70920c4ddab..0c203c614197c 100644 ---- a/drivers/i2c/busses/i2c-imx.c -+++ b/drivers/i2c/busses/i2c-imx.c -@@ -804,6 +804,11 @@ static irqreturn_t i2c_imx_slave_handle(struct imx_i2c_struct *i2c_imx, - ctl &= ~I2CR_MTX; - imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR); - imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); -+ -+ /* flag the last byte as processed */ -+ i2c_imx_slave_event(i2c_imx, -+ I2C_SLAVE_READ_PROCESSED, &value); -+ - i2c_imx_slave_finish_op(i2c_imx); - return IRQ_HANDLED; - } -diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c -index 4ed8814efde6f..6ed0568747eaa 100644 ---- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c -+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c -@@ -1710,7 +1710,7 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, - switch (srq_attr_mask) { - case IB_SRQ_MAX_WR: - /* SRQ resize is not supported */ -- break; -+ return -EINVAL; - case IB_SRQ_LIMIT: - /* Change the SRQ threshold */ - if (srq_attr->srq_limit > srq->qplib_srq.max_wqe) -@@ -1725,13 +1725,12 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, - /* On success, update the shadow */ - srq->srq_limit = srq_attr->srq_limit; - /* No need to Build and send response back to udata */ -- break; -+ return 0; - default: - ibdev_err(&rdev->ibdev, - "Unsupported srq_attr_mask 0x%x", srq_attr_mask); - return -EINVAL; - } -- return 0; - } - - int bnxt_re_query_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr) -diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c -index 51ae58c02b15c..802b0e5801a7d 100644 ---- a/drivers/infiniband/hw/hfi1/pio.c -+++ b/drivers/infiniband/hw/hfi1/pio.c -@@ -2089,7 +2089,7 @@ int init_credit_return(struct hfi1_devdata *dd) - "Unable to allocate credit return DMA range for NUMA %d\n", - i); - ret = -ENOMEM; -- goto done; -+ goto free_cr_base; - } - } - set_dev_node(&dd->pcidev->dev, dd->node); -@@ -2097,6 +2097,10 @@ int init_credit_return(struct hfi1_devdata *dd) - ret = 0; - done: - return ret; -+ -+free_cr_base: -+ free_credit_return(dd); -+ goto done; - } - - void free_credit_return(struct hfi1_devdata *dd) -diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c -index 26c62162759ba..969c5c3ab859e 100644 ---- a/drivers/infiniband/hw/hfi1/sdma.c -+++ b/drivers/infiniband/hw/hfi1/sdma.c -@@ -3158,7 +3158,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) - { - int rval = 0; - -- if ((unlikely(tx->num_desc + 1 == tx->desc_limit))) { -+ if ((unlikely(tx->num_desc == tx->desc_limit))) { - rval = _extend_sdma_tx_descs(dd, tx); - if (rval) { - __sdma_txclean(dd, tx); -diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h -index ad54260cb58c9..ebe98fa2b1cd2 100644 ---- a/drivers/infiniband/hw/irdma/defs.h -+++ b/drivers/infiniband/hw/irdma/defs.h -@@ -345,6 +345,7 @@ enum irdma_cqp_op_type { - #define IRDMA_AE_LLP_TOO_MANY_KEEPALIVE_RETRIES 0x050b - #define IRDMA_AE_LLP_DOUBT_REACHABILITY 0x050c - #define IRDMA_AE_LLP_CONNECTION_ESTABLISHED 0x050e -+#define IRDMA_AE_LLP_TOO_MANY_RNRS 0x050f - #define IRDMA_AE_RESOURCE_EXHAUSTION 0x0520 - #define IRDMA_AE_RESET_SENT 0x0601 - #define IRDMA_AE_TERMINATE_SENT 0x0602 -diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c -index 311a1138e838d..918a2d783141f 100644 ---- a/drivers/infiniband/hw/irdma/hw.c -+++ b/drivers/infiniband/hw/irdma/hw.c -@@ -379,6 +379,7 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) - case IRDMA_AE_LLP_TOO_MANY_RETRIES: - case IRDMA_AE_LCE_QP_CATASTROPHIC: - case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC: -+ case IRDMA_AE_LLP_TOO_MANY_RNRS: - case IRDMA_AE_LCE_CQ_CATASTROPHIC: - case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: - default: -@@ -562,6 +563,13 @@ static void irdma_destroy_irq(struct irdma_pci_f *rf, - dev->irq_ops->irdma_dis_irq(dev, msix_vec->idx); - irq_update_affinity_hint(msix_vec->irq, NULL); - free_irq(msix_vec->irq, dev_id); -+ if (rf == dev_id) { -+ tasklet_kill(&rf->dpc_tasklet); -+ } else { -+ struct irdma_ceq *iwceq = (struct irdma_ceq *)dev_id; -+ -+ tasklet_kill(&iwceq->dpc_tasklet); -+ } - } - - /** -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 01faec6ea5285..42c671f209233 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -762,7 +762,9 @@ static int irdma_validate_qp_attrs(struct ib_qp_init_attr *init_attr, - - if (init_attr->cap.max_inline_data > uk_attrs->max_hw_inline || - init_attr->cap.max_send_sge > uk_attrs->max_hw_wq_frags || -- init_attr->cap.max_recv_sge > uk_attrs->max_hw_wq_frags) -+ init_attr->cap.max_recv_sge > uk_attrs->max_hw_wq_frags || -+ init_attr->cap.max_send_wr > uk_attrs->max_hw_wq_quanta || -+ init_attr->cap.max_recv_wr > uk_attrs->max_hw_rq_quanta) - return -EINVAL; - - if (rdma_protocol_roce(&iwdev->ibdev, 1)) { -@@ -2119,9 +2121,8 @@ static int irdma_create_cq(struct ib_cq *ibcq, - info.cq_base_pa = iwcq->kmem.pa; - } - -- if (dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) -- info.shadow_read_threshold = min(info.cq_uk_init_info.cq_size / 2, -- (u32)IRDMA_MAX_CQ_READ_THRESH); -+ info.shadow_read_threshold = min(info.cq_uk_init_info.cq_size / 2, -+ (u32)IRDMA_MAX_CQ_READ_THRESH); - - if (irdma_sc_cq_init(cq, &info)) { - ibdev_dbg(&iwdev->ibdev, "VERBS: init cq fail\n"); -diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c -index d745ce9dc88aa..61755b5f3e20d 100644 ---- a/drivers/infiniband/hw/qedr/verbs.c -+++ b/drivers/infiniband/hw/qedr/verbs.c -@@ -1879,8 +1879,17 @@ static int qedr_create_user_qp(struct qedr_dev *dev, - /* RQ - read access only (0) */ - rc = qedr_init_user_queue(udata, dev, &qp->urq, ureq.rq_addr, - ureq.rq_len, true, 0, alloc_and_init); -- if (rc) -+ if (rc) { -+ ib_umem_release(qp->usq.umem); -+ qp->usq.umem = NULL; -+ if (rdma_protocol_roce(&dev->ibdev, 1)) { -+ qedr_free_pbl(dev, &qp->usq.pbl_info, -+ qp->usq.pbl_tbl); -+ } else { -+ kfree(qp->usq.pbl_tbl); -+ } - return rc; -+ } - } - - memset(&in_params, 0, sizeof(in_params)); -diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c -index 25e799dba999e..cffa93f114a73 100644 ---- a/drivers/infiniband/ulp/srpt/ib_srpt.c -+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c -@@ -79,12 +79,16 @@ module_param(srpt_srq_size, int, 0444); - MODULE_PARM_DESC(srpt_srq_size, - "Shared receive queue (SRQ) size."); - -+static int srpt_set_u64_x(const char *buffer, const struct kernel_param *kp) -+{ -+ return kstrtou64(buffer, 16, (u64 *)kp->arg); -+} - static int srpt_get_u64_x(char *buffer, const struct kernel_param *kp) - { - return sprintf(buffer, "0x%016llx\n", *(u64 *)kp->arg); - } --module_param_call(srpt_service_guid, NULL, srpt_get_u64_x, &srpt_service_guid, -- 0444); -+module_param_call(srpt_service_guid, srpt_set_u64_x, srpt_get_u64_x, -+ &srpt_service_guid, 0444); - MODULE_PARM_DESC(srpt_service_guid, - "Using this value for ioc_guid, id_ext, and cm_listen_id instead of using the node_guid of the first HCA."); - -@@ -210,10 +214,12 @@ static const char *get_ch_state_name(enum rdma_ch_state s) - /** - * srpt_qp_event - QP event callback function - * @event: Description of the event that occurred. -- * @ch: SRPT RDMA channel. -+ * @ptr: SRPT RDMA channel. - */ --static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch) -+static void srpt_qp_event(struct ib_event *event, void *ptr) - { -+ struct srpt_rdma_ch *ch = ptr; -+ - pr_debug("QP event %d on ch=%p sess_name=%s-%d state=%s\n", - event->event, ch, ch->sess_name, ch->qp->qp_num, - get_ch_state_name(ch->state)); -@@ -1807,8 +1813,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) - ch->cq_size = ch->rq_size + sq_size; - - qp_init->qp_context = (void *)ch; -- qp_init->event_handler -- = (void(*)(struct ib_event *, void*))srpt_qp_event; -+ qp_init->event_handler = srpt_qp_event; - qp_init->send_cq = ch->cq; - qp_init->recv_cq = ch->cq; - qp_init->sq_sig_type = IB_SIGNAL_REQ_WR; -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index e8011d70d0799..02f3bc4e4895e 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -294,6 +294,7 @@ static const struct xpad_device { - { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, - { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, - { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, -+ { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 }, - { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, - { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, - { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, -@@ -489,6 +490,7 @@ static const struct usb_device_id xpad_table[] = { - XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ - XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ -+ XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */ - XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ - XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ - XPAD_XBOX360_VENDOR(0x20d6), /* PowerA Controllers */ -diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h -index cd45a65e17f2c..dfc6c581873b7 100644 ---- a/drivers/input/serio/i8042-acpipnpio.h -+++ b/drivers/input/serio/i8042-acpipnpio.h -@@ -634,6 +634,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { - }, - .driver_data = (void *)(SERIO_QUIRK_NOAUX) - }, -+ { -+ /* Fujitsu Lifebook U728 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U728"), -+ }, -+ .driver_data = (void *)(SERIO_QUIRK_NOAUX) -+ }, - { - /* Gigabyte M912 */ - .matches = { -diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c -index 3f0732db7bf5b..6de64b3f900fb 100644 ---- a/drivers/input/touchscreen/goodix.c -+++ b/drivers/input/touchscreen/goodix.c -@@ -884,7 +884,8 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) - } - } - -- if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) { -+ /* Some devices with gpio_int_idx 0 list a third unused GPIO */ -+ if ((ts->gpio_count == 2 || ts->gpio_count == 3) && ts->gpio_int_idx == 0) { - ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; - gpio_mapping = acpi_goodix_int_first_gpios; - } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { -diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c -index b83b39e93e1a9..4d03fb3a82460 100644 ---- a/drivers/irqchip/irq-gic-v3-its.c -+++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -3161,6 +3161,7 @@ static void its_cpu_init_lpis(void) - val |= GICR_CTLR_ENABLE_LPIS; - writel_relaxed(val, rbase + GICR_CTLR); - -+out: - if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) { - void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); - -@@ -3196,7 +3197,6 @@ static void its_cpu_init_lpis(void) - - /* Make sure the GIC has seen the above */ - dsb(sy); --out: - gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED; - pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", - smp_processor_id(), -diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c -index 2f4784860df5d..be5e19a86ac3b 100644 ---- a/drivers/irqchip/irq-sifive-plic.c -+++ b/drivers/irqchip/irq-sifive-plic.c -@@ -144,7 +144,13 @@ static void plic_irq_eoi(struct irq_data *d) - { - struct plic_handler *handler = this_cpu_ptr(&plic_handlers); - -- writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); -+ if (unlikely(irqd_irq_disabled(d))) { -+ plic_toggle(handler, d->hwirq, 1); -+ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); -+ plic_toggle(handler, d->hwirq, 0); -+ } else { -+ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); -+ } - } - - #ifdef CONFIG_SMP -diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c -index 0e6068ee783e7..3e215aa85b99a 100644 ---- a/drivers/md/dm-crypt.c -+++ b/drivers/md/dm-crypt.c -@@ -61,6 +61,8 @@ struct convert_context { - struct skcipher_request *req; - struct aead_request *req_aead; - } r; -+ bool aead_recheck; -+ bool aead_failed; - - }; - -@@ -81,6 +83,8 @@ struct dm_crypt_io { - blk_status_t error; - sector_t sector; - -+ struct bvec_iter saved_bi_iter; -+ - struct rb_node rb_node; - } CRYPTO_MINALIGN_ATTR; - -@@ -1365,10 +1369,13 @@ static int crypt_convert_block_aead(struct crypt_config *cc, - if (r == -EBADMSG) { - sector_t s = le64_to_cpu(*sector); - -- DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", -- ctx->bio_in->bi_bdev, s); -- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", -- ctx->bio_in, s, 0); -+ ctx->aead_failed = true; -+ if (ctx->aead_recheck) { -+ DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", -+ ctx->bio_in->bi_bdev, s); -+ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", -+ ctx->bio_in, s, 0); -+ } - } - - if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) -@@ -1724,6 +1731,8 @@ static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc, - io->base_bio = bio; - io->sector = sector; - io->error = 0; -+ io->ctx.aead_recheck = false; -+ io->ctx.aead_failed = false; - io->ctx.r.req = NULL; - io->integrity_metadata = NULL; - io->integrity_metadata_from_pool = false; -@@ -1735,6 +1744,8 @@ static void crypt_inc_pending(struct dm_crypt_io *io) - atomic_inc(&io->io_pending); - } - -+static void kcryptd_queue_read(struct dm_crypt_io *io); -+ - /* - * One of the bios was finished. Check for completion of - * the whole request and correctly clean up the buffer. -@@ -1748,6 +1759,15 @@ static void crypt_dec_pending(struct dm_crypt_io *io) - if (!atomic_dec_and_test(&io->io_pending)) - return; - -+ if (likely(!io->ctx.aead_recheck) && unlikely(io->ctx.aead_failed) && -+ cc->on_disk_tag_size && bio_data_dir(base_bio) == READ) { -+ io->ctx.aead_recheck = true; -+ io->ctx.aead_failed = false; -+ io->error = 0; -+ kcryptd_queue_read(io); -+ return; -+ } -+ - if (io->ctx.r.req) - crypt_free_req(cc, io->ctx.r.req, base_bio); - -@@ -1783,15 +1803,19 @@ static void crypt_endio(struct bio *clone) - struct dm_crypt_io *io = clone->bi_private; - struct crypt_config *cc = io->cc; - unsigned int rw = bio_data_dir(clone); -- blk_status_t error; -+ blk_status_t error = clone->bi_status; -+ -+ if (io->ctx.aead_recheck && !error) { -+ kcryptd_queue_crypt(io); -+ return; -+ } - - /* - * free the processed pages - */ -- if (rw == WRITE) -+ if (rw == WRITE || io->ctx.aead_recheck) - crypt_free_buffer_pages(cc, clone); - -- error = clone->bi_status; - bio_put(clone); - - if (rw == READ && !error) { -@@ -1812,6 +1836,22 @@ static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp) - struct crypt_config *cc = io->cc; - struct bio *clone; - -+ if (io->ctx.aead_recheck) { -+ if (!(gfp & __GFP_DIRECT_RECLAIM)) -+ return 1; -+ crypt_inc_pending(io); -+ clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); -+ if (unlikely(!clone)) { -+ crypt_dec_pending(io); -+ return 1; -+ } -+ clone->bi_iter.bi_sector = cc->start + io->sector; -+ crypt_convert_init(cc, &io->ctx, clone, clone, io->sector); -+ io->saved_bi_iter = clone->bi_iter; -+ dm_submit_bio_remap(io->base_bio, clone); -+ return 0; -+ } -+ - /* - * We need the original biovec array in order to decrypt the whole bio - * data *afterwards* -- thanks to immutable biovecs we don't need to -@@ -2038,6 +2078,12 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) - io->ctx.bio_out = clone; - io->ctx.iter_out = clone->bi_iter; - -+ if (crypt_integrity_aead(cc)) { -+ bio_copy_data(clone, io->base_bio); -+ io->ctx.bio_in = clone; -+ io->ctx.iter_in = clone->bi_iter; -+ } -+ - sector += bio_sectors(clone); - - crypt_inc_pending(io); -@@ -2074,6 +2120,14 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) - - static void kcryptd_crypt_read_done(struct dm_crypt_io *io) - { -+ if (io->ctx.aead_recheck) { -+ if (!io->error) { -+ io->ctx.bio_in->bi_iter = io->saved_bi_iter; -+ bio_copy_data(io->base_bio, io->ctx.bio_in); -+ } -+ crypt_free_buffer_pages(io->cc, io->ctx.bio_in); -+ bio_put(io->ctx.bio_in); -+ } - crypt_dec_pending(io); - } - -@@ -2103,11 +2157,17 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) - - crypt_inc_pending(io); - -- crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, -- io->sector); -+ if (io->ctx.aead_recheck) { -+ io->ctx.cc_sector = io->sector + cc->iv_offset; -+ r = crypt_convert(cc, &io->ctx, -+ test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); -+ } else { -+ crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, -+ io->sector); - -- r = crypt_convert(cc, &io->ctx, -- test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); -+ r = crypt_convert(cc, &io->ctx, -+ test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); -+ } - /* - * Crypto API backlogged the request, because its queue was full - * and we're in softirq context, so continue from a workqueue -@@ -2150,10 +2210,13 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, - if (error == -EBADMSG) { - sector_t s = le64_to_cpu(*org_sector_of_dmreq(cc, dmreq)); - -- DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", -- ctx->bio_in->bi_bdev, s); -- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", -- ctx->bio_in, s, 0); -+ ctx->aead_failed = true; -+ if (ctx->aead_recheck) { -+ DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", -+ ctx->bio_in->bi_bdev, s); -+ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", -+ ctx->bio_in, s, 0); -+ } - io->error = BLK_STS_PROTECTION; - } else if (error < 0) - io->error = BLK_STS_IOERR; -@@ -3079,7 +3142,7 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar - sval = strchr(opt_string + strlen("integrity:"), ':') + 1; - if (!strcasecmp(sval, "aead")) { - set_bit(CRYPT_MODE_INTEGRITY_AEAD, &cc->cipher_flags); -- } else if (strcasecmp(sval, "none")) { -+ } else if (strcasecmp(sval, "none")) { - ti->error = "Unknown integrity profile"; - return -EINVAL; - } -diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c -index 77fcff82c82ac..3da4359f51645 100644 ---- a/drivers/md/dm-integrity.c -+++ b/drivers/md/dm-integrity.c -@@ -279,6 +279,8 @@ struct dm_integrity_c { - - atomic64_t number_of_mismatches; - -+ mempool_t recheck_pool; -+ - struct notifier_block reboot_notifier; - }; - -@@ -1699,6 +1701,77 @@ static void integrity_sector_checksum(struct dm_integrity_c *ic, sector_t sector - get_random_bytes(result, ic->tag_size); - } - -+static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checksum) -+{ -+ struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); -+ struct dm_integrity_c *ic = dio->ic; -+ struct bvec_iter iter; -+ struct bio_vec bv; -+ sector_t sector, logical_sector, area, offset; -+ struct page *page; -+ void *buffer; -+ -+ get_area_and_offset(ic, dio->range.logical_sector, &area, &offset); -+ dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset, -+ &dio->metadata_offset); -+ sector = get_data_sector(ic, area, offset); -+ logical_sector = dio->range.logical_sector; -+ -+ page = mempool_alloc(&ic->recheck_pool, GFP_NOIO); -+ buffer = page_to_virt(page); -+ -+ __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { -+ unsigned pos = 0; -+ -+ do { -+ char *mem; -+ int r; -+ struct dm_io_request io_req; -+ struct dm_io_region io_loc; -+ io_req.bi_opf = REQ_OP_READ; -+ io_req.mem.type = DM_IO_KMEM; -+ io_req.mem.ptr.addr = buffer; -+ io_req.notify.fn = NULL; -+ io_req.client = ic->io; -+ io_loc.bdev = ic->dev->bdev; -+ io_loc.sector = sector; -+ io_loc.count = ic->sectors_per_block; -+ -+ r = dm_io(&io_req, 1, &io_loc, NULL); -+ if (unlikely(r)) { -+ dio->bi_status = errno_to_blk_status(r); -+ goto free_ret; -+ } -+ -+ integrity_sector_checksum(ic, logical_sector, buffer, checksum); -+ r = dm_integrity_rw_tag(ic, checksum, &dio->metadata_block, -+ &dio->metadata_offset, ic->tag_size, TAG_CMP); -+ if (r) { -+ if (r > 0) { -+ DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx", -+ bio->bi_bdev, logical_sector); -+ atomic64_inc(&ic->number_of_mismatches); -+ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-checksum", -+ bio, logical_sector, 0); -+ r = -EILSEQ; -+ } -+ dio->bi_status = errno_to_blk_status(r); -+ goto free_ret; -+ } -+ -+ mem = bvec_kmap_local(&bv); -+ memcpy(mem + pos, buffer, ic->sectors_per_block << SECTOR_SHIFT); -+ kunmap_local(mem); -+ -+ pos += ic->sectors_per_block << SECTOR_SHIFT; -+ sector += ic->sectors_per_block; -+ logical_sector += ic->sectors_per_block; -+ } while (pos < bv.bv_len); -+ } -+free_ret: -+ mempool_free(page, &ic->recheck_pool); -+} -+ - static void integrity_metadata(struct work_struct *w) - { - struct dm_integrity_io *dio = container_of(w, struct dm_integrity_io, work); -@@ -1784,15 +1857,8 @@ static void integrity_metadata(struct work_struct *w) - checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE); - if (unlikely(r)) { - if (r > 0) { -- sector_t s; -- -- s = sector - ((r + ic->tag_size - 1) / ic->tag_size); -- DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx", -- bio->bi_bdev, s); -- r = -EILSEQ; -- atomic64_inc(&ic->number_of_mismatches); -- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-checksum", -- bio, s, 0); -+ integrity_recheck(dio, checksums); -+ goto skip_io; - } - if (likely(checksums != checksums_onstack)) - kfree(checksums); -@@ -4208,6 +4274,12 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv - goto bad; - } - -+ r = mempool_init_page_pool(&ic->recheck_pool, 1, 0); -+ if (r) { -+ ti->error = "Cannot allocate mempool"; -+ goto bad; -+ } -+ - ic->metadata_wq = alloc_workqueue("dm-integrity-metadata", - WQ_MEM_RECLAIM, METADATA_WORKQUEUE_MAX_ACTIVE); - if (!ic->metadata_wq) { -@@ -4572,6 +4644,7 @@ static void dm_integrity_dtr(struct dm_target *ti) - kvfree(ic->bbs); - if (ic->bufio) - dm_bufio_client_destroy(ic->bufio); -+ mempool_exit(&ic->recheck_pool); - mempool_exit(&ic->journal_io_mempool); - if (ic->io) - dm_io_client_destroy(ic->io); -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index 4669923f4cfb4..b48e1b59e6da4 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -474,6 +474,63 @@ int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, - return 0; - } - -+static int verity_recheck_copy(struct dm_verity *v, struct dm_verity_io *io, -+ u8 *data, size_t len) -+{ -+ memcpy(data, io->recheck_buffer, len); -+ io->recheck_buffer += len; -+ -+ return 0; -+} -+ -+static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, -+ struct bvec_iter start, sector_t cur_block) -+{ -+ struct page *page; -+ void *buffer; -+ int r; -+ struct dm_io_request io_req; -+ struct dm_io_region io_loc; -+ -+ page = mempool_alloc(&v->recheck_pool, GFP_NOIO); -+ buffer = page_to_virt(page); -+ -+ io_req.bi_opf = REQ_OP_READ; -+ io_req.mem.type = DM_IO_KMEM; -+ io_req.mem.ptr.addr = buffer; -+ io_req.notify.fn = NULL; -+ io_req.client = v->io; -+ io_loc.bdev = v->data_dev->bdev; -+ io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT); -+ io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT); -+ r = dm_io(&io_req, 1, &io_loc, NULL); -+ if (unlikely(r)) -+ goto free_ret; -+ -+ r = verity_hash(v, verity_io_hash_req(v, io), buffer, -+ 1 << v->data_dev_block_bits, -+ verity_io_real_digest(v, io), true); -+ if (unlikely(r)) -+ goto free_ret; -+ -+ if (memcmp(verity_io_real_digest(v, io), -+ verity_io_want_digest(v, io), v->digest_size)) { -+ r = -EIO; -+ goto free_ret; -+ } -+ -+ io->recheck_buffer = buffer; -+ r = verity_for_bv_block(v, io, &start, verity_recheck_copy); -+ if (unlikely(r)) -+ goto free_ret; -+ -+ r = 0; -+free_ret: -+ mempool_free(page, &v->recheck_pool); -+ -+ return r; -+} -+ - static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io, - u8 *data, size_t len) - { -@@ -500,9 +557,7 @@ static int verity_verify_io(struct dm_verity_io *io) - { - bool is_zero; - struct dm_verity *v = io->v; --#if defined(CONFIG_DM_VERITY_FEC) - struct bvec_iter start; --#endif - struct bvec_iter iter_copy; - struct bvec_iter *iter; - struct crypto_wait wait; -@@ -553,10 +608,7 @@ static int verity_verify_io(struct dm_verity_io *io) - if (unlikely(r < 0)) - return r; - --#if defined(CONFIG_DM_VERITY_FEC) -- if (verity_fec_is_enabled(v)) -- start = *iter; --#endif -+ start = *iter; - r = verity_for_io_block(v, io, iter, &wait); - if (unlikely(r < 0)) - return r; -@@ -578,6 +630,10 @@ static int verity_verify_io(struct dm_verity_io *io) - * tasklet since it may sleep, so fallback to work-queue. - */ - return -EAGAIN; -+ } else if (verity_recheck(v, io, start, cur_block) == 0) { -+ if (v->validated_blocks) -+ set_bit(cur_block, v->validated_blocks); -+ continue; - #if defined(CONFIG_DM_VERITY_FEC) - } else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, - cur_block, NULL, &start) == 0) { -@@ -928,6 +984,10 @@ static void verity_dtr(struct dm_target *ti) - if (v->verify_wq) - destroy_workqueue(v->verify_wq); - -+ mempool_exit(&v->recheck_pool); -+ if (v->io) -+ dm_io_client_destroy(v->io); -+ - if (v->bufio) - dm_bufio_client_destroy(v->bufio); - -@@ -1364,6 +1424,20 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) - } - v->hash_blocks = hash_position; - -+ r = mempool_init_page_pool(&v->recheck_pool, 1, 0); -+ if (unlikely(r)) { -+ ti->error = "Cannot allocate mempool"; -+ goto bad; -+ } -+ -+ v->io = dm_io_client_create(); -+ if (IS_ERR(v->io)) { -+ r = PTR_ERR(v->io); -+ v->io = NULL; -+ ti->error = "Cannot allocate dm io"; -+ goto bad; -+ } -+ - v->bufio = dm_bufio_client_create(v->hash_dev->bdev, - 1 << v->hash_dev_block_bits, 1, sizeof(struct buffer_aux), - dm_bufio_alloc_callback, NULL, -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index f3f6070084196..4620a98c99561 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -11,6 +11,7 @@ - #ifndef DM_VERITY_H - #define DM_VERITY_H - -+#include - #include - #include - #include -@@ -68,6 +69,9 @@ struct dm_verity { - unsigned long *validated_blocks; /* bitset blocks validated */ - - char *signature_key_desc; /* signature keyring reference */ -+ -+ struct dm_io_client *io; -+ mempool_t recheck_pool; - }; - - struct dm_verity_io { -@@ -84,6 +88,8 @@ struct dm_verity_io { - - struct work_struct work; - -+ char *recheck_buffer; -+ - /* - * Three variably-size fields follow this struct: - * -diff --git a/drivers/md/md.c b/drivers/md/md.c -index c7efe15229514..846bdee4daa0e 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -564,8 +564,12 @@ static void submit_flushes(struct work_struct *ws) - rcu_read_lock(); - } - rcu_read_unlock(); -- if (atomic_dec_and_test(&mddev->flush_pending)) -+ if (atomic_dec_and_test(&mddev->flush_pending)) { -+ /* The pair is percpu_ref_get() from md_flush_request() */ -+ percpu_ref_put(&mddev->active_io); -+ - queue_work(md_wq, &mddev->flush_work); -+ } - } - - static void md_submit_flush_data(struct work_struct *ws) -diff --git a/drivers/misc/open-dice.c b/drivers/misc/open-dice.c -index c61be3404c6f2..504b836a7abf8 100644 ---- a/drivers/misc/open-dice.c -+++ b/drivers/misc/open-dice.c -@@ -142,7 +142,6 @@ static int __init open_dice_probe(struct platform_device *pdev) - return -ENOMEM; - - *drvdata = (struct open_dice_drvdata){ -- .lock = __MUTEX_INITIALIZER(drvdata->lock), - .rmem = rmem, - .misc = (struct miscdevice){ - .parent = dev, -@@ -152,6 +151,7 @@ static int __init open_dice_probe(struct platform_device *pdev) - .mode = 0600, - }, - }; -+ mutex_init(&drvdata->lock); - - /* Index overflow check not needed, misc_register() will fail. */ - snprintf(drvdata->name, sizeof(drvdata->name), DRIVER_NAME"%u", dev_idx++); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -index 3784347b6fd88..55639c133dd02 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -@@ -437,6 +437,10 @@ static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, - return; - } - -+ /* AF modifies given action iff PF/VF has requested for it */ -+ if ((entry->action & 0xFULL) != NIX_RX_ACTION_DEFAULT) -+ return; -+ - /* copy VF default entry action to the VF mcam entry */ - rx_action = npc_get_default_entry_action(rvu, mcam, blkaddr, - target_func); -diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c -index 3423c95cc84ae..7031f41287e09 100644 ---- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c -+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c -@@ -744,6 +744,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev) - platform_set_drvdata(pdev, sparx5); - sparx5->pdev = pdev; - sparx5->dev = &pdev->dev; -+ spin_lock_init(&sparx5->tx_lock); - - /* Do switch core reset if available */ - reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch"); -diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h -index 7a83222caa737..cb3173d2b0e8d 100644 ---- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h -+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h -@@ -278,6 +278,7 @@ struct sparx5 { - int xtr_irq; - /* Frame DMA */ - int fdma_irq; -+ spinlock_t tx_lock; /* lock for frame transmission */ - struct sparx5_rx rx; - struct sparx5_tx tx; - /* PTP */ -diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c -index 6db6ac6a3bbc2..ac7e1cffbcecf 100644 ---- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c -+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c -@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev) - } - - skb_tx_timestamp(skb); -+ spin_lock(&sparx5->tx_lock); - if (sparx5->fdma_irq > 0) - ret = sparx5_fdma_xmit(sparx5, ifh, skb); - else - ret = sparx5_inject(sparx5, ifh, skb, dev); -+ spin_unlock(&sparx5->tx_lock); - - if (ret == -EBUSY) - goto busy; -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 66178ce6d000e..91b2aa81914ba 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5823,11 +5823,6 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id) - struct net_device *dev = (struct net_device *)dev_id; - struct stmmac_priv *priv = netdev_priv(dev); - -- if (unlikely(!dev)) { -- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -- return IRQ_NONE; -- } -- - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) - return IRQ_HANDLED; -@@ -5843,11 +5838,6 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id) - struct net_device *dev = (struct net_device *)dev_id; - struct stmmac_priv *priv = netdev_priv(dev); - -- if (unlikely(!dev)) { -- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -- return IRQ_NONE; -- } -- - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) - return IRQ_HANDLED; -@@ -5869,11 +5859,6 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void *data) - dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]); - priv = container_of(dma_conf, struct stmmac_priv, dma_conf); - -- if (unlikely(!data)) { -- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -- return IRQ_NONE; -- } -- - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) - return IRQ_HANDLED; -@@ -5900,11 +5885,6 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data) - dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]); - priv = container_of(dma_conf, struct stmmac_priv, dma_conf); - -- if (unlikely(!data)) { -- netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); -- return IRQ_NONE; -- } -- - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) - return IRQ_HANDLED; -diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c -index bace989591f75..937dd9cf4fbaf 100644 ---- a/drivers/net/gtp.c -+++ b/drivers/net/gtp.c -@@ -1906,20 +1906,20 @@ static int __init gtp_init(void) - if (err < 0) - goto error_out; - -- err = genl_register_family(>p_genl_family); -+ err = register_pernet_subsys(>p_net_ops); - if (err < 0) - goto unreg_rtnl_link; - -- err = register_pernet_subsys(>p_net_ops); -+ err = genl_register_family(>p_genl_family); - if (err < 0) -- goto unreg_genl_family; -+ goto unreg_pernet_subsys; - - pr_info("GTP module loaded (pdp ctx size %zd bytes)\n", - sizeof(struct pdp_ctx)); - return 0; - --unreg_genl_family: -- genl_unregister_family(>p_genl_family); -+unreg_pernet_subsys: -+ unregister_pernet_subsys(>p_net_ops); - unreg_rtnl_link: - rtnl_link_unregister(>p_link_ops); - error_out: -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index 3d99fd6664d7a..70e52d27064ec 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -414,9 +414,11 @@ static int rtl8211f_config_init(struct phy_device *phydev) - ERR_PTR(ret)); - return ret; - } -+ -+ return genphy_soft_reset(phydev); - } - -- return genphy_soft_reset(phydev); -+ return 0; - } - - static int rtl821x_resume(struct phy_device *phydev) -diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c -index 177a365b8ec55..3dbf926fd99fd 100644 ---- a/drivers/nvme/host/fc.c -+++ b/drivers/nvme/host/fc.c -@@ -221,11 +221,6 @@ static LIST_HEAD(nvme_fc_lport_list); - static DEFINE_IDA(nvme_fc_local_port_cnt); - static DEFINE_IDA(nvme_fc_ctrl_cnt); - --static struct workqueue_struct *nvme_fc_wq; -- --static bool nvme_fc_waiting_to_unload; --static DECLARE_COMPLETION(nvme_fc_unload_proceed); -- - /* - * These items are short-term. They will eventually be moved into - * a generic FC class. See comments in module init. -@@ -255,8 +250,6 @@ nvme_fc_free_lport(struct kref *ref) - /* remove from transport list */ - spin_lock_irqsave(&nvme_fc_lock, flags); - list_del(&lport->port_list); -- if (nvme_fc_waiting_to_unload && list_empty(&nvme_fc_lport_list)) -- complete(&nvme_fc_unload_proceed); - spin_unlock_irqrestore(&nvme_fc_lock, flags); - - ida_free(&nvme_fc_local_port_cnt, lport->localport.port_num); -@@ -3869,10 +3862,6 @@ static int __init nvme_fc_init_module(void) - { - int ret; - -- nvme_fc_wq = alloc_workqueue("nvme_fc_wq", WQ_MEM_RECLAIM, 0); -- if (!nvme_fc_wq) -- return -ENOMEM; -- - /* - * NOTE: - * It is expected that in the future the kernel will combine -@@ -3890,7 +3879,7 @@ static int __init nvme_fc_init_module(void) - ret = class_register(&fc_class); - if (ret) { - pr_err("couldn't register class fc\n"); -- goto out_destroy_wq; -+ return ret; - } - - /* -@@ -3914,8 +3903,6 @@ static int __init nvme_fc_init_module(void) - device_destroy(&fc_class, MKDEV(0, 0)); - out_destroy_class: - class_unregister(&fc_class); --out_destroy_wq: -- destroy_workqueue(nvme_fc_wq); - - return ret; - } -@@ -3935,45 +3922,23 @@ nvme_fc_delete_controllers(struct nvme_fc_rport *rport) - spin_unlock(&rport->lock); - } - --static void --nvme_fc_cleanup_for_unload(void) -+static void __exit nvme_fc_exit_module(void) - { - struct nvme_fc_lport *lport; - struct nvme_fc_rport *rport; -- -- list_for_each_entry(lport, &nvme_fc_lport_list, port_list) { -- list_for_each_entry(rport, &lport->endp_list, endp_list) { -- nvme_fc_delete_controllers(rport); -- } -- } --} -- --static void __exit nvme_fc_exit_module(void) --{ - unsigned long flags; -- bool need_cleanup = false; - - spin_lock_irqsave(&nvme_fc_lock, flags); -- nvme_fc_waiting_to_unload = true; -- if (!list_empty(&nvme_fc_lport_list)) { -- need_cleanup = true; -- nvme_fc_cleanup_for_unload(); -- } -+ list_for_each_entry(lport, &nvme_fc_lport_list, port_list) -+ list_for_each_entry(rport, &lport->endp_list, endp_list) -+ nvme_fc_delete_controllers(rport); - spin_unlock_irqrestore(&nvme_fc_lock, flags); -- if (need_cleanup) { -- pr_info("%s: waiting for ctlr deletes\n", __func__); -- wait_for_completion(&nvme_fc_unload_proceed); -- pr_info("%s: ctrl deletes complete\n", __func__); -- } -+ flush_workqueue(nvme_delete_wq); - - nvmf_unregister_transport(&nvme_fc_transport); - -- ida_destroy(&nvme_fc_local_port_cnt); -- ida_destroy(&nvme_fc_ctrl_cnt); -- - device_destroy(&fc_class, MKDEV(0, 0)); - class_unregister(&fc_class); -- destroy_workqueue(nvme_fc_wq); - } - - module_init(nvme_fc_init_module); -diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c -index 1ab6601fdd5cf..8a02ed63b1566 100644 ---- a/drivers/nvme/target/fc.c -+++ b/drivers/nvme/target/fc.c -@@ -111,6 +111,8 @@ struct nvmet_fc_tgtport { - struct nvmet_fc_port_entry *pe; - struct kref ref; - u32 max_sg_cnt; -+ -+ struct work_struct put_work; - }; - - struct nvmet_fc_port_entry { -@@ -165,7 +167,7 @@ struct nvmet_fc_tgt_assoc { - struct nvmet_fc_hostport *hostport; - struct nvmet_fc_ls_iod *rcv_disconn; - struct list_head a_list; -- struct nvmet_fc_tgt_queue __rcu *queues[NVMET_NR_QUEUES + 1]; -+ struct nvmet_fc_tgt_queue *queues[NVMET_NR_QUEUES + 1]; - struct kref ref; - struct work_struct del_work; - struct rcu_head rcu; -@@ -248,6 +250,13 @@ static int nvmet_fc_tgt_a_get(struct nvmet_fc_tgt_assoc *assoc); - static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); - static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); - static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); -+static void nvmet_fc_put_tgtport_work(struct work_struct *work) -+{ -+ struct nvmet_fc_tgtport *tgtport = -+ container_of(work, struct nvmet_fc_tgtport, put_work); -+ -+ nvmet_fc_tgtport_put(tgtport); -+} - static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); - static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, - struct nvmet_fc_fcp_iod *fod); -@@ -359,7 +368,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) - - if (!lsop->req_queued) { - spin_unlock_irqrestore(&tgtport->lock, flags); -- return; -+ goto out_putwork; - } - - list_del(&lsop->lsreq_list); -@@ -372,7 +381,8 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) - (lsreq->rqstlen + lsreq->rsplen), - DMA_BIDIRECTIONAL); - -- nvmet_fc_tgtport_put(tgtport); -+out_putwork: -+ queue_work(nvmet_wq, &tgtport->put_work); - } - - static int -@@ -801,14 +811,11 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, - if (!queue) - return NULL; - -- if (!nvmet_fc_tgt_a_get(assoc)) -- goto out_free_queue; -- - queue->work_q = alloc_workqueue("ntfc%d.%d.%d", 0, 0, - assoc->tgtport->fc_target_port.port_num, - assoc->a_id, qid); - if (!queue->work_q) -- goto out_a_put; -+ goto out_free_queue; - - queue->qid = qid; - queue->sqsize = sqsize; -@@ -830,15 +837,13 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, - goto out_fail_iodlist; - - WARN_ON(assoc->queues[qid]); -- rcu_assign_pointer(assoc->queues[qid], queue); -+ assoc->queues[qid] = queue; - - return queue; - - out_fail_iodlist: - nvmet_fc_destroy_fcp_iodlist(assoc->tgtport, queue); - destroy_workqueue(queue->work_q); --out_a_put: -- nvmet_fc_tgt_a_put(assoc); - out_free_queue: - kfree(queue); - return NULL; -@@ -851,12 +856,8 @@ nvmet_fc_tgt_queue_free(struct kref *ref) - struct nvmet_fc_tgt_queue *queue = - container_of(ref, struct nvmet_fc_tgt_queue, ref); - -- rcu_assign_pointer(queue->assoc->queues[queue->qid], NULL); -- - nvmet_fc_destroy_fcp_iodlist(queue->assoc->tgtport, queue); - -- nvmet_fc_tgt_a_put(queue->assoc); -- - destroy_workqueue(queue->work_q); - - kfree_rcu(queue, rcu); -@@ -968,7 +969,7 @@ nvmet_fc_find_target_queue(struct nvmet_fc_tgtport *tgtport, - rcu_read_lock(); - list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { - if (association_id == assoc->association_id) { -- queue = rcu_dereference(assoc->queues[qid]); -+ queue = assoc->queues[qid]; - if (queue && - (!atomic_read(&queue->connected) || - !nvmet_fc_tgt_q_get(queue))) -@@ -1077,8 +1078,6 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) - /* new allocation not needed */ - kfree(newhost); - newhost = match; -- /* no new allocation - release reference */ -- nvmet_fc_tgtport_put(tgtport); - } else { - newhost->tgtport = tgtport; - newhost->hosthandle = hosthandle; -@@ -1093,13 +1092,28 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) - } - - static void --nvmet_fc_delete_assoc(struct work_struct *work) -+nvmet_fc_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) -+{ -+ nvmet_fc_delete_target_assoc(assoc); -+ nvmet_fc_tgt_a_put(assoc); -+} -+ -+static void -+nvmet_fc_delete_assoc_work(struct work_struct *work) - { - struct nvmet_fc_tgt_assoc *assoc = - container_of(work, struct nvmet_fc_tgt_assoc, del_work); -+ struct nvmet_fc_tgtport *tgtport = assoc->tgtport; - -- nvmet_fc_delete_target_assoc(assoc); -- nvmet_fc_tgt_a_put(assoc); -+ nvmet_fc_delete_assoc(assoc); -+ nvmet_fc_tgtport_put(tgtport); -+} -+ -+static void -+nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) -+{ -+ nvmet_fc_tgtport_get(assoc->tgtport); -+ queue_work(nvmet_wq, &assoc->del_work); - } - - static struct nvmet_fc_tgt_assoc * -@@ -1111,6 +1125,9 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) - int idx; - bool needrandom = true; - -+ if (!tgtport->pe) -+ return NULL; -+ - assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); - if (!assoc) - return NULL; -@@ -1130,7 +1147,7 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) - assoc->a_id = idx; - INIT_LIST_HEAD(&assoc->a_list); - kref_init(&assoc->ref); -- INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc); -+ INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc_work); - atomic_set(&assoc->terminating, 0); - - while (needrandom) { -@@ -1171,13 +1188,18 @@ nvmet_fc_target_assoc_free(struct kref *ref) - struct nvmet_fc_tgtport *tgtport = assoc->tgtport; - struct nvmet_fc_ls_iod *oldls; - unsigned long flags; -+ int i; -+ -+ for (i = NVMET_NR_QUEUES; i >= 0; i--) { -+ if (assoc->queues[i]) -+ nvmet_fc_delete_target_queue(assoc->queues[i]); -+ } - - /* Send Disconnect now that all i/o has completed */ - nvmet_fc_xmt_disconnect_assoc(assoc); - - nvmet_fc_free_hostport(assoc->hostport); - spin_lock_irqsave(&tgtport->lock, flags); -- list_del_rcu(&assoc->a_list); - oldls = assoc->rcv_disconn; - spin_unlock_irqrestore(&tgtport->lock, flags); - /* if pending Rcv Disconnect Association LS, send rsp now */ -@@ -1207,7 +1229,7 @@ static void - nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) - { - struct nvmet_fc_tgtport *tgtport = assoc->tgtport; -- struct nvmet_fc_tgt_queue *queue; -+ unsigned long flags; - int i, terminating; - - terminating = atomic_xchg(&assoc->terminating, 1); -@@ -1216,29 +1238,21 @@ nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) - if (terminating) - return; - -+ spin_lock_irqsave(&tgtport->lock, flags); -+ list_del_rcu(&assoc->a_list); -+ spin_unlock_irqrestore(&tgtport->lock, flags); - -- for (i = NVMET_NR_QUEUES; i >= 0; i--) { -- rcu_read_lock(); -- queue = rcu_dereference(assoc->queues[i]); -- if (!queue) { -- rcu_read_unlock(); -- continue; -- } -+ synchronize_rcu(); - -- if (!nvmet_fc_tgt_q_get(queue)) { -- rcu_read_unlock(); -- continue; -- } -- rcu_read_unlock(); -- nvmet_fc_delete_target_queue(queue); -- nvmet_fc_tgt_q_put(queue); -+ /* ensure all in-flight I/Os have been processed */ -+ for (i = NVMET_NR_QUEUES; i >= 0; i--) { -+ if (assoc->queues[i]) -+ flush_workqueue(assoc->queues[i]->work_q); - } - - dev_info(tgtport->dev, - "{%d:%d} Association deleted\n", - tgtport->fc_target_port.port_num, assoc->a_id); -- -- nvmet_fc_tgt_a_put(assoc); - } - - static struct nvmet_fc_tgt_assoc * -@@ -1414,6 +1428,7 @@ nvmet_fc_register_targetport(struct nvmet_fc_port_info *pinfo, - kref_init(&newrec->ref); - ida_init(&newrec->assoc_cnt); - newrec->max_sg_cnt = template->max_sgl_segments; -+ INIT_WORK(&newrec->put_work, nvmet_fc_put_tgtport_work); - - ret = nvmet_fc_alloc_ls_iodlist(newrec); - if (ret) { -@@ -1491,9 +1506,8 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport) - list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { - if (!nvmet_fc_tgt_a_get(assoc)) - continue; -- if (!queue_work(nvmet_wq, &assoc->del_work)) -- /* already deleting - release local reference */ -- nvmet_fc_tgt_a_put(assoc); -+ nvmet_fc_schedule_delete_assoc(assoc); -+ nvmet_fc_tgt_a_put(assoc); - } - rcu_read_unlock(); - } -@@ -1546,9 +1560,8 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port, - continue; - assoc->hostport->invalid = 1; - noassoc = false; -- if (!queue_work(nvmet_wq, &assoc->del_work)) -- /* already deleting - release local reference */ -- nvmet_fc_tgt_a_put(assoc); -+ nvmet_fc_schedule_delete_assoc(assoc); -+ nvmet_fc_tgt_a_put(assoc); - } - spin_unlock_irqrestore(&tgtport->lock, flags); - -@@ -1580,7 +1593,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) - - rcu_read_lock(); - list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { -- queue = rcu_dereference(assoc->queues[0]); -+ queue = assoc->queues[0]; - if (queue && queue->nvme_sq.ctrl == ctrl) { - if (nvmet_fc_tgt_a_get(assoc)) - found_ctrl = true; -@@ -1592,9 +1605,8 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) - nvmet_fc_tgtport_put(tgtport); - - if (found_ctrl) { -- if (!queue_work(nvmet_wq, &assoc->del_work)) -- /* already deleting - release local reference */ -- nvmet_fc_tgt_a_put(assoc); -+ nvmet_fc_schedule_delete_assoc(assoc); -+ nvmet_fc_tgt_a_put(assoc); - return; - } - -@@ -1624,6 +1636,8 @@ nvmet_fc_unregister_targetport(struct nvmet_fc_target_port *target_port) - /* terminate any outstanding associations */ - __nvmet_fc_free_assocs(tgtport); - -+ flush_workqueue(nvmet_wq); -+ - /* - * should terminate LS's as well. However, LS's will be generated - * at the tail end of association termination, so they likely don't -@@ -1869,9 +1883,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, - sizeof(struct fcnvme_ls_disconnect_assoc_acc)), - FCNVME_LS_DISCONNECT_ASSOC); - -- /* release get taken in nvmet_fc_find_target_assoc */ -- nvmet_fc_tgt_a_put(assoc); -- - /* - * The rules for LS response says the response cannot - * go back until ABTS's have been sent for all outstanding -@@ -1886,8 +1897,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, - assoc->rcv_disconn = iod; - spin_unlock_irqrestore(&tgtport->lock, flags); - -- nvmet_fc_delete_target_assoc(assoc); -- - if (oldls) { - dev_info(tgtport->dev, - "{%d:%d} Multiple Disconnect Association LS's " -@@ -1903,6 +1912,9 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, - nvmet_fc_xmt_ls_rsp(tgtport, oldls); - } - -+ nvmet_fc_schedule_delete_assoc(assoc); -+ nvmet_fc_tgt_a_put(assoc); -+ - return false; - } - -@@ -2539,8 +2551,9 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, - - fod->req.cmd = &fod->cmdiubuf.sqe; - fod->req.cqe = &fod->rspiubuf.cqe; -- if (tgtport->pe) -- fod->req.port = tgtport->pe->port; -+ if (!tgtport->pe) -+ goto transport_error; -+ fod->req.port = tgtport->pe->port; - - /* clear any response payload */ - memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); -@@ -2901,6 +2914,9 @@ nvmet_fc_remove_port(struct nvmet_port *port) - - nvmet_fc_portentry_unbind(pe); - -+ /* terminate any outstanding associations */ -+ __nvmet_fc_free_assocs(pe->tgtport); -+ - kfree(pe); - } - -@@ -2932,6 +2948,9 @@ static int __init nvmet_fc_init_module(void) - - static void __exit nvmet_fc_exit_module(void) - { -+ /* ensure any shutdown operation, e.g. delete ctrls have finished */ -+ flush_workqueue(nvmet_wq); -+ - /* sanity check - all lports should be removed */ - if (!list_empty(&nvmet_fc_target_list)) - pr_warn("%s: targetport list not empty\n", __func__); -diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c -index c780af36c1d4a..f5b8442b653db 100644 ---- a/drivers/nvme/target/fcloop.c -+++ b/drivers/nvme/target/fcloop.c -@@ -358,7 +358,7 @@ fcloop_h2t_ls_req(struct nvme_fc_local_port *localport, - if (!rport->targetport) { - tls_req->status = -ECONNREFUSED; - spin_lock(&rport->lock); -- list_add_tail(&rport->ls_list, &tls_req->ls_list); -+ list_add_tail(&tls_req->ls_list, &rport->ls_list); - spin_unlock(&rport->lock); - queue_work(nvmet_wq, &rport->ls_work); - return ret; -@@ -391,7 +391,7 @@ fcloop_h2t_xmt_ls_rsp(struct nvmet_fc_target_port *targetport, - if (remoteport) { - rport = remoteport->private; - spin_lock(&rport->lock); -- list_add_tail(&rport->ls_list, &tls_req->ls_list); -+ list_add_tail(&tls_req->ls_list, &rport->ls_list); - spin_unlock(&rport->lock); - queue_work(nvmet_wq, &rport->ls_work); - } -@@ -446,7 +446,7 @@ fcloop_t2h_ls_req(struct nvmet_fc_target_port *targetport, void *hosthandle, - if (!tport->remoteport) { - tls_req->status = -ECONNREFUSED; - spin_lock(&tport->lock); -- list_add_tail(&tport->ls_list, &tls_req->ls_list); -+ list_add_tail(&tls_req->ls_list, &tport->ls_list); - spin_unlock(&tport->lock); - queue_work(nvmet_wq, &tport->ls_work); - return ret; -diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c -index ce42afe8f64ef..3480768274699 100644 ---- a/drivers/nvme/target/tcp.c -+++ b/drivers/nvme/target/tcp.c -@@ -1884,6 +1884,7 @@ static void __exit nvmet_tcp_exit(void) - flush_workqueue(nvmet_wq); - - destroy_workqueue(nvmet_tcp_wq); -+ ida_destroy(&nvmet_tcp_queue_ida); - } - - module_init(nvmet_tcp_init); -diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c -index 59c164b5c64aa..4086a7818981a 100644 ---- a/drivers/pci/controller/dwc/pcie-designware-ep.c -+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c -@@ -6,6 +6,7 @@ - * Author: Kishon Vijay Abraham I - */ - -+#include - #include - #include - -@@ -600,7 +601,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, - } - - aligned_offset = msg_addr & (epc->mem->window.page_size - 1); -- msg_addr &= ~aligned_offset; -+ msg_addr = ALIGN_DOWN(msg_addr, epc->mem->window.page_size); - ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, - epc->mem->window.page_size); - if (ret) -diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c -index e9cf318e6670f..34877a1f43a15 100644 ---- a/drivers/pci/msi/irqdomain.c -+++ b/drivers/pci/msi/irqdomain.c -@@ -60,7 +60,7 @@ static irq_hw_number_t pci_msi_domain_calc_hwirq(struct msi_desc *desc) - - return (irq_hw_number_t)desc->msi_index | - pci_dev_id(dev) << 11 | -- (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; -+ ((irq_hw_number_t)(pci_domain_nr(dev->bus) & 0xFFFFFFFF)) << 27; - } - - static inline bool pci_msi_desc_is_multi_msi(struct msi_desc *desc) -diff --git a/drivers/platform/x86/intel/vbtn.c b/drivers/platform/x86/intel/vbtn.c -index 8e2b07ed2ce94..c10c99a31a90a 100644 ---- a/drivers/platform/x86/intel/vbtn.c -+++ b/drivers/platform/x86/intel/vbtn.c -@@ -200,9 +200,6 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) - autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE); - - sparse_keymap_report_event(input_dev, event, val, autorelease); -- -- /* Some devices need this to report further events */ -- acpi_evaluate_object(handle, "VBDL", NULL, NULL); - } - - /* -diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index 6edd2e294750e..c2fb19af10705 100644 ---- a/drivers/platform/x86/thinkpad_acpi.c -+++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -10511,6 +10511,7 @@ static int convert_dytc_to_profile(int funcmode, int dytcmode, - return 0; - default: - /* Unknown function */ -+ pr_debug("unknown function 0x%x\n", funcmode); - return -EOPNOTSUPP; - } - return 0; -@@ -10696,8 +10697,8 @@ static void dytc_profile_refresh(void) - return; - - perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF; -- convert_dytc_to_profile(funcmode, perfmode, &profile); -- if (profile != dytc_current_profile) { -+ err = convert_dytc_to_profile(funcmode, perfmode, &profile); -+ if (!err && profile != dytc_current_profile) { - dytc_current_profile = profile; - platform_profile_notify(); - } -diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c -index 9a92d515abb9b..11d72a3533552 100644 ---- a/drivers/platform/x86/touchscreen_dmi.c -+++ b/drivers/platform/x86/touchscreen_dmi.c -@@ -50,7 +50,7 @@ static const struct property_entry chuwi_hi8_air_props[] = { - }; - - static const struct ts_dmi_data chuwi_hi8_air_data = { -- .acpi_name = "MSSL1680:00", -+ .acpi_name = "MSSL1680", - .properties = chuwi_hi8_air_props, - }; - -@@ -913,6 +913,32 @@ static const struct ts_dmi_data teclast_tbook11_data = { - .properties = teclast_tbook11_props, - }; - -+static const struct property_entry teclast_x16_plus_props[] = { -+ PROPERTY_ENTRY_U32("touchscreen-min-x", 8), -+ PROPERTY_ENTRY_U32("touchscreen-min-y", 14), -+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1916), -+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1264), -+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), -+ PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"), -+ PROPERTY_ENTRY_U32("silead,max-fingers", 10), -+ PROPERTY_ENTRY_BOOL("silead,home-button"), -+ { } -+}; -+ -+static const struct ts_dmi_data teclast_x16_plus_data = { -+ .embedded_fw = { -+ .name = "silead/gsl3692-teclast-x16-plus.fw", -+ .prefix = { 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, -+ .length = 43560, -+ .sha256 = { 0x9d, 0xb0, 0x3d, 0xf1, 0x00, 0x3c, 0xb5, 0x25, -+ 0x62, 0x8a, 0xa0, 0x93, 0x4b, 0xe0, 0x4e, 0x75, -+ 0xd1, 0x27, 0xb1, 0x65, 0x3c, 0xba, 0xa5, 0x0f, -+ 0xcd, 0xb4, 0xbe, 0x00, 0xbb, 0xf6, 0x43, 0x29 }, -+ }, -+ .acpi_name = "MSSL1680:00", -+ .properties = teclast_x16_plus_props, -+}; -+ - static const struct property_entry teclast_x3_plus_props[] = { - PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), - PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), -@@ -1567,6 +1593,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { - DMI_MATCH(DMI_PRODUCT_SKU, "E5A6_A1"), - }, - }, -+ { -+ /* Teclast X16 Plus */ -+ .driver_data = (void *)&teclast_x16_plus_data, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_MATCH(DMI_PRODUCT_SKU, "D3A5_A1"), -+ }, -+ }, - { - /* Teclast X3 Plus */ - .driver_data = (void *)&teclast_x3_plus_data, -@@ -1741,7 +1776,7 @@ static void ts_dmi_add_props(struct i2c_client *client) - int error; - - if (has_acpi_companion(dev) && -- !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) { -+ strstarts(client->name, ts_data->acpi_name)) { - error = device_create_managed_software_node(dev, ts_data->properties, NULL); - if (error) - dev_err(dev, "failed to add properties: %d\n", error); -diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c -index b9eeaff1c6615..925e486f73a6d 100644 ---- a/drivers/regulator/pwm-regulator.c -+++ b/drivers/regulator/pwm-regulator.c -@@ -158,6 +158,9 @@ static int pwm_regulator_get_voltage(struct regulator_dev *rdev) - pwm_get_state(drvdata->pwm, &pstate); - - voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit); -+ if (voltage < min(max_uV_duty, min_uV_duty) || -+ voltage > max(max_uV_duty, min_uV_duty)) -+ return -ENOTRECOVERABLE; - - /* - * The dutycycle for min_uV might be greater than the one for max_uV. -diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c -index c533d1dadc6bb..a5dba3829769c 100644 ---- a/drivers/s390/cio/device_ops.c -+++ b/drivers/s390/cio/device_ops.c -@@ -202,7 +202,8 @@ int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, - return -EINVAL; - if (cdev->private->state == DEV_STATE_NOT_OPER) - return -ENODEV; -- if (cdev->private->state == DEV_STATE_VERIFY) { -+ if (cdev->private->state == DEV_STATE_VERIFY || -+ cdev->private->flags.doverify) { - /* Remember to fake irb when finished. */ - if (!cdev->private->flags.fake_irb) { - cdev->private->flags.fake_irb = FAKE_CMD_IRB; -@@ -214,8 +215,7 @@ int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, - } - if (cdev->private->state != DEV_STATE_ONLINE || - ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) && -- !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) || -- cdev->private->flags.doverify) -+ !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS))) - return -EBUSY; - ret = cio_set_options (sch, flags); - if (ret) -diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig -index 03e71e3d5e5b3..3b990cf2c1954 100644 ---- a/drivers/scsi/Kconfig -+++ b/drivers/scsi/Kconfig -@@ -1285,7 +1285,7 @@ source "drivers/scsi/arm/Kconfig" - - config JAZZ_ESP - bool "MIPS JAZZ FAS216 SCSI support" -- depends on MACH_JAZZ && SCSI -+ depends on MACH_JAZZ && SCSI=y - select SCSI_SPI_ATTRS - help - This is the driver for the onboard SCSI host adapter of MIPS Magnum -diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index 7aac9fc719675..0bb7e164b525f 100644 ---- a/drivers/scsi/lpfc/lpfc_scsi.c -+++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -1919,7 +1919,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - * - * Returns the number of SGEs added to the SGL. - **/ --static int -+static uint32_t - lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - struct sli4_sge *sgl, int datasegcnt, - struct lpfc_io_buf *lpfc_cmd) -@@ -1927,8 +1927,8 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - struct scatterlist *sgde = NULL; /* s/g data entry */ - struct sli4_sge_diseed *diseed = NULL; - dma_addr_t physaddr; -- int i = 0, num_sge = 0, status; -- uint32_t reftag; -+ int i = 0, status; -+ uint32_t reftag, num_sge = 0; - uint8_t txop, rxop; - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - uint32_t rc; -@@ -2100,7 +2100,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - * - * Returns the number of SGEs added to the SGL. - **/ --static int -+static uint32_t - lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - struct sli4_sge *sgl, int datacnt, int protcnt, - struct lpfc_io_buf *lpfc_cmd) -@@ -2124,8 +2124,8 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - uint32_t rc; - #endif - uint32_t checking = 1; -- uint32_t dma_offset = 0; -- int num_sge = 0, j = 2; -+ uint32_t dma_offset = 0, num_sge = 0; -+ int j = 2; - struct sli4_hybrid_sgl *sgl_xtra = NULL; - - sgpe = scsi_prot_sglist(sc); -diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c -index 3cda5d26b66ca..e70ab8db30142 100644 ---- a/drivers/scsi/scsi.c -+++ b/drivers/scsi/scsi.c -@@ -328,21 +328,39 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, - return result + 4; - } - -+enum scsi_vpd_parameters { -+ SCSI_VPD_HEADER_SIZE = 4, -+ SCSI_VPD_LIST_SIZE = 36, -+}; -+ - static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page) - { -- unsigned char vpd_header[SCSI_VPD_HEADER_SIZE] __aligned(4); -+ unsigned char vpd[SCSI_VPD_LIST_SIZE] __aligned(4); - int result; - - if (sdev->no_vpd_size) - return SCSI_DEFAULT_VPD_LEN; - -+ /* -+ * Fetch the supported pages VPD and validate that the requested page -+ * number is present. -+ */ -+ if (page != 0) { -+ result = scsi_vpd_inquiry(sdev, vpd, 0, sizeof(vpd)); -+ if (result < SCSI_VPD_HEADER_SIZE) -+ return 0; -+ -+ result -= SCSI_VPD_HEADER_SIZE; -+ if (!memchr(&vpd[SCSI_VPD_HEADER_SIZE], page, result)) -+ return 0; -+ } - /* - * Fetch the VPD page header to find out how big the page - * is. This is done to prevent problems on legacy devices - * which can not handle allocation lengths as large as - * potentially requested by the caller. - */ -- result = scsi_vpd_inquiry(sdev, vpd_header, page, sizeof(vpd_header)); -+ result = scsi_vpd_inquiry(sdev, vpd, page, SCSI_VPD_HEADER_SIZE); - if (result < 0) - return 0; - -diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c -index 47d487729635c..e44f6bb25a8ea 100644 ---- a/drivers/scsi/smartpqi/smartpqi_init.c -+++ b/drivers/scsi/smartpqi/smartpqi_init.c -@@ -6449,8 +6449,11 @@ static void pqi_map_queues(struct Scsi_Host *shost) - { - struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); - -- blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], -+ if (!ctrl_info->disable_managed_interrupts) -+ return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], - ctrl_info->pci_dev, 0); -+ else -+ return blk_mq_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT]); - } - - static inline bool pqi_is_tape_changer_device(struct pqi_scsi_dev *device) -diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c -index 474b272f9b02d..832adb570b501 100644 ---- a/drivers/soc/mediatek/mtk-pm-domains.c -+++ b/drivers/soc/mediatek/mtk-pm-domains.c -@@ -499,6 +499,11 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren - goto err_put_node; - } - -+ /* recursive call to add all subdomains */ -+ ret = scpsys_add_subdomain(scpsys, child); -+ if (ret) -+ goto err_put_node; -+ - ret = pm_genpd_add_subdomain(parent_pd, child_pd); - if (ret) { - dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n", -@@ -508,11 +513,6 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren - dev_dbg(scpsys->dev, "%s add subdomain: %s\n", parent_pd->name, - child_pd->name); - } -- -- /* recursive call to add all subdomains */ -- ret = scpsys_add_subdomain(scpsys, child); -- if (ret) -- goto err_put_node; - } - - return 0; -@@ -526,9 +526,6 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd) - { - int ret; - -- if (scpsys_domain_is_on(pd)) -- scpsys_power_off(&pd->genpd); -- - /* - * We're in the error cleanup already, so we only complain, - * but won't emit another error on top of the original one. -@@ -538,6 +535,8 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd) - dev_err(pd->scpsys->dev, - "failed to remove domain '%s' : %d - state may be inconsistent\n", - pd->genpd.name, ret); -+ if (scpsys_domain_is_on(pd)) -+ scpsys_power_off(&pd->genpd); - - clk_bulk_put(pd->num_clks, pd->clks); - clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); -diff --git a/drivers/soc/renesas/r8a77980-sysc.c b/drivers/soc/renesas/r8a77980-sysc.c -index 39ca84a67daad..621e411fc9991 100644 ---- a/drivers/soc/renesas/r8a77980-sysc.c -+++ b/drivers/soc/renesas/r8a77980-sysc.c -@@ -25,7 +25,8 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = { - PD_CPU_NOCR }, - { "ca53-cpu3", 0x200, 3, R8A77980_PD_CA53_CPU3, R8A77980_PD_CA53_SCU, - PD_CPU_NOCR }, -- { "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON }, -+ { "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON, -+ PD_CPU_NOCR }, - { "a3ir", 0x180, 0, R8A77980_PD_A3IR, R8A77980_PD_ALWAYS_ON }, - { "a2ir0", 0x400, 0, R8A77980_PD_A2IR0, R8A77980_PD_A3IR }, - { "a2ir1", 0x400, 1, R8A77980_PD_A2IR1, R8A77980_PD_A3IR }, -diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c -index d3a23b1c2a4c5..61bf00dfe9c33 100644 ---- a/drivers/spi/spi-hisi-sfc-v3xx.c -+++ b/drivers/spi/spi-hisi-sfc-v3xx.c -@@ -377,6 +377,11 @@ static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = { - static irqreturn_t hisi_sfc_v3xx_isr(int irq, void *data) - { - struct hisi_sfc_v3xx_host *host = data; -+ u32 reg; -+ -+ reg = readl(host->regbase + HISI_SFC_V3XX_INT_STAT); -+ if (!reg) -+ return IRQ_NONE; - - hisi_sfc_v3xx_disable_int(host); - -diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c -index 51ceaa4857249..ec3a4939ee984 100644 ---- a/drivers/spi/spi-sh-msiof.c -+++ b/drivers/spi/spi-sh-msiof.c -@@ -137,14 +137,14 @@ struct sh_msiof_spi_priv { - - /* SIFCTR */ - #define SIFCTR_TFWM_MASK GENMASK(31, 29) /* Transmit FIFO Watermark */ --#define SIFCTR_TFWM_64 (0 << 29) /* Transfer Request when 64 empty stages */ --#define SIFCTR_TFWM_32 (1 << 29) /* Transfer Request when 32 empty stages */ --#define SIFCTR_TFWM_24 (2 << 29) /* Transfer Request when 24 empty stages */ --#define SIFCTR_TFWM_16 (3 << 29) /* Transfer Request when 16 empty stages */ --#define SIFCTR_TFWM_12 (4 << 29) /* Transfer Request when 12 empty stages */ --#define SIFCTR_TFWM_8 (5 << 29) /* Transfer Request when 8 empty stages */ --#define SIFCTR_TFWM_4 (6 << 29) /* Transfer Request when 4 empty stages */ --#define SIFCTR_TFWM_1 (7 << 29) /* Transfer Request when 1 empty stage */ -+#define SIFCTR_TFWM_64 (0UL << 29) /* Transfer Request when 64 empty stages */ -+#define SIFCTR_TFWM_32 (1UL << 29) /* Transfer Request when 32 empty stages */ -+#define SIFCTR_TFWM_24 (2UL << 29) /* Transfer Request when 24 empty stages */ -+#define SIFCTR_TFWM_16 (3UL << 29) /* Transfer Request when 16 empty stages */ -+#define SIFCTR_TFWM_12 (4UL << 29) /* Transfer Request when 12 empty stages */ -+#define SIFCTR_TFWM_8 (5UL << 29) /* Transfer Request when 8 empty stages */ -+#define SIFCTR_TFWM_4 (6UL << 29) /* Transfer Request when 4 empty stages */ -+#define SIFCTR_TFWM_1 (7UL << 29) /* Transfer Request when 1 empty stage */ - #define SIFCTR_TFUA_MASK GENMASK(26, 20) /* Transmit FIFO Usable Area */ - #define SIFCTR_TFUA_SHIFT 20 - #define SIFCTR_TFUA(i) ((i) << SIFCTR_TFUA_SHIFT) -diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c -index 301fe376a1206..13558cbd9b82e 100644 ---- a/drivers/target/target_core_device.c -+++ b/drivers/target/target_core_device.c -@@ -147,7 +147,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd) - struct se_session *se_sess = se_cmd->se_sess; - struct se_node_acl *nacl = se_sess->se_node_acl; - struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; -- unsigned long flags; - - rcu_read_lock(); - deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun); -@@ -178,10 +177,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd) - se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); - se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev); - -- spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags); -- list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list); -- spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags); -- - return 0; - } - EXPORT_SYMBOL(transport_lookup_tmr_lun); -diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c -index 69a4c9581e80e..7aec34c090661 100644 ---- a/drivers/target/target_core_pscsi.c -+++ b/drivers/target/target_core_pscsi.c -@@ -910,12 +910,15 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, - - return 0; - fail: -- if (bio) -- bio_put(bio); -+ if (bio) { -+ bio_uninit(bio); -+ kfree(bio); -+ } - while (req->bio) { - bio = req->bio; - req->bio = bio->bi_next; -- bio_put(bio); -+ bio_uninit(bio); -+ kfree(bio); - } - req->biotail = NULL; - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; -diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c -index 0686882bcbda3..fb93d74c5d0b2 100644 ---- a/drivers/target/target_core_transport.c -+++ b/drivers/target/target_core_transport.c -@@ -3627,6 +3627,10 @@ int transport_generic_handle_tmr( - unsigned long flags; - bool aborted = false; - -+ spin_lock_irqsave(&cmd->se_dev->se_tmr_lock, flags); -+ list_add_tail(&cmd->se_tmr_req->tmr_list, &cmd->se_dev->dev_tmr_list); -+ spin_unlock_irqrestore(&cmd->se_dev->se_tmr_lock, flags); -+ - spin_lock_irqsave(&cmd->t_state_lock, flags); - if (cmd->transport_state & CMD_T_ABORTED) { - aborted = true; -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index c74eaf2552c32..2f0f05259778a 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -1345,11 +1345,41 @@ static void pl011_start_tx_pio(struct uart_amba_port *uap) - } - } - -+static void pl011_rs485_tx_start(struct uart_amba_port *uap) -+{ -+ struct uart_port *port = &uap->port; -+ u32 cr; -+ -+ /* Enable transmitter */ -+ cr = pl011_read(uap, REG_CR); -+ cr |= UART011_CR_TXE; -+ -+ /* Disable receiver if half-duplex */ -+ if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) -+ cr &= ~UART011_CR_RXE; -+ -+ if (port->rs485.flags & SER_RS485_RTS_ON_SEND) -+ cr &= ~UART011_CR_RTS; -+ else -+ cr |= UART011_CR_RTS; -+ -+ pl011_write(cr, uap, REG_CR); -+ -+ if (port->rs485.delay_rts_before_send) -+ mdelay(port->rs485.delay_rts_before_send); -+ -+ uap->rs485_tx_started = true; -+} -+ - static void pl011_start_tx(struct uart_port *port) - { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); - -+ if ((uap->port.rs485.flags & SER_RS485_ENABLED) && -+ !uap->rs485_tx_started) -+ pl011_rs485_tx_start(uap); -+ - if (!pl011_dma_tx_start(uap)) - pl011_start_tx_pio(uap); - } -@@ -1431,42 +1461,12 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, - return true; - } - --static void pl011_rs485_tx_start(struct uart_amba_port *uap) --{ -- struct uart_port *port = &uap->port; -- u32 cr; -- -- /* Enable transmitter */ -- cr = pl011_read(uap, REG_CR); -- cr |= UART011_CR_TXE; -- -- /* Disable receiver if half-duplex */ -- if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) -- cr &= ~UART011_CR_RXE; -- -- if (port->rs485.flags & SER_RS485_RTS_ON_SEND) -- cr &= ~UART011_CR_RTS; -- else -- cr |= UART011_CR_RTS; -- -- pl011_write(cr, uap, REG_CR); -- -- if (port->rs485.delay_rts_before_send) -- mdelay(port->rs485.delay_rts_before_send); -- -- uap->rs485_tx_started = true; --} -- - /* Returns true if tx interrupts have to be (kept) enabled */ - static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) - { - struct circ_buf *xmit = &uap->port.state->xmit; - int count = uap->fifosize >> 1; - -- if ((uap->port.rs485.flags & SER_RS485_ENABLED) && -- !uap->rs485_tx_started) -- pl011_rs485_tx_start(uap); -- - if (uap->port.x_char) { - if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) - return true; -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index 9fd4e9ed93b8b..f3c25467e571f 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -6159,7 +6159,6 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) - ufshcd_hold(hba, false); - if (!ufshcd_is_clkgating_allowed(hba)) - ufshcd_setup_clocks(hba, true); -- ufshcd_release(hba); - pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; - ufshcd_vops_resume(hba, pm_op); - } else { -diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c -index ccdd525bd7c80..2b8f98f0707e7 100644 ---- a/drivers/usb/cdns3/cdns3-gadget.c -+++ b/drivers/usb/cdns3/cdns3-gadget.c -@@ -826,7 +826,11 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, - return; - } - -- if (request->complete) { -+ /* -+ * zlp request is appended by driver, needn't call usb_gadget_giveback_request() to notify -+ * gadget composite driver. -+ */ -+ if (request->complete && request->buf != priv_dev->zlp_buf) { - spin_unlock(&priv_dev->lock); - usb_gadget_giveback_request(&priv_ep->endpoint, - request); -@@ -2537,11 +2541,11 @@ static int cdns3_gadget_ep_disable(struct usb_ep *ep) - - while (!list_empty(&priv_ep->wa2_descmiss_req_list)) { - priv_req = cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list); -+ list_del_init(&priv_req->list); - - kfree(priv_req->request.buf); - cdns3_gadget_ep_free_request(&priv_ep->endpoint, - &priv_req->request); -- list_del_init(&priv_req->list); - --priv_ep->wa2_counter; - } - -diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c -index 7b20d2d5c262e..7242591b346bc 100644 ---- a/drivers/usb/cdns3/core.c -+++ b/drivers/usb/cdns3/core.c -@@ -394,7 +394,6 @@ static int cdns_role_set(struct usb_role_switch *sw, enum usb_role role) - return ret; - } - -- - /** - * cdns_wakeup_irq - interrupt handler for wakeup events - * @irq: irq number for cdns3/cdnsp core device -diff --git a/drivers/usb/cdns3/drd.c b/drivers/usb/cdns3/drd.c -index d00ff98dffabf..33ba30f79b337 100644 ---- a/drivers/usb/cdns3/drd.c -+++ b/drivers/usb/cdns3/drd.c -@@ -156,7 +156,8 @@ bool cdns_is_device(struct cdns *cdns) - */ - static void cdns_otg_disable_irq(struct cdns *cdns) - { -- writel(0, &cdns->otg_irq_regs->ien); -+ if (cdns->version) -+ writel(0, &cdns->otg_irq_regs->ien); - } - - /** -@@ -418,15 +419,20 @@ int cdns_drd_init(struct cdns *cdns) - - cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd; - -- if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) { -+ state = readl(&cdns->otg_cdnsp_regs->did); -+ -+ if (OTG_CDNSP_CHECK_DID(state)) { - cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) - &cdns->otg_cdnsp_regs->ien; - cdns->version = CDNSP_CONTROLLER_V2; -- } else { -+ } else if (OTG_CDNS3_CHECK_DID(state)) { - cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) - &cdns->otg_v1_regs->ien; - writel(1, &cdns->otg_v1_regs->simulate); - cdns->version = CDNS3_CONTROLLER_V1; -+ } else { -+ dev_err(cdns->dev, "not supporte DID=0x%08x\n", state); -+ return -EINVAL; - } - - dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", -@@ -479,7 +485,6 @@ int cdns_drd_exit(struct cdns *cdns) - return 0; - } - -- - /* Indicate the cdns3 core was power lost before */ - bool cdns_power_is_lost(struct cdns *cdns) - { -diff --git a/drivers/usb/cdns3/drd.h b/drivers/usb/cdns3/drd.h -index cbdf94f73ed91..d72370c321d39 100644 ---- a/drivers/usb/cdns3/drd.h -+++ b/drivers/usb/cdns3/drd.h -@@ -79,7 +79,11 @@ struct cdnsp_otg_regs { - __le32 susp_timing_ctrl; - }; - --#define OTG_CDNSP_DID 0x0004034E -+/* CDNSP driver supports 0x000403xx Cadence USB controller family. */ -+#define OTG_CDNSP_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040300) -+ -+/* CDNS3 driver supports 0x000402xx Cadence USB controller family. */ -+#define OTG_CDNS3_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040200) - - /* - * Common registers interface for both CDNS3 and CDNSP version of DRD. -diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c -index 6164fc4c96a49..ceca4d839dfd4 100644 ---- a/drivers/usb/cdns3/host.c -+++ b/drivers/usb/cdns3/host.c -@@ -18,6 +18,11 @@ - #include "../host/xhci.h" - #include "../host/xhci-plat.h" - -+/* -+ * The XECP_PORT_CAP_REG and XECP_AUX_CTRL_REG1 exist only -+ * in Cadence USB3 dual-role controller, so it can't be used -+ * with Cadence CDNSP dual-role controller. -+ */ - #define XECP_PORT_CAP_REG 0x8000 - #define XECP_AUX_CTRL_REG1 0x8120 - -@@ -57,6 +62,8 @@ static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { - .resume_quirk = xhci_cdns3_resume_quirk, - }; - -+static const struct xhci_plat_priv xhci_plat_cdnsp_xhci; -+ - static int __cdns_host_init(struct cdns *cdns) - { - struct platform_device *xhci; -@@ -81,8 +88,13 @@ static int __cdns_host_init(struct cdns *cdns) - goto err1; - } - -- cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, -- sizeof(struct xhci_plat_priv), GFP_KERNEL); -+ if (cdns->version < CDNSP_CONTROLLER_V2) -+ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, -+ sizeof(struct xhci_plat_priv), GFP_KERNEL); -+ else -+ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdnsp_xhci, -+ sizeof(struct xhci_plat_priv), GFP_KERNEL); -+ - if (!cdns->xhci_plat_data) { - ret = -ENOMEM; - goto err1; -diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c -index 576c21bf77cda..b134110cc2ed5 100644 ---- a/drivers/usb/dwc3/gadget.c -+++ b/drivers/usb/dwc3/gadget.c -@@ -2548,6 +2548,11 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) - int ret; - - spin_lock_irqsave(&dwc->lock, flags); -+ if (!dwc->pullups_connected) { -+ spin_unlock_irqrestore(&dwc->lock, flags); -+ return 0; -+ } -+ - dwc->connected = false; - - /* -diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c -index bbb6ff6b11aa1..5e78fcc63e4d3 100644 ---- a/drivers/usb/gadget/function/f_ncm.c -+++ b/drivers/usb/gadget/function/f_ncm.c -@@ -1340,7 +1340,15 @@ static int ncm_unwrap_ntb(struct gether *port, - "Parsed NTB with %d frames\n", dgram_counter); - - to_process -= block_len; -- if (to_process != 0) { -+ -+ /* -+ * Windows NCM driver avoids USB ZLPs by adding a 1-byte -+ * zero pad as needed. -+ */ -+ if (to_process == 1 && -+ (*(unsigned char *)(ntb_ptr + block_len) == 0x00)) { -+ to_process--; -+ } else if (to_process > 0) { - ntb_ptr = (unsigned char *)(ntb_ptr + block_len); - goto parse_ntb; - } -diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c -index 32e6d19f7011a..a327f8bc57043 100644 ---- a/drivers/usb/roles/class.c -+++ b/drivers/usb/roles/class.c -@@ -19,7 +19,9 @@ static struct class *role_class; - struct usb_role_switch { - struct device dev; - struct mutex lock; /* device lock*/ -+ struct module *module; /* the module this device depends on */ - enum usb_role role; -+ bool registered; - - /* From descriptor */ - struct device *usb2_port; -@@ -46,6 +48,9 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) - if (IS_ERR_OR_NULL(sw)) - return 0; - -+ if (!sw->registered) -+ return -EOPNOTSUPP; -+ - mutex_lock(&sw->lock); - - ret = sw->set(sw, role); -@@ -71,7 +76,7 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) - { - enum usb_role role; - -- if (IS_ERR_OR_NULL(sw)) -+ if (IS_ERR_OR_NULL(sw) || !sw->registered) - return USB_ROLE_NONE; - - mutex_lock(&sw->lock); -@@ -133,7 +138,7 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev) - usb_role_switch_match); - - if (!IS_ERR_OR_NULL(sw)) -- WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); -+ WARN_ON(!try_module_get(sw->module)); - - return sw; - } -@@ -155,7 +160,7 @@ struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) - sw = fwnode_connection_find_match(fwnode, "usb-role-switch", - NULL, usb_role_switch_match); - if (!IS_ERR_OR_NULL(sw)) -- WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); -+ WARN_ON(!try_module_get(sw->module)); - - return sw; - } -@@ -170,7 +175,7 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); - void usb_role_switch_put(struct usb_role_switch *sw) - { - if (!IS_ERR_OR_NULL(sw)) { -- module_put(sw->dev.parent->driver->owner); -+ module_put(sw->module); - put_device(&sw->dev); - } - } -@@ -187,15 +192,18 @@ struct usb_role_switch * - usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode) - { - struct device *dev; -+ struct usb_role_switch *sw = NULL; - - if (!fwnode) - return NULL; - - dev = class_find_device_by_fwnode(role_class, fwnode); -- if (dev) -- WARN_ON(!try_module_get(dev->parent->driver->owner)); -+ if (dev) { -+ sw = to_role_switch(dev); -+ WARN_ON(!try_module_get(sw->module)); -+ } - -- return dev ? to_role_switch(dev) : NULL; -+ return sw; - } - EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode); - -@@ -337,6 +345,7 @@ usb_role_switch_register(struct device *parent, - sw->set = desc->set; - sw->get = desc->get; - -+ sw->module = parent->driver->owner; - sw->dev.parent = parent; - sw->dev.fwnode = desc->fwnode; - sw->dev.class = role_class; -@@ -351,6 +360,8 @@ usb_role_switch_register(struct device *parent, - return ERR_PTR(ret); - } - -+ sw->registered = true; -+ - /* TODO: Symlinks for the host port and the device controller. */ - - return sw; -@@ -365,8 +376,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_register); - */ - void usb_role_switch_unregister(struct usb_role_switch *sw) - { -- if (!IS_ERR_OR_NULL(sw)) -+ if (!IS_ERR_OR_NULL(sw)) { -+ sw->registered = false; - device_unregister(&sw->dev); -+ } - } - EXPORT_SYMBOL_GPL(usb_role_switch_unregister); - -diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c -index 26171c5d3c61c..48130d636a020 100644 ---- a/drivers/usb/typec/ucsi/ucsi_acpi.c -+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c -@@ -25,6 +25,8 @@ struct ucsi_acpi { - unsigned long flags; - guid_t guid; - u64 cmd; -+ bool dell_quirk_probed; -+ bool dell_quirk_active; - }; - - static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func) -@@ -126,12 +128,73 @@ static const struct ucsi_operations ucsi_zenbook_ops = { - .async_write = ucsi_acpi_async_write - }; - --static const struct dmi_system_id zenbook_dmi_id[] = { -+/* -+ * Some Dell laptops expect that an ACK command with the -+ * UCSI_ACK_CONNECTOR_CHANGE bit set is followed by a (separate) -+ * ACK command that only has the UCSI_ACK_COMMAND_COMPLETE bit set. -+ * If this is not done events are not delivered to OSPM and -+ * subsequent commands will timeout. -+ */ -+static int -+ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset, -+ const void *val, size_t val_len) -+{ -+ struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); -+ u64 cmd = *(u64 *)val, ack = 0; -+ int ret; -+ -+ if (UCSI_COMMAND(cmd) == UCSI_ACK_CC_CI && -+ cmd & UCSI_ACK_CONNECTOR_CHANGE) -+ ack = UCSI_ACK_CC_CI | UCSI_ACK_COMMAND_COMPLETE; -+ -+ ret = ucsi_acpi_sync_write(ucsi, offset, val, val_len); -+ if (ret != 0) -+ return ret; -+ if (ack == 0) -+ return ret; -+ -+ if (!ua->dell_quirk_probed) { -+ ua->dell_quirk_probed = true; -+ -+ cmd = UCSI_GET_CAPABILITY; -+ ret = ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &cmd, -+ sizeof(cmd)); -+ if (ret == 0) -+ return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, -+ &ack, sizeof(ack)); -+ if (ret != -ETIMEDOUT) -+ return ret; -+ -+ ua->dell_quirk_active = true; -+ dev_err(ua->dev, "Firmware bug: Additional ACK required after ACKing a connector change.\n"); -+ dev_err(ua->dev, "Firmware bug: Enabling workaround\n"); -+ } -+ -+ if (!ua->dell_quirk_active) -+ return ret; -+ -+ return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &ack, sizeof(ack)); -+} -+ -+static const struct ucsi_operations ucsi_dell_ops = { -+ .read = ucsi_acpi_read, -+ .sync_write = ucsi_dell_sync_write, -+ .async_write = ucsi_acpi_async_write -+}; -+ -+static const struct dmi_system_id ucsi_acpi_quirks[] = { - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), - }, -+ .driver_data = (void *)&ucsi_zenbook_ops, -+ }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), -+ }, -+ .driver_data = (void *)&ucsi_dell_ops, - }, - { } - }; -@@ -160,6 +223,7 @@ static int ucsi_acpi_probe(struct platform_device *pdev) - { - struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); - const struct ucsi_operations *ops = &ucsi_acpi_ops; -+ const struct dmi_system_id *id; - struct ucsi_acpi *ua; - struct resource *res; - acpi_status status; -@@ -189,8 +253,9 @@ static int ucsi_acpi_probe(struct platform_device *pdev) - init_completion(&ua->complete); - ua->dev = &pdev->dev; - -- if (dmi_check_system(zenbook_dmi_id)) -- ops = &ucsi_zenbook_ops; -+ id = dmi_first_match(ucsi_acpi_quirks); -+ if (id) -+ ops = id->driver_data; - - ua->ucsi = ucsi_create(&pdev->dev, ops); - if (IS_ERR(ua->ucsi)) -diff --git a/drivers/vfio/iova_bitmap.c b/drivers/vfio/iova_bitmap.c -index 0f19d502f351b..dfab5b742191a 100644 ---- a/drivers/vfio/iova_bitmap.c -+++ b/drivers/vfio/iova_bitmap.c -@@ -99,7 +99,7 @@ struct iova_bitmap { - struct iova_bitmap_map mapped; - - /* userspace address of the bitmap */ -- u64 __user *bitmap; -+ u8 __user *bitmap; - - /* u64 index that @mapped points to */ - unsigned long mapped_base_index; -@@ -161,7 +161,7 @@ static int iova_bitmap_get(struct iova_bitmap *bitmap) - { - struct iova_bitmap_map *mapped = &bitmap->mapped; - unsigned long npages; -- u64 __user *addr; -+ u8 __user *addr; - long ret; - - /* -@@ -174,18 +174,19 @@ static int iova_bitmap_get(struct iova_bitmap *bitmap) - bitmap->mapped_base_index) * - sizeof(*bitmap->bitmap), PAGE_SIZE); - -- /* -- * We always cap at max number of 'struct page' a base page can fit. -- * This is, for example, on x86 means 2M of bitmap data max. -- */ -- npages = min(npages, PAGE_SIZE / sizeof(struct page *)); -- - /* - * Bitmap address to be pinned is calculated via pointer arithmetic - * with bitmap u64 word index. - */ - addr = bitmap->bitmap + bitmap->mapped_base_index; - -+ /* -+ * We always cap at max number of 'struct page' a base page can fit. -+ * This is, for example, on x86 means 2M of bitmap data max. -+ */ -+ npages = min(npages + !!offset_in_page(addr), -+ PAGE_SIZE / sizeof(struct page *)); -+ - ret = pin_user_pages_fast((unsigned long)addr, npages, - FOLL_WRITE, mapped->pages); - if (ret <= 0) -@@ -246,7 +247,7 @@ struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length, - - mapped = &bitmap->mapped; - mapped->pgshift = __ffs(page_size); -- bitmap->bitmap = data; -+ bitmap->bitmap = (u8 __user *)data; - bitmap->mapped_total_index = - iova_bitmap_offset_to_index(bitmap, length - 1) + 1; - bitmap->iova = iova; -@@ -301,7 +302,7 @@ static unsigned long iova_bitmap_mapped_remaining(struct iova_bitmap *bitmap) - - remaining = bitmap->mapped_total_index - bitmap->mapped_base_index; - remaining = min_t(unsigned long, remaining, -- bytes / sizeof(*bitmap->bitmap)); -+ DIV_ROUND_UP(bytes, sizeof(*bitmap->bitmap))); - - return remaining; - } -@@ -405,6 +406,7 @@ void iova_bitmap_set(struct iova_bitmap *bitmap, - mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; - unsigned long last_bit = (((iova + length - 1) - mapped->iova) >> - mapped->pgshift) + mapped->pgoff * BITS_PER_BYTE; -+ unsigned long last_page_idx = mapped->npages - 1; - - do { - unsigned int page_idx = cur_bit / BITS_PER_PAGE; -@@ -413,6 +415,9 @@ void iova_bitmap_set(struct iova_bitmap *bitmap, - last_bit - cur_bit + 1); - void *kaddr; - -+ if (unlikely(page_idx > last_page_idx)) -+ break; -+ - kaddr = kmap_local_page(mapped->pages[page_idx]); - bitmap_set(kaddr, offset, nbits); - kunmap_local(kaddr); -diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c -index b7818b652698f..a7b63c475f954 100644 ---- a/drivers/video/fbdev/savage/savagefb_driver.c -+++ b/drivers/video/fbdev/savage/savagefb_driver.c -@@ -869,6 +869,9 @@ static int savagefb_check_var(struct fb_var_screeninfo *var, - - DBG("savagefb_check_var"); - -+ if (!var->pixclock) -+ return -EINVAL; -+ - var->transp.offset = 0; - var->transp.length = 0; - switch (var->bits_per_pixel) { -diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c -index 1c197c3f95381..fe8996461b9ef 100644 ---- a/drivers/video/fbdev/sis/sis_main.c -+++ b/drivers/video/fbdev/sis/sis_main.c -@@ -1475,6 +1475,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) - - vtotal = var->upper_margin + var->lower_margin + var->vsync_len; - -+ if (!var->pixclock) -+ return -EINVAL; - pixclock = var->pixclock; - - if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { -diff --git a/fs/afs/volume.c b/fs/afs/volume.c -index 1c9144e3e83ac..a146d70efa650 100644 ---- a/fs/afs/volume.c -+++ b/fs/afs/volume.c -@@ -341,7 +341,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) - { - struct afs_server_list *new, *old, *discard; - struct afs_vldb_entry *vldb; -- char idbuf[16]; -+ char idbuf[24]; - int ret, idsz; - - _enter(""); -@@ -349,7 +349,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) - /* We look up an ID by passing it as a decimal string in the - * operation's name parameter. - */ -- idsz = sprintf(idbuf, "%llu", volume->vid); -+ idsz = snprintf(idbuf, sizeof(idbuf), "%llu", volume->vid); - - vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz); - if (IS_ERR(vldb)) { -diff --git a/fs/aio.c b/fs/aio.c -index e85ba0b77f596..849c3e3ed558b 100644 ---- a/fs/aio.c -+++ b/fs/aio.c -@@ -595,6 +595,13 @@ void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel) - struct kioctx *ctx = req->ki_ctx; - unsigned long flags; - -+ /* -+ * kiocb didn't come from aio or is neither a read nor a write, hence -+ * ignore it. -+ */ -+ if (!(iocb->ki_flags & IOCB_AIO_RW)) -+ return; -+ - if (WARN_ON_ONCE(!list_empty(&req->ki_list))) - return; - -@@ -1476,7 +1483,7 @@ static int aio_prep_rw(struct kiocb *req, const struct iocb *iocb) - req->ki_complete = aio_complete_rw; - req->private = NULL; - req->ki_pos = iocb->aio_offset; -- req->ki_flags = req->ki_filp->f_iocb_flags; -+ req->ki_flags = req->ki_filp->f_iocb_flags | IOCB_AIO_RW; - if (iocb->aio_flags & IOCB_FLAG_RESFD) - req->ki_flags |= IOCB_EVENTFD; - if (iocb->aio_flags & IOCB_FLAG_IOPRIO) { -diff --git a/fs/cachefiles/cache.c b/fs/cachefiles/cache.c -index 7077f72e6f474..f449f7340aad0 100644 ---- a/fs/cachefiles/cache.c -+++ b/fs/cachefiles/cache.c -@@ -168,6 +168,8 @@ int cachefiles_add_cache(struct cachefiles_cache *cache) - dput(root); - error_open_root: - cachefiles_end_secure(cache, saved_cred); -+ put_cred(cache->cache_cred); -+ cache->cache_cred = NULL; - error_getsec: - fscache_relinquish_cache(cache_cookie); - cache->cache = NULL; -diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c -index aa4efcabb5e37..5f4df9588620f 100644 ---- a/fs/cachefiles/daemon.c -+++ b/fs/cachefiles/daemon.c -@@ -805,6 +805,7 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache) - cachefiles_put_directory(cache->graveyard); - cachefiles_put_directory(cache->store); - mntput(cache->mnt); -+ put_cred(cache->cache_cred); - - kfree(cache->rootdirname); - kfree(cache->secctx); -diff --git a/fs/erofs/compress.h b/fs/erofs/compress.h -index 26fa170090b8f..c4a3187bdb8fc 100644 ---- a/fs/erofs/compress.h -+++ b/fs/erofs/compress.h -@@ -21,6 +21,8 @@ struct z_erofs_decompress_req { - }; - - struct z_erofs_decompressor { -+ int (*config)(struct super_block *sb, struct erofs_super_block *dsb, -+ void *data, int size); - int (*decompress)(struct z_erofs_decompress_req *rq, - struct page **pagepool); - char *name; -@@ -93,6 +95,8 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq, - struct page **pagepool); - - /* prototypes for specific algorithms */ -+int z_erofs_load_lzma_config(struct super_block *sb, -+ struct erofs_super_block *dsb, void *data, int size); - int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq, - struct page **pagepool); - #endif -diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c -index 0cfad74374ca9..1eefa4411e066 100644 ---- a/fs/erofs/decompressor.c -+++ b/fs/erofs/decompressor.c -@@ -24,11 +24,11 @@ struct z_erofs_lz4_decompress_ctx { - unsigned int oend; - }; - --int z_erofs_load_lz4_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lz4_cfgs *lz4, int size) -+static int z_erofs_load_lz4_config(struct super_block *sb, -+ struct erofs_super_block *dsb, void *data, int size) - { - struct erofs_sb_info *sbi = EROFS_SB(sb); -+ struct z_erofs_lz4_cfgs *lz4 = data; - u16 distance; - - if (lz4) { -@@ -374,17 +374,71 @@ static struct z_erofs_decompressor decompressors[] = { - .name = "interlaced" - }, - [Z_EROFS_COMPRESSION_LZ4] = { -+ .config = z_erofs_load_lz4_config, - .decompress = z_erofs_lz4_decompress, - .name = "lz4" - }, - #ifdef CONFIG_EROFS_FS_ZIP_LZMA - [Z_EROFS_COMPRESSION_LZMA] = { -+ .config = z_erofs_load_lzma_config, - .decompress = z_erofs_lzma_decompress, - .name = "lzma" - }, - #endif - }; - -+int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb) -+{ -+ struct erofs_sb_info *sbi = EROFS_SB(sb); -+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -+ unsigned int algs, alg; -+ erofs_off_t offset; -+ int size, ret = 0; -+ -+ if (!erofs_sb_has_compr_cfgs(sbi)) { -+ sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4; -+ return z_erofs_load_lz4_config(sb, dsb, NULL, 0); -+ } -+ -+ sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs); -+ if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) { -+ erofs_err(sb, "unidentified algorithms %x, please upgrade kernel", -+ sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS); -+ return -EOPNOTSUPP; -+ } -+ -+ offset = EROFS_SUPER_OFFSET + sbi->sb_size; -+ alg = 0; -+ for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) { -+ void *data; -+ -+ if (!(algs & 1)) -+ continue; -+ -+ data = erofs_read_metadata(sb, &buf, &offset, &size); -+ if (IS_ERR(data)) { -+ ret = PTR_ERR(data); -+ break; -+ } -+ -+ if (alg >= ARRAY_SIZE(decompressors) || -+ !decompressors[alg].config) { -+ erofs_err(sb, "algorithm %d isn't enabled on this kernel", -+ alg); -+ ret = -EOPNOTSUPP; -+ } else { -+ ret = decompressors[alg].config(sb, -+ dsb, data, size); -+ } -+ -+ kfree(data); -+ if (ret) -+ break; -+ } -+ erofs_put_metabuf(&buf); -+ return ret; -+} -+ - int z_erofs_decompress(struct z_erofs_decompress_req *rq, - struct page **pagepool) - { -diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c -index 49addc345aebe..970464c4b6769 100644 ---- a/fs/erofs/decompressor_lzma.c -+++ b/fs/erofs/decompressor_lzma.c -@@ -72,10 +72,10 @@ int z_erofs_lzma_init(void) - } - - int z_erofs_load_lzma_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lzma_cfgs *lzma, int size) -+ struct erofs_super_block *dsb, void *data, int size) - { - static DEFINE_MUTEX(lzma_resize_mutex); -+ struct z_erofs_lzma_cfgs *lzma = data; - unsigned int dict_size, i; - struct z_erofs_lzma *strm, *head = NULL; - int err; -diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h -index d8d09fc3ed655..79a7a5815ea63 100644 ---- a/fs/erofs/internal.h -+++ b/fs/erofs/internal.h -@@ -471,6 +471,8 @@ struct erofs_map_dev { - - /* data.c */ - extern const struct file_operations erofs_file_fops; -+void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, -+ erofs_off_t *offset, int *lengthp); - void erofs_unmap_metabuf(struct erofs_buf *buf); - void erofs_put_metabuf(struct erofs_buf *buf); - void *erofs_bread(struct erofs_buf *buf, struct inode *inode, -@@ -565,9 +567,7 @@ void z_erofs_exit_zip_subsystem(void); - int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, - struct erofs_workgroup *egrp); - int erofs_try_to_free_cached_page(struct page *page); --int z_erofs_load_lz4_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lz4_cfgs *lz4, int len); -+int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb); - #else - static inline void erofs_shrinker_register(struct super_block *sb) {} - static inline void erofs_shrinker_unregister(struct super_block *sb) {} -@@ -575,36 +575,14 @@ static inline int erofs_init_shrinker(void) { return 0; } - static inline void erofs_exit_shrinker(void) {} - static inline int z_erofs_init_zip_subsystem(void) { return 0; } - static inline void z_erofs_exit_zip_subsystem(void) {} --static inline int z_erofs_load_lz4_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lz4_cfgs *lz4, int len) --{ -- if (lz4 || dsb->u1.lz4_max_distance) { -- erofs_err(sb, "lz4 algorithm isn't enabled"); -- return -EINVAL; -- } -- return 0; --} - #endif /* !CONFIG_EROFS_FS_ZIP */ - - #ifdef CONFIG_EROFS_FS_ZIP_LZMA - int z_erofs_lzma_init(void); - void z_erofs_lzma_exit(void); --int z_erofs_load_lzma_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lzma_cfgs *lzma, int size); - #else - static inline int z_erofs_lzma_init(void) { return 0; } - static inline int z_erofs_lzma_exit(void) { return 0; } --static inline int z_erofs_load_lzma_config(struct super_block *sb, -- struct erofs_super_block *dsb, -- struct z_erofs_lzma_cfgs *lzma, int size) { -- if (lzma) { -- erofs_err(sb, "lzma algorithm isn't enabled"); -- return -EINVAL; -- } -- return 0; --} - #endif /* !CONFIG_EROFS_FS_ZIP */ - - /* flags for erofs_fscache_register_cookie() */ -diff --git a/fs/erofs/namei.c b/fs/erofs/namei.c -index 0dc34721080c7..e8ccaa761bd63 100644 ---- a/fs/erofs/namei.c -+++ b/fs/erofs/namei.c -@@ -137,24 +137,24 @@ static void *find_target_block_classic(struct erofs_buf *target, - /* string comparison without already matched prefix */ - diff = erofs_dirnamecmp(name, &dname, &matched); - -- if (!diff) { -- *_ndirents = 0; -- goto out; -- } else if (diff > 0) { -- head = mid + 1; -- startprfx = matched; -- -- if (!IS_ERR(candidate)) -- erofs_put_metabuf(target); -- *target = buf; -- candidate = de; -- *_ndirents = ndirents; -- } else { -+ if (diff < 0) { - erofs_put_metabuf(&buf); -- - back = mid - 1; - endprfx = matched; -+ continue; -+ } -+ -+ if (!IS_ERR(candidate)) -+ erofs_put_metabuf(target); -+ *target = buf; -+ if (!diff) { -+ *_ndirents = 0; -+ return de; - } -+ head = mid + 1; -+ startprfx = matched; -+ candidate = de; -+ *_ndirents = ndirents; - continue; - } - out: /* free if the candidate is valid */ -diff --git a/fs/erofs/super.c b/fs/erofs/super.c -index bd8bf8fc2f5df..f2647126cb2fb 100644 ---- a/fs/erofs/super.c -+++ b/fs/erofs/super.c -@@ -126,8 +126,8 @@ static bool check_layout_compatibility(struct super_block *sb, - - #ifdef CONFIG_EROFS_FS_ZIP - /* read variable-sized metadata, offset will be aligned by 4-byte */ --static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, -- erofs_off_t *offset, int *lengthp) -+void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, -+ erofs_off_t *offset, int *lengthp) - { - u8 *buffer, *ptr; - int len, i, cnt; -@@ -159,64 +159,15 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, - } - return buffer; - } -- --static int erofs_load_compr_cfgs(struct super_block *sb, -- struct erofs_super_block *dsb) --{ -- struct erofs_sb_info *sbi = EROFS_SB(sb); -- struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -- unsigned int algs, alg; -- erofs_off_t offset; -- int size, ret = 0; -- -- sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs); -- if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) { -- erofs_err(sb, "try to load compressed fs with unsupported algorithms %x", -- sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS); -- return -EINVAL; -- } -- -- offset = EROFS_SUPER_OFFSET + sbi->sb_size; -- alg = 0; -- for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) { -- void *data; -- -- if (!(algs & 1)) -- continue; -- -- data = erofs_read_metadata(sb, &buf, &offset, &size); -- if (IS_ERR(data)) { -- ret = PTR_ERR(data); -- break; -- } -- -- switch (alg) { -- case Z_EROFS_COMPRESSION_LZ4: -- ret = z_erofs_load_lz4_config(sb, dsb, data, size); -- break; -- case Z_EROFS_COMPRESSION_LZMA: -- ret = z_erofs_load_lzma_config(sb, dsb, data, size); -- break; -- default: -- DBG_BUGON(1); -- ret = -EFAULT; -- } -- kfree(data); -- if (ret) -- break; -- } -- erofs_put_metabuf(&buf); -- return ret; --} - #else --static int erofs_load_compr_cfgs(struct super_block *sb, -- struct erofs_super_block *dsb) -+static int z_erofs_parse_cfgs(struct super_block *sb, -+ struct erofs_super_block *dsb) - { -- if (dsb->u1.available_compr_algs) { -- erofs_err(sb, "try to load compressed fs when compression is disabled"); -- return -EINVAL; -- } -- return 0; -+ if (!dsb->u1.available_compr_algs) -+ return 0; -+ -+ erofs_err(sb, "compression disabled, unable to mount compressed EROFS"); -+ return -EOPNOTSUPP; - } - #endif - -@@ -398,10 +349,7 @@ static int erofs_read_superblock(struct super_block *sb) - } - - /* parse on-disk compression configurations */ -- if (erofs_sb_has_compr_cfgs(sbi)) -- ret = erofs_load_compr_cfgs(sb, dsb); -- else -- ret = z_erofs_load_lz4_config(sb, dsb, NULL, 0); -+ ret = z_erofs_parse_cfgs(sb, dsb); - if (ret < 0) - goto out; - -diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c -index 0337b70b2dac4..abcded1acd194 100644 ---- a/fs/erofs/zmap.c -+++ b/fs/erofs/zmap.c -@@ -610,7 +610,7 @@ static int z_erofs_do_map_blocks(struct inode *inode, - .map = map, - }; - int err = 0; -- unsigned int lclusterbits, endoff; -+ unsigned int lclusterbits, endoff, afmt; - unsigned long initial_lcn; - unsigned long long ofs, end; - -@@ -700,17 +700,20 @@ static int z_erofs_do_map_blocks(struct inode *inode, - err = -EFSCORRUPTED; - goto unmap_out; - } -- if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER) -- map->m_algorithmformat = -- Z_EROFS_COMPRESSION_INTERLACED; -- else -- map->m_algorithmformat = -- Z_EROFS_COMPRESSION_SHIFTED; -- } else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) { -- map->m_algorithmformat = vi->z_algorithmtype[1]; -+ afmt = vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER ? -+ Z_EROFS_COMPRESSION_INTERLACED : -+ Z_EROFS_COMPRESSION_SHIFTED; - } else { -- map->m_algorithmformat = vi->z_algorithmtype[0]; -+ afmt = m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2 ? -+ vi->z_algorithmtype[1] : vi->z_algorithmtype[0]; -+ if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) { -+ erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu", -+ afmt, vi->nid); -+ err = -EFSCORRUPTED; -+ goto unmap_out; -+ } - } -+ map->m_algorithmformat = afmt; - - if ((flags & EROFS_GET_BLOCKS_FIEMAP) || - ((flags & EROFS_GET_BLOCKS_READMORE) && -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index aa5aadd70bbc2..67af684e44e6e 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -2229,7 +2229,7 @@ static int ext4_fill_es_cache_info(struct inode *inode, - - - /* -- * ext4_ext_determine_hole - determine hole around given block -+ * ext4_ext_find_hole - find hole around given block according to the given path - * @inode: inode we lookup in - * @path: path in extent tree to @lblk - * @lblk: pointer to logical block around which we want to determine hole -@@ -2241,9 +2241,9 @@ static int ext4_fill_es_cache_info(struct inode *inode, - * The function returns the length of a hole starting at @lblk. We update @lblk - * to the beginning of the hole if we managed to find it. - */ --static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode, -- struct ext4_ext_path *path, -- ext4_lblk_t *lblk) -+static ext4_lblk_t ext4_ext_find_hole(struct inode *inode, -+ struct ext4_ext_path *path, -+ ext4_lblk_t *lblk) - { - int depth = ext_depth(inode); - struct ext4_extent *ex; -@@ -2270,30 +2270,6 @@ static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode, - return len; - } - --/* -- * ext4_ext_put_gap_in_cache: -- * calculate boundaries of the gap that the requested block fits into -- * and cache this gap -- */ --static void --ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start, -- ext4_lblk_t hole_len) --{ -- struct extent_status es; -- -- ext4_es_find_extent_range(inode, &ext4_es_is_delayed, hole_start, -- hole_start + hole_len - 1, &es); -- if (es.es_len) { -- /* There's delayed extent containing lblock? */ -- if (es.es_lblk <= hole_start) -- return; -- hole_len = min(es.es_lblk - hole_start, hole_len); -- } -- ext_debug(inode, " -> %u:%u\n", hole_start, hole_len); -- ext4_es_insert_extent(inode, hole_start, hole_len, ~0, -- EXTENT_STATUS_HOLE); --} -- - /* - * ext4_ext_rm_idx: - * removes index from the index block. -@@ -4064,6 +4040,69 @@ static int get_implied_cluster_alloc(struct super_block *sb, - return 0; - } - -+/* -+ * Determine hole length around the given logical block, first try to -+ * locate and expand the hole from the given @path, and then adjust it -+ * if it's partially or completely converted to delayed extents, insert -+ * it into the extent cache tree if it's indeed a hole, finally return -+ * the length of the determined extent. -+ */ -+static ext4_lblk_t ext4_ext_determine_insert_hole(struct inode *inode, -+ struct ext4_ext_path *path, -+ ext4_lblk_t lblk) -+{ -+ ext4_lblk_t hole_start, len; -+ struct extent_status es; -+ -+ hole_start = lblk; -+ len = ext4_ext_find_hole(inode, path, &hole_start); -+again: -+ ext4_es_find_extent_range(inode, &ext4_es_is_delayed, hole_start, -+ hole_start + len - 1, &es); -+ if (!es.es_len) -+ goto insert_hole; -+ -+ /* -+ * There's a delalloc extent in the hole, handle it if the delalloc -+ * extent is in front of, behind and straddle the queried range. -+ */ -+ if (lblk >= es.es_lblk + es.es_len) { -+ /* -+ * The delalloc extent is in front of the queried range, -+ * find again from the queried start block. -+ */ -+ len -= lblk - hole_start; -+ hole_start = lblk; -+ goto again; -+ } else if (in_range(lblk, es.es_lblk, es.es_len)) { -+ /* -+ * The delalloc extent containing lblk, it must have been -+ * added after ext4_map_blocks() checked the extent status -+ * tree, adjust the length to the delalloc extent's after -+ * lblk. -+ */ -+ len = es.es_lblk + es.es_len - lblk; -+ return len; -+ } else { -+ /* -+ * The delalloc extent is partially or completely behind -+ * the queried range, update hole length until the -+ * beginning of the delalloc extent. -+ */ -+ len = min(es.es_lblk - hole_start, len); -+ } -+ -+insert_hole: -+ /* Put just found gap into cache to speed up subsequent requests */ -+ ext_debug(inode, " -> %u:%u\n", hole_start, len); -+ ext4_es_insert_extent(inode, hole_start, len, ~0, EXTENT_STATUS_HOLE); -+ -+ /* Update hole_len to reflect hole size after lblk */ -+ if (hole_start != lblk) -+ len -= lblk - hole_start; -+ -+ return len; -+} - - /* - * Block allocation/map/preallocation routine for extents based files -@@ -4181,22 +4220,12 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, - * we couldn't try to create block if create flag is zero - */ - if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { -- ext4_lblk_t hole_start, hole_len; -+ ext4_lblk_t len; - -- hole_start = map->m_lblk; -- hole_len = ext4_ext_determine_hole(inode, path, &hole_start); -- /* -- * put just found gap into cache to speed up -- * subsequent requests -- */ -- ext4_ext_put_gap_in_cache(inode, hole_start, hole_len); -+ len = ext4_ext_determine_insert_hole(inode, path, map->m_lblk); - -- /* Update hole_len to reflect hole size after map->m_lblk */ -- if (hole_start != map->m_lblk) -- hole_len -= map->m_lblk - hole_start; - map->m_pblk = 0; -- map->m_len = min_t(unsigned int, map->m_len, hole_len); -- -+ map->m_len = min_t(unsigned int, map->m_len, len); - goto out; - } - -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 1a310ee7d9e55..6a3e27771df73 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -831,7 +831,7 @@ mb_update_avg_fragment_size(struct super_block *sb, struct ext4_group_info *grp) - struct ext4_sb_info *sbi = EXT4_SB(sb); - int new_order; - -- if (!test_opt2(sb, MB_OPTIMIZE_SCAN) || grp->bb_free == 0) -+ if (!test_opt2(sb, MB_OPTIMIZE_SCAN) || grp->bb_fragments == 0) - return; - - new_order = mb_avg_fragment_size_order(sb, -@@ -2176,6 +2176,9 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac, - return err; - - ext4_lock_group(ac->ac_sb, group); -+ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) -+ goto out; -+ - max = mb_find_extent(e4b, ex.fe_start, ex.fe_len, &ex); - - if (max > 0) { -@@ -2183,6 +2186,7 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac, - ext4_mb_use_best_found(ac, e4b); - } - -+out: - ext4_unlock_group(ac->ac_sb, group); - ext4_mb_unload_buddy(e4b); - -@@ -2211,12 +2215,10 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, - if (err) - return err; - -- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) { -- ext4_mb_unload_buddy(e4b); -- return 0; -- } -- - ext4_lock_group(ac->ac_sb, group); -+ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) -+ goto out; -+ - max = mb_find_extent(e4b, ac->ac_g_ex.fe_start, - ac->ac_g_ex.fe_len, &ex); - ex.fe_logical = 0xDEADFA11; /* debug value */ -@@ -2249,6 +2251,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, - ac->ac_b_ex = ex; - ext4_mb_use_best_found(ac, e4b); - } -+out: - ext4_unlock_group(ac->ac_sb, group); - ext4_mb_unload_buddy(e4b); - -diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c -index 2215179c925b3..2618bf5a37892 100644 ---- a/fs/ntfs3/attrib.c -+++ b/fs/ntfs3/attrib.c -@@ -1658,8 +1658,10 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, - le_b = NULL; - attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, - 0, NULL, &mi_b); -- if (!attr_b) -- return -ENOENT; -+ if (!attr_b) { -+ err = -ENOENT; -+ goto out; -+ } - - attr = attr_b; - le = le_b; -@@ -1740,13 +1742,15 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, - ok: - run_truncate_around(run, vcn); - out: -- if (new_valid > data_size) -- new_valid = data_size; -+ if (attr_b) { -+ if (new_valid > data_size) -+ new_valid = data_size; - -- valid_size = le64_to_cpu(attr_b->nres.valid_size); -- if (new_valid != valid_size) { -- attr_b->nres.valid_size = cpu_to_le64(valid_size); -- mi_b->dirty = true; -+ valid_size = le64_to_cpu(attr_b->nres.valid_size); -+ if (new_valid != valid_size) { -+ attr_b->nres.valid_size = cpu_to_le64(valid_size); -+ mi_b->dirty = true; -+ } - } - - return err; -diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c -index 0c6a68e71e7d4..723e49ec83ce7 100644 ---- a/fs/ntfs3/attrlist.c -+++ b/fs/ntfs3/attrlist.c -@@ -127,12 +127,13 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, - { - size_t off; - u16 sz; -+ const unsigned le_min_size = le_size(0); - - if (!le) { - le = ni->attr_list.le; - } else { - sz = le16_to_cpu(le->size); -- if (sz < sizeof(struct ATTR_LIST_ENTRY)) { -+ if (sz < le_min_size) { - /* Impossible 'cause we should not return such le. */ - return NULL; - } -@@ -141,7 +142,7 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, - - /* Check boundary. */ - off = PtrOffset(ni->attr_list.le, le); -- if (off + sizeof(struct ATTR_LIST_ENTRY) > ni->attr_list.size) { -+ if (off + le_min_size > ni->attr_list.size) { - /* The regular end of list. */ - return NULL; - } -@@ -149,8 +150,7 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, - sz = le16_to_cpu(le->size); - - /* Check le for errors. */ -- if (sz < sizeof(struct ATTR_LIST_ENTRY) || -- off + sz > ni->attr_list.size || -+ if (sz < le_min_size || off + sz > ni->attr_list.size || - sz < le->name_off + le->name_len * sizeof(short)) { - return NULL; - } -diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c -index d4d9f4ffb6d9a..72cdfa8727d3c 100644 ---- a/fs/ntfs3/dir.c -+++ b/fs/ntfs3/dir.c -@@ -309,11 +309,31 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, - return 0; - } - -- /* NTFS: symlinks are "dir + reparse" or "file + reparse" */ -- if (fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) -- dt_type = DT_LNK; -- else -- dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; -+ /* -+ * NTFS: symlinks are "dir + reparse" or "file + reparse" -+ * Unfortunately reparse attribute is used for many purposes (several dozens). -+ * It is not possible here to know is this name symlink or not. -+ * To get exactly the type of name we should to open inode (read mft). -+ * getattr for opened file (fstat) correctly returns symlink. -+ */ -+ dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; -+ -+ /* -+ * It is not reliable to detect the type of name using duplicated information -+ * stored in parent directory. -+ * The only correct way to get the type of name - read MFT record and find ATTR_STD. -+ * The code below is not good idea. -+ * It does additional locks/reads just to get the type of name. -+ * Should we use additional mount option to enable branch below? -+ */ -+ if ((fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) && -+ ino != ni->mi.rno) { -+ struct inode *inode = ntfs_iget5(sbi->sb, &e->ref, NULL); -+ if (!IS_ERR_OR_NULL(inode)) { -+ dt_type = fs_umode_to_dtype(inode->i_mode); -+ iput(inode); -+ } -+ } - - return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type); - } -@@ -495,11 +515,9 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, - struct INDEX_HDR *hdr; - const struct ATTR_FILE_NAME *fname; - u32 e_size, off, end; -- u64 vbo = 0; - size_t drs = 0, fles = 0, bit = 0; -- loff_t i_size = ni->vfs_inode.i_size; - struct indx_node *node = NULL; -- u8 index_bits = ni->dir.index_bits; -+ size_t max_indx = ni->vfs_inode.i_size >> ni->dir.index_bits; - - if (is_empty) - *is_empty = true; -@@ -543,7 +561,7 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, - fles += 1; - } - -- if (vbo >= i_size) -+ if (bit >= max_indx) - goto out; - - err = indx_used_bit(&ni->dir, ni, &bit); -@@ -553,8 +571,7 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, - if (bit == MINUS_ONE_T) - goto out; - -- vbo = (u64)bit << index_bits; -- if (vbo >= i_size) -+ if (bit >= max_indx) - goto out; - - err = indx_read(&ni->dir, ni, bit << ni->dir.idx2vbn_bits, -@@ -564,7 +581,6 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, - - hdr = &node->index->ihdr; - bit += 1; -- vbo = (u64)bit << ni->dir.idx2vbn_bits; - } - - out: -diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c -index f31c0389a2e7d..14efe46df91ef 100644 ---- a/fs/ntfs3/file.c -+++ b/fs/ntfs3/file.c -@@ -1110,6 +1110,8 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) - iocb->ki_pos += written; - if (iocb->ki_pos > ni->i_valid) - ni->i_valid = iocb->ki_pos; -+ if (iocb->ki_pos > i_size) -+ i_size_write(inode, iocb->ki_pos); - - return written; - } -diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c -index 710cb5aa5a65b..d53ef128fa733 100644 ---- a/fs/ntfs3/fslog.c -+++ b/fs/ntfs3/fslog.c -@@ -465,7 +465,7 @@ static inline bool is_rst_area_valid(const struct RESTART_HDR *rhdr) - { - const struct RESTART_AREA *ra; - u16 cl, fl, ul; -- u32 off, l_size, file_dat_bits, file_size_round; -+ u32 off, l_size, seq_bits; - u16 ro = le16_to_cpu(rhdr->ra_off); - u32 sys_page = le32_to_cpu(rhdr->sys_page_size); - -@@ -511,13 +511,15 @@ static inline bool is_rst_area_valid(const struct RESTART_HDR *rhdr) - /* Make sure the sequence number bits match the log file size. */ - l_size = le64_to_cpu(ra->l_size); - -- file_dat_bits = sizeof(u64) * 8 - le32_to_cpu(ra->seq_num_bits); -- file_size_round = 1u << (file_dat_bits + 3); -- if (file_size_round != l_size && -- (file_size_round < l_size || (file_size_round / 2) > l_size)) { -- return false; -+ seq_bits = sizeof(u64) * 8 + 3; -+ while (l_size) { -+ l_size >>= 1; -+ seq_bits -= 1; - } - -+ if (seq_bits != ra->seq_num_bits) -+ return false; -+ - /* The log page data offset and record header length must be quad-aligned. */ - if (!IS_ALIGNED(le16_to_cpu(ra->data_off), 8) || - !IS_ALIGNED(le16_to_cpu(ra->rec_hdr_len), 8)) -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index 4b72bc7f12ca3..1eac80d55b554 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -976,6 +976,30 @@ static inline __le32 security_hash(const void *sd, size_t bytes) - return cpu_to_le32(hash); - } - -+/* -+ * simple wrapper for sb_bread_unmovable. -+ */ -+struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block) -+{ -+ struct ntfs_sb_info *sbi = sb->s_fs_info; -+ struct buffer_head *bh; -+ -+ if (unlikely(block >= sbi->volume.blocks)) { -+ /* prevent generic message "attempt to access beyond end of device" */ -+ ntfs_err(sb, "try to read out of volume at offset 0x%llx", -+ (u64)block << sb->s_blocksize_bits); -+ return NULL; -+ } -+ -+ bh = sb_bread_unmovable(sb, block); -+ if (bh) -+ return bh; -+ -+ ntfs_err(sb, "failed to read volume at offset 0x%llx", -+ (u64)block << sb->s_blocksize_bits); -+ return NULL; -+} -+ - int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer) - { - struct block_device *bdev = sb->s_bdev; -diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c -index dc937089a464a..42dd9fdaf4151 100644 ---- a/fs/ntfs3/inode.c -+++ b/fs/ntfs3/inode.c -@@ -402,7 +402,6 @@ static struct inode *ntfs_read_mft(struct inode *inode, - goto out; - - if (!is_match && name) { -- /* Reuse rec as buffer for ascii name. */ - err = -ENOENT; - goto out; - } -@@ -417,6 +416,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, - - if (names != le16_to_cpu(rec->hard_links)) { - /* Correct minor error on the fly. Do not mark inode as dirty. */ -+ ntfs_inode_warn(inode, "Correct links count -> %u.", names); - rec->hard_links = cpu_to_le16(names); - ni->mi.dirty = true; - } -diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h -index 0f38d558169a1..ba26a465b3091 100644 ---- a/fs/ntfs3/ntfs.h -+++ b/fs/ntfs3/ntfs.h -@@ -517,12 +517,10 @@ struct ATTR_LIST_ENTRY { - __le64 vcn; // 0x08: Starting VCN of this attribute. - struct MFT_REF ref; // 0x10: MFT record number with attribute. - __le16 id; // 0x18: struct ATTRIB ID. -- __le16 name[3]; // 0x1A: Just to align. To get real name can use bNameOffset. -+ __le16 name[]; // 0x1A: Just to align. To get real name can use name_off. - - }; // sizeof(0x20) - --static_assert(sizeof(struct ATTR_LIST_ENTRY) == 0x20); -- - static inline u32 le_size(u8 name_len) - { - return ALIGN(offsetof(struct ATTR_LIST_ENTRY, name) + -diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h -index 74482ef569ab7..0f9bec29f2b70 100644 ---- a/fs/ntfs3/ntfs_fs.h -+++ b/fs/ntfs3/ntfs_fs.h -@@ -580,6 +580,7 @@ bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes); - int log_replay(struct ntfs_inode *ni, bool *initialized); - - /* Globals from fsntfs.c */ -+struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block); - bool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes); - int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes, - bool simple); -@@ -1012,19 +1013,6 @@ static inline u64 bytes_to_block(const struct super_block *sb, u64 size) - return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; - } - --static inline struct buffer_head *ntfs_bread(struct super_block *sb, -- sector_t block) --{ -- struct buffer_head *bh = sb_bread(sb, block); -- -- if (bh) -- return bh; -- -- ntfs_err(sb, "failed to read volume at offset 0x%llx", -- (u64)block << sb->s_blocksize_bits); -- return NULL; --} -- - static inline struct ntfs_inode *ntfs_i(struct inode *inode) - { - return container_of(inode, struct ntfs_inode, vfs_inode); -diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c -index ba336c7280b85..a8d4ed7bca025 100644 ---- a/fs/ntfs3/record.c -+++ b/fs/ntfs3/record.c -@@ -226,11 +226,6 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr) - return NULL; - } - -- if (off + asize < off) { -- /* overflow check */ -- return NULL; -- } -- - attr = Add2Ptr(attr, asize); - off += asize; - } -@@ -253,8 +248,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr) - if ((t32 & 0xf) || (t32 > 0x100)) - return NULL; - -- /* Check boundary. */ -- if (off + asize > used) -+ /* Check overflow and boundary. */ -+ if (off + asize < off || off + asize > used) - return NULL; - - /* Check size of attribute. */ -@@ -491,8 +486,20 @@ bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi, - return false; - - if (ni && is_attr_indexed(attr)) { -- le16_add_cpu(&ni->mi.mrec->hard_links, -1); -- ni->mi.dirty = true; -+ u16 links = le16_to_cpu(ni->mi.mrec->hard_links); -+ struct ATTR_FILE_NAME *fname = -+ attr->type != ATTR_NAME ? -+ NULL : -+ resident_data_ex(attr, -+ SIZEOF_ATTRIBUTE_FILENAME); -+ if (fname && fname->type == FILE_NAME_DOS) { -+ /* Do not decrease links count deleting DOS name. */ -+ } else if (!links) { -+ /* minor error. Not critical. */ -+ } else { -+ ni->mi.mrec->hard_links = cpu_to_le16(links - 1); -+ ni->mi.dirty = true; -+ } - } - - used -= asize; -diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c -index df15e00c2a3a0..d98cf7b382bcc 100644 ---- a/fs/ntfs3/xattr.c -+++ b/fs/ntfs3/xattr.c -@@ -217,6 +217,9 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, - if (!ea->name_len) - break; - -+ if (ea->name_len > ea_size) -+ break; -+ - if (buffer) { - /* Check if we can use field ea->name */ - if (off + ea_size > size) -diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c -index 6f4d7aa70e5a2..fd082151c5f9b 100644 ---- a/fs/smb/client/cached_dir.c -+++ b/fs/smb/client/cached_dir.c -@@ -149,7 +149,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, - return -EOPNOTSUPP; - - ses = tcon->ses; -- server = ses->server; -+ server = cifs_pick_channel(ses); - cfids = tcon->cfids; - - if (!server->ops->new_lease_key) -diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c -index d0ac2648c0d61..d3d4cf6321fd5 100644 ---- a/fs/smb/client/cifsencrypt.c -+++ b/fs/smb/client/cifsencrypt.c -@@ -444,7 +444,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, - len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); - UniStrupr(user); - } else { -- memset(user, '\0', 2); -+ *(u16 *)user = 0; - } - - rc = crypto_shash_update(ses->server->secmech.hmacmd5, -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 7f1aea4c11b9c..58bb54994e22a 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -86,7 +86,7 @@ - #define SMB_INTERFACE_POLL_INTERVAL 600 - - /* maximum number of PDUs in one compound */ --#define MAX_COMPOUND 5 -+#define MAX_COMPOUND 7 - - /* - * Default number of credits to keep available for SMB3. -diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c -index f4818599c00a2..4d5302b58b534 100644 ---- a/fs/smb/client/fs_context.c -+++ b/fs/smb/client/fs_context.c -@@ -209,7 +209,7 @@ cifs_parse_security_flavors(struct fs_context *fc, char *value, struct smb3_fs_c - - switch (match_token(value, cifs_secflavor_tokens, args)) { - case Opt_sec_krb5p: -- cifs_errorf(fc, "sec=krb5p is not supported!\n"); -+ cifs_errorf(fc, "sec=krb5p is not supported. Use sec=krb5,seal instead\n"); - return 1; - case Opt_sec_krb5i: - ctx->sign = true; -diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c -index 2d75ba5aaa8ad..5990bdbae598f 100644 ---- a/fs/smb/client/readdir.c -+++ b/fs/smb/client/readdir.c -@@ -304,14 +304,16 @@ cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, - } - - static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr, -- SEARCH_ID_FULL_DIR_INFO *info, -+ const void *info, - struct cifs_sb_info *cifs_sb) - { -+ const FILE_FULL_DIRECTORY_INFO *di = info; -+ - __dir_info_to_fattr(fattr, info); - -- /* See MS-FSCC 2.4.19 FileIdFullDirectoryInformation */ -+ /* See MS-FSCC 2.4.14, 2.4.19 */ - if (fattr->cf_cifsattrs & ATTR_REPARSE) -- fattr->cf_cifstag = le32_to_cpu(info->EaSize); -+ fattr->cf_cifstag = le32_to_cpu(di->EaSize); - cifs_fill_common_info(fattr, cifs_sb); - } - -@@ -425,7 +427,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { - cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; - } else /* not srvinos - BB fixme add check for backlevel? */ { -- cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; -+ cifsFile->srch_inf.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO; - } - - search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME; -@@ -1019,10 +1021,9 @@ static int cifs_filldir(char *find_entry, struct file *file, - (FIND_FILE_STANDARD_INFO *)find_entry, - cifs_sb); - break; -+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO: - case SMB_FIND_FILE_ID_FULL_DIR_INFO: -- cifs_fulldir_info_to_fattr(&fattr, -- (SEARCH_ID_FULL_DIR_INFO *)find_entry, -- cifs_sb); -+ cifs_fulldir_info_to_fattr(&fattr, find_entry, cifs_sb); - break; - default: - cifs_dir_info_to_fattr(&fattr, -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index c1fc1651d8b69..4c1231496a725 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -5010,6 +5010,9 @@ int SMB2_query_directory_init(const unsigned int xid, - case SMB_FIND_FILE_POSIX_INFO: - req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO; - break; -+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO: -+ req->FileInformationClass = FILE_FULL_DIRECTORY_INFORMATION; -+ break; - default: - cifs_tcon_dbg(VFS, "info level %u isn't supported\n", - info_level); -@@ -5079,6 +5082,9 @@ smb2_parse_query_directory(struct cifs_tcon *tcon, - /* note that posix payload are variable size */ - info_buf_size = sizeof(struct smb2_posix_info); - break; -+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO: -+ info_buf_size = sizeof(FILE_FULL_DIRECTORY_INFO); -+ break; - default: - cifs_tcon_dbg(VFS, "info level %u isn't supported\n", - srch_inf->info_level); -diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c -index 8a1dd8407a3a7..df44acaec9ae9 100644 ---- a/fs/smb/client/transport.c -+++ b/fs/smb/client/transport.c -@@ -427,10 +427,17 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, - server->conn_id, server->hostname); - } - smbd_done: -- if (rc < 0 && rc != -EINTR) -+ /* -+ * there's hardly any use for the layers above to know the -+ * actual error code here. All they should do at this point is -+ * to retry the connection and hope it goes away. -+ */ -+ if (rc < 0 && rc != -EINTR && rc != -EAGAIN) { - cifs_server_dbg(VFS, "Error %d sending data on socket to server\n", - rc); -- else if (rc > 0) -+ rc = -ECONNABORTED; -+ cifs_signal_cifsd_for_reconnect(server, false); -+ } else if (rc > 0) - rc = 0; - out: - cifs_in_send_dec(server); -@@ -449,8 +456,8 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, - if (!(flags & CIFS_TRANSFORM_REQ)) - return __smb_send_rqst(server, num_rqst, rqst); - -- if (num_rqst > MAX_COMPOUND - 1) -- return -ENOMEM; -+ if (WARN_ON_ONCE(num_rqst > MAX_COMPOUND - 1)) -+ return -EIO; - - if (!server->ops->init_transform_rq) { - cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n"); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 4a1911dcf834b..67313881f8ac1 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -337,6 +337,8 @@ enum rw_hint { - #define IOCB_NOIO (1 << 20) - /* can use bio alloc cache */ - #define IOCB_ALLOC_CACHE (1 << 21) -+/* kiocb is a read or write operation submitted by fs/aio.c. */ -+#define IOCB_AIO_RW (1 << 23) - - struct kiocb { - struct file *ki_filp; -diff --git a/include/linux/memblock.h b/include/linux/memblock.h -index 50ad19662a322..6790f08066b72 100644 ---- a/include/linux/memblock.h -+++ b/include/linux/memblock.h -@@ -118,6 +118,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size); - int memblock_physmem_add(phys_addr_t base, phys_addr_t size); - #endif - void memblock_trim_memory(phys_addr_t align); -+unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, -+ phys_addr_t base2, phys_addr_t size2); - bool memblock_overlaps_region(struct memblock_type *type, - phys_addr_t base, phys_addr_t size); - int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); -diff --git a/include/linux/socket.h b/include/linux/socket.h -index b3c58042bd254..d79efd0268809 100644 ---- a/include/linux/socket.h -+++ b/include/linux/socket.h -@@ -33,7 +33,10 @@ typedef __kernel_sa_family_t sa_family_t; - - struct sockaddr { - sa_family_t sa_family; /* address family, AF_xxx */ -- char sa_data[14]; /* 14 bytes of protocol address */ -+ union { -+ char sa_data_min[14]; /* Minimum 14 bytes of protocol address */ -+ DECLARE_FLEX_ARRAY(char, sa_data); -+ }; - }; - - struct linger { -diff --git a/include/linux/swap.h b/include/linux/swap.h -index a18cf4b7c724c..add47f43e568e 100644 ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -571,6 +571,11 @@ static inline int swap_duplicate(swp_entry_t swp) - return 0; - } - -+static inline int swapcache_prepare(swp_entry_t swp) -+{ -+ return 0; -+} -+ - static inline void swap_free(swp_entry_t swp) - { - } -diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h -index dde4dd9c4012c..4a767b3d20b9d 100644 ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -274,8 +274,8 @@ nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, - flow_table->type->put(flow_table); - } - --int flow_offload_route_init(struct flow_offload *flow, -- const struct nf_flow_route *route); -+void flow_offload_route_init(struct flow_offload *flow, -+ struct nf_flow_route *route); - - int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); - void flow_offload_refresh(struct nf_flowtable *flow_table, -diff --git a/include/net/switchdev.h b/include/net/switchdev.h -index 7dcdc97c0bc33..a3d8f013adcd5 100644 ---- a/include/net/switchdev.h -+++ b/include/net/switchdev.h -@@ -303,6 +303,9 @@ void switchdev_deferred_process(void); - int switchdev_port_attr_set(struct net_device *dev, - const struct switchdev_attr *attr, - struct netlink_ext_ack *extack); -+bool switchdev_port_obj_act_is_deferred(struct net_device *dev, -+ enum switchdev_notifier_type nt, -+ const struct switchdev_obj *obj); - int switchdev_port_obj_add(struct net_device *dev, - const struct switchdev_obj *obj, - struct netlink_ext_ack *extack); -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 4c838f7290dd9..8ea1fba84eff9 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -2290,7 +2290,7 @@ struct tcp_ulp_ops { - /* cleanup ulp */ - void (*release)(struct sock *sk); - /* diagnostic */ -- int (*get_info)(const struct sock *sk, struct sk_buff *skb); -+ int (*get_info)(struct sock *sk, struct sk_buff *skb); - size_t (*get_info_size)(const struct sock *sk); - /* clone ulp */ - void (*clone)(const struct request_sock *req, struct sock *newsk, -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index fdc31fdb612da..d2751ed536df2 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -100,10 +100,6 @@ struct scsi_vpd { - unsigned char data[]; - }; - --enum scsi_vpd_parameters { -- SCSI_VPD_HEADER_SIZE = 4, --}; -- - struct scsi_device { - struct Scsi_Host *host; - struct request_queue *request_queue; -diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c -index 6a61a98d602cd..83f8f67e933df 100644 ---- a/kernel/bpf/helpers.c -+++ b/kernel/bpf/helpers.c -@@ -1091,6 +1091,7 @@ struct bpf_hrtimer { - struct bpf_prog *prog; - void __rcu *callback_fn; - void *value; -+ struct rcu_head rcu; - }; - - /* the actual struct hidden inside uapi struct bpf_timer */ -@@ -1312,6 +1313,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer) - - if (in_nmi()) - return -EOPNOTSUPP; -+ rcu_read_lock(); - __bpf_spin_lock_irqsave(&timer->lock); - t = timer->timer; - if (!t) { -@@ -1333,6 +1335,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_timer_kern *, timer) - * if it was running. - */ - ret = ret ?: hrtimer_cancel(&t->timer); -+ rcu_read_unlock(); - return ret; - } - -@@ -1387,7 +1390,7 @@ void bpf_timer_cancel_and_free(void *val) - */ - if (this_cpu_read(hrtimer_running) != t) - hrtimer_cancel(&t->timer); -- kfree(t); -+ kfree_rcu(t, rcu); - } - - BPF_CALL_2(bpf_kptr_xchg, void *, map_value, void *, ptr) -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index 76bafa8d331a7..3a2335bc1d58b 100644 ---- a/kernel/sched/rt.c -+++ b/kernel/sched/rt.c -@@ -37,6 +37,8 @@ static struct ctl_table sched_rt_sysctls[] = { - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = sched_rt_handler, -+ .extra1 = SYSCTL_ONE, -+ .extra2 = SYSCTL_INT_MAX, - }, - { - .procname = "sched_rt_runtime_us", -@@ -44,6 +46,8 @@ static struct ctl_table sched_rt_sysctls[] = { - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = sched_rt_handler, -+ .extra1 = SYSCTL_NEG_ONE, -+ .extra2 = SYSCTL_INT_MAX, - }, - { - .procname = "sched_rr_timeslice_ms", -@@ -2970,9 +2974,6 @@ static int sched_rt_global_constraints(void) - #ifdef CONFIG_SYSCTL - static int sched_rt_global_validate(void) - { -- if (sysctl_sched_rt_period <= 0) -- return -EINVAL; -- - if ((sysctl_sched_rt_runtime != RUNTIME_INF) && - ((sysctl_sched_rt_runtime > sysctl_sched_rt_period) || - ((u64)sysctl_sched_rt_runtime * -@@ -3003,7 +3004,7 @@ static int sched_rt_handler(struct ctl_table *table, int write, void *buffer, - old_period = sysctl_sched_rt_period; - old_runtime = sysctl_sched_rt_runtime; - -- ret = proc_dointvec(table, write, buffer, lenp, ppos); -+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - - if (!ret && write) { - ret = sched_rt_global_validate(); -@@ -3047,6 +3048,9 @@ static int sched_rr_handler(struct ctl_table *table, int write, void *buffer, - sched_rr_timeslice = - sysctl_sched_rr_timeslice <= 0 ? RR_TIMESLICE : - msecs_to_jiffies(sysctl_sched_rr_timeslice); -+ -+ if (sysctl_sched_rr_timeslice <= 0) -+ sysctl_sched_rr_timeslice = jiffies_to_msecs(RR_TIMESLICE); - } - mutex_unlock(&mutex); - -diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c -index 63bdad20dbaf8..98a678129b067 100644 ---- a/mm/damon/lru_sort.c -+++ b/mm/damon/lru_sort.c -@@ -185,9 +185,21 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres) - return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_DEPRIO); - } - -+static void damon_lru_sort_copy_quota_status(struct damos_quota *dst, -+ struct damos_quota *src) -+{ -+ dst->total_charged_sz = src->total_charged_sz; -+ dst->total_charged_ns = src->total_charged_ns; -+ dst->charged_sz = src->charged_sz; -+ dst->charged_from = src->charged_from; -+ dst->charge_target_from = src->charge_target_from; -+ dst->charge_addr_from = src->charge_addr_from; -+} -+ - static int damon_lru_sort_apply_parameters(void) - { -- struct damos *scheme; -+ struct damos *scheme, *hot_scheme, *cold_scheme; -+ struct damos *old_hot_scheme = NULL, *old_cold_scheme = NULL; - unsigned int hot_thres, cold_thres; - int err = 0; - -@@ -195,18 +207,35 @@ static int damon_lru_sort_apply_parameters(void) - if (err) - return err; - -+ damon_for_each_scheme(scheme, ctx) { -+ if (!old_hot_scheme) { -+ old_hot_scheme = scheme; -+ continue; -+ } -+ old_cold_scheme = scheme; -+ } -+ - hot_thres = damon_max_nr_accesses(&damon_lru_sort_mon_attrs) * - hot_thres_access_freq / 1000; -- scheme = damon_lru_sort_new_hot_scheme(hot_thres); -- if (!scheme) -+ hot_scheme = damon_lru_sort_new_hot_scheme(hot_thres); -+ if (!hot_scheme) - return -ENOMEM; -- damon_set_schemes(ctx, &scheme, 1); -+ if (old_hot_scheme) -+ damon_lru_sort_copy_quota_status(&hot_scheme->quota, -+ &old_hot_scheme->quota); - - cold_thres = cold_min_age / damon_lru_sort_mon_attrs.aggr_interval; -- scheme = damon_lru_sort_new_cold_scheme(cold_thres); -- if (!scheme) -+ cold_scheme = damon_lru_sort_new_cold_scheme(cold_thres); -+ if (!cold_scheme) { -+ damon_destroy_scheme(hot_scheme); - return -ENOMEM; -- damon_add_scheme(ctx, scheme); -+ } -+ if (old_cold_scheme) -+ damon_lru_sort_copy_quota_status(&cold_scheme->quota, -+ &old_cold_scheme->quota); -+ -+ damon_set_schemes(ctx, &hot_scheme, 1); -+ damon_add_scheme(ctx, cold_scheme); - - return damon_set_region_biggest_system_ram_default(target, - &monitor_region_start, -diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c -index 162c9b1ca00fd..cc337e94acfda 100644 ---- a/mm/damon/reclaim.c -+++ b/mm/damon/reclaim.c -@@ -141,9 +141,20 @@ static struct damos *damon_reclaim_new_scheme(void) - &damon_reclaim_wmarks); - } - -+static void damon_reclaim_copy_quota_status(struct damos_quota *dst, -+ struct damos_quota *src) -+{ -+ dst->total_charged_sz = src->total_charged_sz; -+ dst->total_charged_ns = src->total_charged_ns; -+ dst->charged_sz = src->charged_sz; -+ dst->charged_from = src->charged_from; -+ dst->charge_target_from = src->charge_target_from; -+ dst->charge_addr_from = src->charge_addr_from; -+} -+ - static int damon_reclaim_apply_parameters(void) - { -- struct damos *scheme; -+ struct damos *scheme, *old_scheme; - int err = 0; - - err = damon_set_attrs(ctx, &damon_reclaim_mon_attrs); -@@ -154,6 +165,11 @@ static int damon_reclaim_apply_parameters(void) - scheme = damon_reclaim_new_scheme(); - if (!scheme) - return -ENOMEM; -+ if (!list_empty(&ctx->schemes)) { -+ damon_for_each_scheme(old_scheme, ctx) -+ damon_reclaim_copy_quota_status(&scheme->quota, -+ &old_scheme->quota); -+ } - damon_set_schemes(ctx, &scheme, 1); - - return damon_set_region_biggest_system_ram_default(target, -diff --git a/mm/memblock.c b/mm/memblock.c -index 511d4783dcf1d..516efec80851a 100644 ---- a/mm/memblock.c -+++ b/mm/memblock.c -@@ -175,8 +175,9 @@ static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size) - /* - * Address comparison utilities - */ --static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, -- phys_addr_t base2, phys_addr_t size2) -+unsigned long __init_memblock -+memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, phys_addr_t base2, -+ phys_addr_t size2) - { - return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); - } -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 9da98e3e71cfe..4570d3e315cf1 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -7517,9 +7517,13 @@ bool mem_cgroup_swap_full(struct folio *folio) - - static int __init setup_swap_account(char *s) - { -- pr_warn_once("The swapaccount= commandline option is deprecated. " -- "Please report your usecase to linux-mm@kvack.org if you " -- "depend on this functionality.\n"); -+ bool res; -+ -+ if (!kstrtobool(s, &res) && !res) -+ pr_warn_once("The swapaccount=0 commandline option is deprecated " -+ "in favor of configuring swap control via cgroupfs. " -+ "Please report your usecase to linux-mm@kvack.org if you " -+ "depend on this functionality.\n"); - return 1; - } - __setup("swapaccount=", setup_swap_account); -diff --git a/mm/memory.c b/mm/memory.c -index fc8b264ec0cac..fb83cf56377ab 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -3761,6 +3761,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) - struct page *page; - struct swap_info_struct *si = NULL; - rmap_t rmap_flags = RMAP_NONE; -+ bool need_clear_cache = false; - bool exclusive = false; - swp_entry_t entry; - pte_t pte; -@@ -3822,6 +3823,20 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) - if (!folio) { - if (data_race(si->flags & SWP_SYNCHRONOUS_IO) && - __swap_count(entry) == 1) { -+ /* -+ * Prevent parallel swapin from proceeding with -+ * the cache flag. Otherwise, another thread may -+ * finish swapin first, free the entry, and swapout -+ * reusing the same entry. It's undetectable as -+ * pte_same() returns true due to entry reuse. -+ */ -+ if (swapcache_prepare(entry)) { -+ /* Relax a bit to prevent rapid repeated page faults */ -+ schedule_timeout_uninterruptible(1); -+ goto out; -+ } -+ need_clear_cache = true; -+ - /* skip swapcache */ - folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, - vma, vmf->address, false); -@@ -4073,6 +4088,9 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) - unlock: - pte_unmap_unlock(vmf->pte, vmf->ptl); - out: -+ /* Clear the swap cache pin for direct swapin after PTL unlock */ -+ if (need_clear_cache) -+ swapcache_clear(si, entry); - if (si) - put_swap_device(si); - return ret; -@@ -4086,6 +4104,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) - folio_unlock(swapcache); - folio_put(swapcache); - } -+ if (need_clear_cache) -+ swapcache_clear(si, entry); - if (si) - put_swap_device(si); - return ret; -diff --git a/mm/swap.h b/mm/swap.h -index cc08c459c6190..5eff40ef76934 100644 ---- a/mm/swap.h -+++ b/mm/swap.h -@@ -39,6 +39,7 @@ void __delete_from_swap_cache(struct folio *folio, - void delete_from_swap_cache(struct folio *folio); - void clear_shadow_from_swap_cache(int type, unsigned long begin, - unsigned long end); -+void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry); - struct folio *swap_cache_get_folio(swp_entry_t entry, - struct vm_area_struct *vma, unsigned long addr); - struct page *find_get_incore_page(struct address_space *mapping, pgoff_t index); -@@ -98,6 +99,10 @@ static inline int swap_writepage(struct page *p, struct writeback_control *wbc) - return 0; - } - -+static inline void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry) -+{ -+} -+ - static inline struct folio *swap_cache_get_folio(swp_entry_t entry, - struct vm_area_struct *vma, unsigned long addr) - { -diff --git a/mm/swapfile.c b/mm/swapfile.c -index 71db6d8a1ea30..cca9fda9d036f 100644 ---- a/mm/swapfile.c -+++ b/mm/swapfile.c -@@ -3373,6 +3373,19 @@ int swapcache_prepare(swp_entry_t entry) - return __swap_duplicate(entry, SWAP_HAS_CACHE); - } - -+void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry) -+{ -+ struct swap_cluster_info *ci; -+ unsigned long offset = swp_offset(entry); -+ unsigned char usage; -+ -+ ci = lock_cluster_or_swap_info(si, offset); -+ usage = __swap_entry_free_locked(si, offset, SWAP_HAS_CACHE); -+ unlock_cluster_or_swap_info(si, ci); -+ if (!usage) -+ free_swap_slot(entry); -+} -+ - struct swap_info_struct *swp_swap_info(swp_entry_t entry) - { - return swap_type_to_swap_info(swp_type(entry)); -diff --git a/mm/zswap.c b/mm/zswap.c -index b3829ada4a413..b7cb126797f9e 100644 ---- a/mm/zswap.c -+++ b/mm/zswap.c -@@ -1013,6 +1013,8 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle) - if (zswap_rb_search(&tree->rbroot, entry->offset) != entry) { - spin_unlock(&tree->lock); - delete_from_swap_cache(page_folio(page)); -+ unlock_page(page); -+ put_page(page); - ret = -ENOMEM; - goto fail; - } -diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c -index 4b3982c368b35..b61ef2dff7a4b 100644 ---- a/net/bridge/br_switchdev.c -+++ b/net/bridge/br_switchdev.c -@@ -593,21 +593,40 @@ br_switchdev_mdb_replay_one(struct notifier_block *nb, struct net_device *dev, - } - - static int br_switchdev_mdb_queue_one(struct list_head *mdb_list, -+ struct net_device *dev, -+ unsigned long action, - enum switchdev_obj_id id, - const struct net_bridge_mdb_entry *mp, - struct net_device *orig_dev) - { -- struct switchdev_obj_port_mdb *mdb; -+ struct switchdev_obj_port_mdb mdb = { -+ .obj = { -+ .id = id, -+ .orig_dev = orig_dev, -+ }, -+ }; -+ struct switchdev_obj_port_mdb *pmdb; - -- mdb = kzalloc(sizeof(*mdb), GFP_ATOMIC); -- if (!mdb) -- return -ENOMEM; -+ br_switchdev_mdb_populate(&mdb, mp); -+ -+ if (action == SWITCHDEV_PORT_OBJ_ADD && -+ switchdev_port_obj_act_is_deferred(dev, action, &mdb.obj)) { -+ /* This event is already in the deferred queue of -+ * events, so this replay must be elided, lest the -+ * driver receives duplicate events for it. This can -+ * only happen when replaying additions, since -+ * modifications are always immediately visible in -+ * br->mdb_list, whereas actual event delivery may be -+ * delayed. -+ */ -+ return 0; -+ } - -- mdb->obj.id = id; -- mdb->obj.orig_dev = orig_dev; -- br_switchdev_mdb_populate(mdb, mp); -- list_add_tail(&mdb->obj.list, mdb_list); -+ pmdb = kmemdup(&mdb, sizeof(mdb), GFP_ATOMIC); -+ if (!pmdb) -+ return -ENOMEM; - -+ list_add_tail(&pmdb->obj.list, mdb_list); - return 0; - } - -@@ -675,51 +694,50 @@ br_switchdev_mdb_replay(struct net_device *br_dev, struct net_device *dev, - if (!br_opt_get(br, BROPT_MULTICAST_ENABLED)) - return 0; - -- /* We cannot walk over br->mdb_list protected just by the rtnl_mutex, -- * because the write-side protection is br->multicast_lock. But we -- * need to emulate the [ blocking ] calling context of a regular -- * switchdev event, so since both br->multicast_lock and RCU read side -- * critical sections are atomic, we have no choice but to pick the RCU -- * read side lock, queue up all our events, leave the critical section -- * and notify switchdev from blocking context. -+ if (adding) -+ action = SWITCHDEV_PORT_OBJ_ADD; -+ else -+ action = SWITCHDEV_PORT_OBJ_DEL; -+ -+ /* br_switchdev_mdb_queue_one() will take care to not queue a -+ * replay of an event that is already pending in the switchdev -+ * deferred queue. In order to safely determine that, there -+ * must be no new deferred MDB notifications enqueued for the -+ * duration of the MDB scan. Therefore, grab the write-side -+ * lock to avoid racing with any concurrent IGMP/MLD snooping. - */ -- rcu_read_lock(); -+ spin_lock_bh(&br->multicast_lock); - -- hlist_for_each_entry_rcu(mp, &br->mdb_list, mdb_node) { -+ hlist_for_each_entry(mp, &br->mdb_list, mdb_node) { - struct net_bridge_port_group __rcu * const *pp; - const struct net_bridge_port_group *p; - - if (mp->host_joined) { -- err = br_switchdev_mdb_queue_one(&mdb_list, -+ err = br_switchdev_mdb_queue_one(&mdb_list, dev, action, - SWITCHDEV_OBJ_ID_HOST_MDB, - mp, br_dev); - if (err) { -- rcu_read_unlock(); -+ spin_unlock_bh(&br->multicast_lock); - goto out_free_mdb; - } - } - -- for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL; -+ for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { - if (p->key.port->dev != dev) - continue; - -- err = br_switchdev_mdb_queue_one(&mdb_list, -+ err = br_switchdev_mdb_queue_one(&mdb_list, dev, action, - SWITCHDEV_OBJ_ID_PORT_MDB, - mp, dev); - if (err) { -- rcu_read_unlock(); -+ spin_unlock_bh(&br->multicast_lock); - goto out_free_mdb; - } - } - } - -- rcu_read_unlock(); -- -- if (adding) -- action = SWITCHDEV_PORT_OBJ_ADD; -- else -- action = SWITCHDEV_PORT_OBJ_DEL; -+ spin_unlock_bh(&br->multicast_lock); - - list_for_each_entry(obj, &mdb_list, list) { - err = br_switchdev_mdb_replay_one(nb, dev, -@@ -780,6 +798,16 @@ static void nbp_switchdev_unsync_objs(struct net_bridge_port *p, - br_switchdev_mdb_replay(br_dev, dev, ctx, false, blocking_nb, NULL); - - br_switchdev_vlan_replay(br_dev, ctx, false, blocking_nb, NULL); -+ -+ /* Make sure that the device leaving this bridge has seen all -+ * relevant events before it is disassociated. In the normal -+ * case, when the device is directly attached to the bridge, -+ * this is covered by del_nbp(). If the association was indirect -+ * however, e.g. via a team or bond, and the device is leaving -+ * that intermediate device, then the bridge port remains in -+ * place. -+ */ -+ switchdev_deferred_process(); - } - - /* Let the bridge know that this port is offloaded, so that it can assign a -diff --git a/net/core/dev.c b/net/core/dev.c -index 1ba3662faf0aa..60619fe8af5fc 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -8861,7 +8861,7 @@ EXPORT_SYMBOL(dev_set_mac_address_user); - - int dev_get_mac_address(struct sockaddr *sa, struct net *net, char *dev_name) - { -- size_t size = sizeof(sa->sa_data); -+ size_t size = sizeof(sa->sa_data_min); - struct net_device *dev; - int ret = 0; - -diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c -index 7674bb9f3076c..5cdbfbf9a7dcf 100644 ---- a/net/core/dev_ioctl.c -+++ b/net/core/dev_ioctl.c -@@ -342,7 +342,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, - if (ifr->ifr_hwaddr.sa_family != dev->type) - return -EINVAL; - memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, -- min(sizeof(ifr->ifr_hwaddr.sa_data), -+ min(sizeof(ifr->ifr_hwaddr.sa_data_min), - (size_t)dev->addr_len)); - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - return 0; -diff --git a/net/core/skmsg.c b/net/core/skmsg.c -index 3818035ea0021..39643f78cf782 100644 ---- a/net/core/skmsg.c -+++ b/net/core/skmsg.c -@@ -1217,8 +1217,11 @@ static void sk_psock_verdict_data_ready(struct sock *sk) - - rcu_read_lock(); - psock = sk_psock(sk); -- if (psock) -- psock->saved_data_ready(sk); -+ if (psock) { -+ read_lock_bh(&sk->sk_callback_lock); -+ sk_psock_data_ready(sk, psock); -+ read_unlock_bh(&sk->sk_callback_lock); -+ } - rcu_read_unlock(); - } - } -diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c -index 9456f5bb35e5d..ccff96820a703 100644 ---- a/net/ipv4/arp.c -+++ b/net/ipv4/arp.c -@@ -1125,7 +1125,8 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) - if (neigh) { - if (!(READ_ONCE(neigh->nud_state) & NUD_NOARP)) { - read_lock_bh(&neigh->lock); -- memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); -+ memcpy(r->arp_ha.sa_data, neigh->ha, -+ min(dev->addr_len, (unsigned char)sizeof(r->arp_ha.sa_data_min))); - r->arp_flags = arp_state_to_flags(neigh); - read_unlock_bh(&neigh->lock); - r->arp_ha.sa_family = dev->type; -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index 35d6e74be8406..bb0d1252cad86 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -1804,6 +1804,21 @@ static int in_dev_dump_addr(struct in_device *in_dev, struct sk_buff *skb, - return err; - } - -+/* Combine dev_addr_genid and dev_base_seq to detect changes. -+ */ -+static u32 inet_base_seq(const struct net *net) -+{ -+ u32 res = atomic_read(&net->ipv4.dev_addr_genid) + -+ net->dev_base_seq; -+ -+ /* Must not return 0 (see nl_dump_check_consistent()). -+ * Chose a value far away from 0. -+ */ -+ if (!res) -+ res = 0x80000000; -+ return res; -+} -+ - static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) - { - const struct nlmsghdr *nlh = cb->nlh; -@@ -1855,8 +1870,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) - idx = 0; - head = &tgt_net->dev_index_head[h]; - rcu_read_lock(); -- cb->seq = atomic_read(&tgt_net->ipv4.dev_addr_genid) ^ -- tgt_net->dev_base_seq; -+ cb->seq = inet_base_seq(tgt_net); - hlist_for_each_entry_rcu(dev, head, index_hlist) { - if (idx < s_idx) - goto cont; -@@ -2257,8 +2271,7 @@ static int inet_netconf_dump_devconf(struct sk_buff *skb, - idx = 0; - head = &net->dev_index_head[h]; - rcu_read_lock(); -- cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^ -- net->dev_base_seq; -+ cb->seq = inet_base_seq(net); - hlist_for_each_entry_rcu(dev, head, index_hlist) { - if (idx < s_idx) - goto cont; -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index f2ed2aed08ab3..56776e1b1de52 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -1111,10 +1111,33 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, - return 0; - - error: -+ if (sk_hashed(sk)) { -+ spinlock_t *lock = inet_ehash_lockp(hinfo, sk->sk_hash); -+ -+ sock_prot_inuse_add(net, sk->sk_prot, -1); -+ -+ spin_lock(lock); -+ sk_nulls_del_node_init_rcu(sk); -+ spin_unlock(lock); -+ -+ sk->sk_hash = 0; -+ inet_sk(sk)->inet_sport = 0; -+ inet_sk(sk)->inet_num = 0; -+ -+ if (tw) -+ inet_twsk_bind_unhash(tw, hinfo); -+ } -+ - spin_unlock(&head2->lock); - if (tb_created) - inet_bind_bucket_destroy(hinfo->bind_bucket_cachep, tb); -- spin_unlock_bh(&head->lock); -+ spin_unlock(&head->lock); -+ -+ if (tw) -+ inet_twsk_deschedule_put(tw); -+ -+ local_bh_enable(); -+ - return -ENOMEM; - } - -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index b8dc20fe7a4e2..46527b5cc8f0c 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -706,6 +706,22 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb, - return err; - } - -+/* Combine dev_addr_genid and dev_base_seq to detect changes. -+ */ -+static u32 inet6_base_seq(const struct net *net) -+{ -+ u32 res = atomic_read(&net->ipv6.dev_addr_genid) + -+ net->dev_base_seq; -+ -+ /* Must not return 0 (see nl_dump_check_consistent()). -+ * Chose a value far away from 0. -+ */ -+ if (!res) -+ res = 0x80000000; -+ return res; -+} -+ -+ - static int inet6_netconf_dump_devconf(struct sk_buff *skb, - struct netlink_callback *cb) - { -@@ -739,8 +755,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb, - idx = 0; - head = &net->dev_index_head[h]; - rcu_read_lock(); -- cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ -- net->dev_base_seq; -+ cb->seq = inet6_base_seq(net); - hlist_for_each_entry_rcu(dev, head, index_hlist) { - if (idx < s_idx) - goto cont; -@@ -5326,7 +5341,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, - } - - rcu_read_lock(); -- cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq; -+ cb->seq = inet6_base_seq(tgt_net); - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { - idx = 0; - head = &tgt_net->dev_index_head[h]; -diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c -index 5fa0e37305d9d..1cfdd9d950123 100644 ---- a/net/ipv6/exthdrs.c -+++ b/net/ipv6/exthdrs.c -@@ -180,6 +180,8 @@ static bool ip6_parse_tlv(bool hopbyhop, - case IPV6_TLV_IOAM: - if (!ipv6_hop_ioam(skb, off)) - return false; -+ -+ nh = skb_network_header(skb); - break; - case IPV6_TLV_JUMBO: - if (!ipv6_hop_jumbo(skb, off)) -@@ -974,6 +976,14 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff) - if (!skb_valid_dst(skb)) - ip6_route_input(skb); - -+ /* About to mangle packet header */ -+ if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len)) -+ goto drop; -+ -+ /* Trace pointer may have changed */ -+ trace = (struct ioam6_trace_hdr *)(skb_network_header(skb) -+ + optoff + sizeof(*hdr)); -+ - ioam6_fill_trace_data(skb, ns, trace, true); - break; - default: -diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c -index 29346a6eec9ff..35508abd76f43 100644 ---- a/net/ipv6/seg6.c -+++ b/net/ipv6/seg6.c -@@ -512,22 +512,24 @@ int __init seg6_init(void) - { - int err; - -- err = genl_register_family(&seg6_genl_family); -+ err = register_pernet_subsys(&ip6_segments_ops); - if (err) - goto out; - -- err = register_pernet_subsys(&ip6_segments_ops); -+ err = genl_register_family(&seg6_genl_family); - if (err) -- goto out_unregister_genl; -+ goto out_unregister_pernet; - - #ifdef CONFIG_IPV6_SEG6_LWTUNNEL - err = seg6_iptunnel_init(); - if (err) -- goto out_unregister_pernet; -+ goto out_unregister_genl; - - err = seg6_local_init(); -- if (err) -- goto out_unregister_pernet; -+ if (err) { -+ seg6_iptunnel_exit(); -+ goto out_unregister_genl; -+ } - #endif - - #ifdef CONFIG_IPV6_SEG6_HMAC -@@ -548,11 +550,11 @@ int __init seg6_init(void) - #endif - #endif - #ifdef CONFIG_IPV6_SEG6_LWTUNNEL --out_unregister_pernet: -- unregister_pernet_subsys(&ip6_segments_ops); --#endif - out_unregister_genl: - genl_unregister_family(&seg6_genl_family); -+#endif -+out_unregister_pernet: -+ unregister_pernet_subsys(&ip6_segments_ops); - goto out; - } - -diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c -index 314ec3a51e8de..bb92dc8b82f39 100644 ---- a/net/l2tp/l2tp_ip6.c -+++ b/net/l2tp/l2tp_ip6.c -@@ -630,7 +630,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - back_from_confirm: - lock_sock(sk); -- ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; -+ ulen = len + (skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0); - err = ip6_append_data(sk, ip_generic_getfrag, msg, - ulen, transhdrlen, &ipc6, - &fl6, (struct rt6_info *)dst, -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index a2c4866080bd7..6cf0b77839d1d 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1775,6 +1775,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, - sband->band); - } - -+ ieee80211_sta_set_rx_nss(link_sta); -+ - return ret; - } - -diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c -index c6f0da028a2a4..f25dc6931a5b1 100644 ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -7294,6 +7294,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, - ieee80211_report_disconnect(sdata, frame_buf, - sizeof(frame_buf), true, - req->reason_code, false); -+ drv_mgd_complete_tx(sdata->local, sdata, &info); - return 0; - } - -diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c -index f3d6c3e4c970e..bd56015b29258 100644 ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -891,6 +891,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) - if (ieee80211_vif_is_mesh(&sdata->vif)) - mesh_accept_plinks_update(sdata); - -+ ieee80211_check_fast_xmit(sta); -+ - return 0; - out_remove: - if (sta->sta.valid_links) -diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c -index 322a035f75929..3d62e8b718740 100644 ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3044,7 +3044,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta) - sdata->vif.type == NL80211_IFTYPE_STATION) - goto out; - -- if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) -+ if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !sta->uploaded) - goto out; - - if (test_sta_flag(sta, WLAN_STA_PS_STA) || -diff --git a/net/mctp/route.c b/net/mctp/route.c -index 68be8f2b622dd..256bf0b89e6ca 100644 ---- a/net/mctp/route.c -+++ b/net/mctp/route.c -@@ -663,7 +663,7 @@ struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk, - spin_unlock_irqrestore(&mns->keys_lock, flags); - - if (!tagbits) { -- kfree(key); -+ mctp_key_unref(key); - return ERR_PTR(-EBUSY); - } - -diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c -index a536586742f28..e57c5f47f0351 100644 ---- a/net/mptcp/diag.c -+++ b/net/mptcp/diag.c -@@ -13,17 +13,19 @@ - #include - #include "protocol.h" - --static int subflow_get_info(const struct sock *sk, struct sk_buff *skb) -+static int subflow_get_info(struct sock *sk, struct sk_buff *skb) - { - struct mptcp_subflow_context *sf; - struct nlattr *start; - u32 flags = 0; -+ bool slow; - int err; - - start = nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP); - if (!start) - return -EMSGSIZE; - -+ slow = lock_sock_fast(sk); - rcu_read_lock(); - sf = rcu_dereference(inet_csk(sk)->icsk_ulp_data); - if (!sf) { -@@ -69,11 +71,13 @@ static int subflow_get_info(const struct sock *sk, struct sk_buff *skb) - } - - rcu_read_unlock(); -+ unlock_sock_fast(sk, slow); - nla_nest_end(skb, start); - return 0; - - nla_failure: - rcu_read_unlock(); -+ unlock_sock_fast(sk, slow); - nla_nest_cancel(skb, start); - return err; - } -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index 980050f6b456f..70a1025f093cf 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -900,7 +900,8 @@ static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry) - } - - static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, -- struct mptcp_pm_addr_entry *entry) -+ struct mptcp_pm_addr_entry *entry, -+ bool needs_id) - { - struct mptcp_pm_addr_entry *cur, *del_entry = NULL; - unsigned int addr_max; -@@ -942,7 +943,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, - } - } - -- if (!entry->addr.id) { -+ if (!entry->addr.id && needs_id) { - find_next: - entry->addr.id = find_next_zero_bit(pernet->id_bitmap, - MPTCP_PM_MAX_ADDR_ID + 1, -@@ -953,7 +954,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, - } - } - -- if (!entry->addr.id) -+ if (!entry->addr.id && needs_id) - goto out; - - __set_bit(entry->addr.id, pernet->id_bitmap); -@@ -1095,7 +1096,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) - entry->ifindex = 0; - entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; - entry->lsk = NULL; -- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry); -+ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true); - if (ret < 0) - kfree(entry); - -@@ -1311,6 +1312,18 @@ static int mptcp_nl_add_subflow_or_signal_addr(struct net *net) - return 0; - } - -+static bool mptcp_pm_has_addr_attr_id(const struct nlattr *attr, -+ struct genl_info *info) -+{ -+ struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1]; -+ -+ if (!nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr, -+ mptcp_pm_addr_policy, info->extack) && -+ tb[MPTCP_PM_ADDR_ATTR_ID]) -+ return true; -+ return false; -+} -+ - static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) - { - struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; -@@ -1352,7 +1365,8 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) - goto out_free; - } - } -- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry); -+ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, -+ !mptcp_pm_has_addr_attr_id(attr, info)); - if (ret < 0) { - GENL_SET_ERR_MSG(info, "too many addresses or duplicate one"); - goto out_free; -diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c -index 2e1e0d0e3ec60..631fa104617c3 100644 ---- a/net/mptcp/pm_userspace.c -+++ b/net/mptcp/pm_userspace.c -@@ -25,8 +25,9 @@ void mptcp_free_local_addr_list(struct mptcp_sock *msk) - } - } - --int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, -- struct mptcp_pm_addr_entry *entry) -+static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, -+ struct mptcp_pm_addr_entry *entry, -+ bool needs_id) - { - DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); - struct mptcp_pm_addr_entry *match = NULL; -@@ -41,7 +42,7 @@ int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, - spin_lock_bh(&msk->pm.lock); - list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) { - addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true); -- if (addr_match && entry->addr.id == 0) -+ if (addr_match && entry->addr.id == 0 && needs_id) - entry->addr.id = e->addr.id; - id_match = (e->addr.id == entry->addr.id); - if (addr_match && id_match) { -@@ -64,7 +65,7 @@ int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, - } - - *e = *entry; -- if (!e->addr.id) -+ if (!e->addr.id && needs_id) - e->addr.id = find_next_zero_bit(id_bitmap, - MPTCP_PM_MAX_ADDR_ID + 1, - 1); -@@ -155,7 +156,7 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - if (new_entry.addr.port == msk_sport) - new_entry.addr.port = 0; - -- return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry); -+ return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); - } - - int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) -@@ -197,7 +198,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) - goto announce_err; - } - -- err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val); -+ err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false); - if (err < 0) { - GENL_SET_ERR_MSG(info, "did not match address and id"); - goto announce_err; -@@ -221,6 +222,40 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) - return err; - } - -+static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk, -+ struct genl_info *info) -+{ -+ struct mptcp_rm_list list = { .nr = 0 }; -+ struct mptcp_subflow_context *subflow; -+ struct sock *sk = (struct sock *)msk; -+ bool has_id_0 = false; -+ int err = -EINVAL; -+ -+ lock_sock(sk); -+ mptcp_for_each_subflow(msk, subflow) { -+ if (subflow->local_id == 0) { -+ has_id_0 = true; -+ break; -+ } -+ } -+ if (!has_id_0) { -+ GENL_SET_ERR_MSG(info, "address with id 0 not found"); -+ goto remove_err; -+ } -+ -+ list.ids[list.nr++] = 0; -+ -+ spin_lock_bh(&msk->pm.lock); -+ mptcp_pm_remove_addr(msk, &list); -+ spin_unlock_bh(&msk->pm.lock); -+ -+ err = 0; -+ -+remove_err: -+ release_sock(sk); -+ return err; -+} -+ - int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info) - { - struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN]; -@@ -252,6 +287,11 @@ int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info) - goto remove_err; - } - -+ if (id_val == 0) { -+ err = mptcp_userspace_pm_remove_id_zero_address(msk, info); -+ goto remove_err; -+ } -+ - lock_sock((struct sock *)msk); - - list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) { -@@ -335,7 +375,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info) - } - - local.addr = addr_l; -- err = mptcp_userspace_pm_append_new_local_addr(msk, &local); -+ err = mptcp_userspace_pm_append_new_local_addr(msk, &local, false); - if (err < 0) { - GENL_SET_ERR_MSG(info, "did not match address and id"); - goto create_err; -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index 259672cc344f3..b092205213234 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -834,8 +834,6 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list); - void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk, - struct list_head *rm_list); - --int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, -- struct mptcp_pm_addr_entry *entry); - void mptcp_free_local_addr_list(struct mptcp_sock *msk); - int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info); - int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info); -diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c -index c94a9971d790c..7ffd698497f2a 100644 ---- a/net/netfilter/nf_conntrack_proto_sctp.c -+++ b/net/netfilter/nf_conntrack_proto_sctp.c -@@ -299,7 +299,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb, - pr_debug("Setting vtag %x for secondary conntrack\n", - sh->vtag); - ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag; -- } else { -+ } else if (sch->type == SCTP_CID_SHUTDOWN_ACK) { - /* If it is a shutdown ack OOTB packet, we expect a return - shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ - pr_debug("Setting vtag %x for new conn OOTB\n", -diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c -index c1d99cb370b44..99195cf6b2657 100644 ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -87,12 +87,22 @@ static u32 flow_offload_dst_cookie(struct flow_offload_tuple *flow_tuple) - return 0; - } - -+static struct dst_entry *nft_route_dst_fetch(struct nf_flow_route *route, -+ enum flow_offload_tuple_dir dir) -+{ -+ struct dst_entry *dst = route->tuple[dir].dst; -+ -+ route->tuple[dir].dst = NULL; -+ -+ return dst; -+} -+ - static int flow_offload_fill_route(struct flow_offload *flow, -- const struct nf_flow_route *route, -+ struct nf_flow_route *route, - enum flow_offload_tuple_dir dir) - { - struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; -- struct dst_entry *dst = route->tuple[dir].dst; -+ struct dst_entry *dst = nft_route_dst_fetch(route, dir); - int i, j = 0; - - switch (flow_tuple->l3proto) { -@@ -122,12 +132,10 @@ static int flow_offload_fill_route(struct flow_offload *flow, - ETH_ALEN); - flow_tuple->out.ifidx = route->tuple[dir].out.ifindex; - flow_tuple->out.hw_ifidx = route->tuple[dir].out.hw_ifindex; -+ dst_release(dst); - break; - case FLOW_OFFLOAD_XMIT_XFRM: - case FLOW_OFFLOAD_XMIT_NEIGH: -- if (!dst_hold_safe(route->tuple[dir].dst)) -- return -1; -- - flow_tuple->dst_cache = dst; - flow_tuple->dst_cookie = flow_offload_dst_cookie(flow_tuple); - break; -@@ -148,27 +156,12 @@ static void nft_flow_dst_release(struct flow_offload *flow, - dst_release(flow->tuplehash[dir].tuple.dst_cache); - } - --int flow_offload_route_init(struct flow_offload *flow, -- const struct nf_flow_route *route) -+void flow_offload_route_init(struct flow_offload *flow, -+ struct nf_flow_route *route) - { -- int err; -- -- err = flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL); -- if (err < 0) -- return err; -- -- err = flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY); -- if (err < 0) -- goto err_route_reply; -- -+ flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL); -+ flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY); - flow->type = NF_FLOW_OFFLOAD_ROUTE; -- -- return 0; -- --err_route_reply: -- nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL); -- -- return err; - } - EXPORT_SYMBOL_GPL(flow_offload_route_init); - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 49acb89ba9c56..e21ec3ad80939 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -686,15 +686,16 @@ static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj) - return err; - } - --static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, -- struct nft_flowtable *flowtable) -+static struct nft_trans * -+nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, -+ struct nft_flowtable *flowtable) - { - struct nft_trans *trans; - - trans = nft_trans_alloc(ctx, msg_type, - sizeof(struct nft_trans_flowtable)); - if (trans == NULL) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - - if (msg_type == NFT_MSG_NEWFLOWTABLE) - nft_activate_next(ctx->net, flowtable); -@@ -703,22 +704,22 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, - nft_trans_flowtable(trans) = flowtable; - nft_trans_commit_list_add_tail(ctx->net, trans); - -- return 0; -+ return trans; - } - - static int nft_delflowtable(struct nft_ctx *ctx, - struct nft_flowtable *flowtable) - { -- int err; -+ struct nft_trans *trans; - -- err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); -- if (err < 0) -- return err; -+ trans = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); -+ if (IS_ERR(trans)) -+ return PTR_ERR(trans); - - nft_deactivate_next(ctx->net, flowtable); - nft_use_dec(&ctx->table->use); - -- return err; -+ return 0; - } - - static void __nft_reg_track_clobber(struct nft_regs_track *track, u8 dreg) -@@ -1245,6 +1246,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx) - return 0; - - err_register_hooks: -+ ctx->table->flags |= NFT_TABLE_F_DORMANT; - nft_trans_destroy(trans); - return ret; - } -@@ -2057,7 +2059,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, - struct nft_hook *hook; - int err; - -- hook = kmalloc(sizeof(struct nft_hook), GFP_KERNEL_ACCOUNT); -+ hook = kzalloc(sizeof(struct nft_hook), GFP_KERNEL_ACCOUNT); - if (!hook) { - err = -ENOMEM; - goto err_hook_alloc; -@@ -2458,19 +2460,15 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - RCU_INIT_POINTER(chain->blob_gen_0, blob); - RCU_INIT_POINTER(chain->blob_gen_1, blob); - -- err = nf_tables_register_hook(net, table, chain); -- if (err < 0) -- goto err_destroy_chain; -- - if (!nft_use_inc(&table->use)) { - err = -EMFILE; -- goto err_use; -+ goto err_destroy_chain; - } - - trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN); - if (IS_ERR(trans)) { - err = PTR_ERR(trans); -- goto err_unregister_hook; -+ goto err_trans; - } - - nft_trans_chain_policy(trans) = NFT_CHAIN_POLICY_UNSET; -@@ -2478,17 +2476,22 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - nft_trans_chain_policy(trans) = policy; - - err = nft_chain_add(table, chain); -- if (err < 0) { -- nft_trans_destroy(trans); -- goto err_unregister_hook; -- } -+ if (err < 0) -+ goto err_chain_add; -+ -+ /* This must be LAST to ensure no packets are walking over this chain. */ -+ err = nf_tables_register_hook(net, table, chain); -+ if (err < 0) -+ goto err_register_hook; - - return 0; - --err_unregister_hook: -+err_register_hook: -+ nft_chain_del(chain); -+err_chain_add: -+ nft_trans_destroy(trans); -+err_trans: - nft_use_dec_restore(&table->use); --err_use: -- nf_tables_unregister_hook(net, table, chain); - err_destroy_chain: - nf_tables_chain_destroy(ctx); - -@@ -7937,7 +7940,7 @@ static int nft_register_flowtable_net_hooks(struct net *net, - return err; - } - --static void nft_flowtable_hooks_destroy(struct list_head *hook_list) -+static void nft_hooks_destroy(struct list_head *hook_list) - { - struct nft_hook *hook, *next; - -@@ -8030,9 +8033,9 @@ static int nf_tables_newflowtable(struct sk_buff *skb, - u8 family = info->nfmsg->nfgen_family; - const struct nf_flowtable_type *type; - struct nft_flowtable *flowtable; -- struct nft_hook *hook, *next; - struct net *net = info->net; - struct nft_table *table; -+ struct nft_trans *trans; - struct nft_ctx ctx; - int err; - -@@ -8112,34 +8115,34 @@ static int nf_tables_newflowtable(struct sk_buff *skb, - err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], - &flowtable_hook, flowtable, true); - if (err < 0) -- goto err4; -+ goto err_flowtable_parse_hooks; - - list_splice(&flowtable_hook.list, &flowtable->hook_list); - flowtable->data.priority = flowtable_hook.priority; - flowtable->hooknum = flowtable_hook.num; - -+ trans = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); -+ if (IS_ERR(trans)) { -+ err = PTR_ERR(trans); -+ goto err_flowtable_trans; -+ } -+ -+ /* This must be LAST to ensure no packets are walking over this flowtable. */ - err = nft_register_flowtable_net_hooks(ctx.net, table, - &flowtable->hook_list, - flowtable); -- if (err < 0) { -- nft_flowtable_hooks_destroy(&flowtable->hook_list); -- goto err4; -- } -- -- err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); - if (err < 0) -- goto err5; -+ goto err_flowtable_hooks; - - list_add_tail_rcu(&flowtable->list, &table->flowtables); - - return 0; --err5: -- list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { -- nft_unregister_flowtable_hook(net, flowtable, hook); -- list_del_rcu(&hook->list); -- kfree_rcu(hook, rcu); -- } --err4: -+ -+err_flowtable_hooks: -+ nft_trans_destroy(trans); -+err_flowtable_trans: -+ nft_hooks_destroy(&flowtable->hook_list); -+err_flowtable_parse_hooks: - flowtable->data.type->free(&flowtable->data); - err3: - module_put(type->owner); -@@ -8892,7 +8895,7 @@ static void nft_commit_release(struct nft_trans *trans) - break; - case NFT_MSG_DELFLOWTABLE: - if (nft_trans_flowtable_update(trans)) -- nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans)); -+ nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); - else - nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); - break; -@@ -9849,7 +9852,7 @@ static void nf_tables_abort_release(struct nft_trans *trans) - break; - case NFT_MSG_NEWFLOWTABLE: - if (nft_trans_flowtable_update(trans)) -- nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans)); -+ nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); - else - nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); - break; -diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c -index 3d9f6dda5aeb2..7a8707632a815 100644 ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -250,9 +250,14 @@ static int nft_flow_route(const struct nft_pktinfo *pkt, - break; - } - -+ if (!dst_hold_safe(this_dst)) -+ return -ENOENT; -+ - nf_route(nft_net(pkt), &other_dst, &fl, false, nft_pf(pkt)); -- if (!other_dst) -+ if (!other_dst) { -+ dst_release(this_dst); - return -ENOENT; -+ } - - nft_default_forward_path(route, this_dst, dir); - nft_default_forward_path(route, other_dst, !dir); -@@ -349,8 +354,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, - if (!flow) - goto err_flow_alloc; - -- if (flow_offload_route_init(flow, &route) < 0) -- goto err_flow_add; -+ flow_offload_route_init(flow, &route); - - if (tcph) { - ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -@@ -361,12 +365,12 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, - if (ret < 0) - goto err_flow_add; - -- dst_release(route.tuple[!dir].dst); - return; - - err_flow_add: - flow_offload_free(flow); - err_flow_alloc: -+ dst_release(route.tuple[dir].dst); - dst_release(route.tuple[!dir].dst); - err_flow_route: - clear_bit(IPS_OFFLOAD_BIT, &ct->status); -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 51882f07ef70c..c3117350f5fbb 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -3284,7 +3284,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, - int addr_len) - { - struct sock *sk = sock->sk; -- char name[sizeof(uaddr->sa_data) + 1]; -+ char name[sizeof(uaddr->sa_data_min) + 1]; - - /* - * Check legality -@@ -3295,8 +3295,8 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, - /* uaddr->sa_data comes from the userspace, it's not guaranteed to be - * zero-terminated. - */ -- memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); -- name[sizeof(uaddr->sa_data)] = 0; -+ memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data_min)); -+ name[sizeof(uaddr->sa_data_min)] = 0; - - return packet_do_bind(sk, name, 0, 0); - } -@@ -3566,11 +3566,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, - return -EOPNOTSUPP; - - uaddr->sa_family = AF_PACKET; -- memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); -+ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data_min)); - rcu_read_lock(); - dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex)); - if (dev) -- strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); -+ strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data_min)); - rcu_read_unlock(); - - return sizeof(*uaddr); -diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c -index ff5f49ab236ed..39a6c5713d0b2 100644 ---- a/net/phonet/datagram.c -+++ b/net/phonet/datagram.c -@@ -35,10 +35,10 @@ static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg) - - switch (cmd) { - case SIOCINQ: -- lock_sock(sk); -+ spin_lock_bh(&sk->sk_receive_queue.lock); - skb = skb_peek(&sk->sk_receive_queue); - answ = skb ? skb->len : 0; -- release_sock(sk); -+ spin_unlock_bh(&sk->sk_receive_queue.lock); - return put_user(answ, (int __user *)arg); - - case SIOCPNADDRESOURCE: -diff --git a/net/phonet/pep.c b/net/phonet/pep.c -index 83ea13a50690b..607f54c23647a 100644 ---- a/net/phonet/pep.c -+++ b/net/phonet/pep.c -@@ -917,6 +917,37 @@ static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len) - return 0; - } - -+static unsigned int pep_first_packet_length(struct sock *sk) -+{ -+ struct pep_sock *pn = pep_sk(sk); -+ struct sk_buff_head *q; -+ struct sk_buff *skb; -+ unsigned int len = 0; -+ bool found = false; -+ -+ if (sock_flag(sk, SOCK_URGINLINE)) { -+ q = &pn->ctrlreq_queue; -+ spin_lock_bh(&q->lock); -+ skb = skb_peek(q); -+ if (skb) { -+ len = skb->len; -+ found = true; -+ } -+ spin_unlock_bh(&q->lock); -+ } -+ -+ if (likely(!found)) { -+ q = &sk->sk_receive_queue; -+ spin_lock_bh(&q->lock); -+ skb = skb_peek(q); -+ if (skb) -+ len = skb->len; -+ spin_unlock_bh(&q->lock); -+ } -+ -+ return len; -+} -+ - static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) - { - struct pep_sock *pn = pep_sk(sk); -@@ -930,15 +961,7 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) - break; - } - -- lock_sock(sk); -- if (sock_flag(sk, SOCK_URGINLINE) && -- !skb_queue_empty(&pn->ctrlreq_queue)) -- answ = skb_peek(&pn->ctrlreq_queue)->len; -- else if (!skb_queue_empty(&sk->sk_receive_queue)) -- answ = skb_peek(&sk->sk_receive_queue)->len; -- else -- answ = 0; -- release_sock(sk); -+ answ = pep_first_packet_length(sk); - ret = put_user(answ, (int __user *)arg); - break; - -diff --git a/net/sched/Kconfig b/net/sched/Kconfig -index 24cf0bf7c80e5..9c4a80fce794f 100644 ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -45,23 +45,6 @@ if NET_SCHED - - comment "Queueing/Scheduling" - --config NET_SCH_CBQ -- tristate "Class Based Queueing (CBQ)" -- help -- Say Y here if you want to use the Class-Based Queueing (CBQ) packet -- scheduling algorithm. This algorithm classifies the waiting packets -- into a tree-like hierarchy of classes; the leaves of this tree are -- in turn scheduled by separate algorithms. -- -- See the top of for more details. -- -- CBQ is a commonly used scheduler, so if you're unsure, you should -- say Y here. Then say Y to all the queueing algorithms below that you -- want to use as leaf disciplines. -- -- To compile this code as a module, choose M here: the -- module will be called sch_cbq. -- - config NET_SCH_HTB - tristate "Hierarchical Token Bucket (HTB)" - help -@@ -85,20 +68,6 @@ config NET_SCH_HFSC - To compile this code as a module, choose M here: the - module will be called sch_hfsc. - --config NET_SCH_ATM -- tristate "ATM Virtual Circuits (ATM)" -- depends on ATM -- help -- Say Y here if you want to use the ATM pseudo-scheduler. This -- provides a framework for invoking classifiers, which in turn -- select classes of this queuing discipline. Each class maps -- the flow(s) it is handling to a given virtual circuit. -- -- See the top of for more details. -- -- To compile this code as a module, choose M here: the -- module will be called sch_atm. -- - config NET_SCH_PRIO - tristate "Multi Band Priority Queueing (PRIO)" - help -@@ -217,17 +186,6 @@ config NET_SCH_GRED - To compile this code as a module, choose M here: the - module will be called sch_gred. - --config NET_SCH_DSMARK -- tristate "Differentiated Services marker (DSMARK)" -- help -- Say Y if you want to schedule packets according to the -- Differentiated Services architecture proposed in RFC 2475. -- Technical information on this method, with pointers to associated -- RFCs, is available at . -- -- To compile this code as a module, choose M here: the -- module will be called sch_dsmark. -- - config NET_SCH_NETEM - tristate "Network emulator (NETEM)" - help -diff --git a/net/sched/Makefile b/net/sched/Makefile -index 8a33a35fc50d5..a66ac1e7b79b5 100644 ---- a/net/sched/Makefile -+++ b/net/sched/Makefile -@@ -33,20 +33,17 @@ obj-$(CONFIG_NET_ACT_TUNNEL_KEY)+= act_tunnel_key.o - obj-$(CONFIG_NET_ACT_CT) += act_ct.o - obj-$(CONFIG_NET_ACT_GATE) += act_gate.o - obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o --obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o - obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o - obj-$(CONFIG_NET_SCH_HFSC) += sch_hfsc.o - obj-$(CONFIG_NET_SCH_RED) += sch_red.o - obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o - obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o --obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o - obj-$(CONFIG_NET_SCH_SFB) += sch_sfb.o - obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o - obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o - obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o - obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o - obj-$(CONFIG_NET_SCH_MULTIQ) += sch_multiq.o --obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o - obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o - obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o - obj-$(CONFIG_NET_SCH_PLUG) += sch_plug.o -diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c -deleted file mode 100644 -index 4a981ca90b0bf..0000000000000 ---- a/net/sched/sch_atm.c -+++ /dev/null -@@ -1,706 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* net/sched/sch_atm.c - ATM VC selection "queueing discipline" */ -- --/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include /* for fput */ --#include --#include --#include -- --/* -- * The ATM queuing discipline provides a framework for invoking classifiers -- * (aka "filters"), which in turn select classes of this queuing discipline. -- * Each class maps the flow(s) it is handling to a given VC. Multiple classes -- * may share the same VC. -- * -- * When creating a class, VCs are specified by passing the number of the open -- * socket descriptor by which the calling process references the VC. The kernel -- * keeps the VC open at least until all classes using it are removed. -- * -- * In this file, most functions are named atm_tc_* to avoid confusion with all -- * the atm_* in net/atm. This naming convention differs from what's used in the -- * rest of net/sched. -- * -- * Known bugs: -- * - sometimes messes up the IP stack -- * - any manipulations besides the few operations described in the README, are -- * untested and likely to crash the system -- * - should lock the flow while there is data in the queue (?) -- */ -- --#define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back)) -- --struct atm_flow_data { -- struct Qdisc_class_common common; -- struct Qdisc *q; /* FIFO, TBF, etc. */ -- struct tcf_proto __rcu *filter_list; -- struct tcf_block *block; -- struct atm_vcc *vcc; /* VCC; NULL if VCC is closed */ -- void (*old_pop)(struct atm_vcc *vcc, -- struct sk_buff *skb); /* chaining */ -- struct atm_qdisc_data *parent; /* parent qdisc */ -- struct socket *sock; /* for closing */ -- int ref; /* reference count */ -- struct gnet_stats_basic_sync bstats; -- struct gnet_stats_queue qstats; -- struct list_head list; -- struct atm_flow_data *excess; /* flow for excess traffic; -- NULL to set CLP instead */ -- int hdr_len; -- unsigned char hdr[]; /* header data; MUST BE LAST */ --}; -- --struct atm_qdisc_data { -- struct atm_flow_data link; /* unclassified skbs go here */ -- struct list_head flows; /* NB: "link" is also on this -- list */ -- struct tasklet_struct task; /* dequeue tasklet */ --}; -- --/* ------------------------- Class/flow operations ------------------------- */ -- --static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow; -- -- list_for_each_entry(flow, &p->flows, list) { -- if (flow->common.classid == classid) -- return flow; -- } -- return NULL; --} -- --static int atm_tc_graft(struct Qdisc *sch, unsigned long arg, -- struct Qdisc *new, struct Qdisc **old, -- struct netlink_ext_ack *extack) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)arg; -- -- pr_debug("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n", -- sch, p, flow, new, old); -- if (list_empty(&flow->list)) -- return -EINVAL; -- if (!new) -- new = &noop_qdisc; -- *old = flow->q; -- flow->q = new; -- if (*old) -- qdisc_reset(*old); -- return 0; --} -- --static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl) --{ -- struct atm_flow_data *flow = (struct atm_flow_data *)cl; -- -- pr_debug("atm_tc_leaf(sch %p,flow %p)\n", sch, flow); -- return flow ? flow->q : NULL; --} -- --static unsigned long atm_tc_find(struct Qdisc *sch, u32 classid) --{ -- struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch); -- struct atm_flow_data *flow; -- -- pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid); -- flow = lookup_flow(sch, classid); -- pr_debug("%s: flow %p\n", __func__, flow); -- return (unsigned long)flow; --} -- --static unsigned long atm_tc_bind_filter(struct Qdisc *sch, -- unsigned long parent, u32 classid) --{ -- struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch); -- struct atm_flow_data *flow; -- -- pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid); -- flow = lookup_flow(sch, classid); -- if (flow) -- flow->ref++; -- pr_debug("%s: flow %p\n", __func__, flow); -- return (unsigned long)flow; --} -- --/* -- * atm_tc_put handles all destructions, including the ones that are explicitly -- * requested (atm_tc_destroy, etc.). The assumption here is that we never drop -- * anything that still seems to be in use. -- */ --static void atm_tc_put(struct Qdisc *sch, unsigned long cl) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)cl; -- -- pr_debug("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow); -- if (--flow->ref) -- return; -- pr_debug("atm_tc_put: destroying\n"); -- list_del_init(&flow->list); -- pr_debug("atm_tc_put: qdisc %p\n", flow->q); -- qdisc_put(flow->q); -- tcf_block_put(flow->block); -- if (flow->sock) { -- pr_debug("atm_tc_put: f_count %ld\n", -- file_count(flow->sock->file)); -- flow->vcc->pop = flow->old_pop; -- sockfd_put(flow->sock); -- } -- if (flow->excess) -- atm_tc_put(sch, (unsigned long)flow->excess); -- if (flow != &p->link) -- kfree(flow); -- /* -- * If flow == &p->link, the qdisc no longer works at this point and -- * needs to be removed. (By the caller of atm_tc_put.) -- */ --} -- --static void sch_atm_pop(struct atm_vcc *vcc, struct sk_buff *skb) --{ -- struct atm_qdisc_data *p = VCC2FLOW(vcc)->parent; -- -- pr_debug("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n", vcc, skb, p); -- VCC2FLOW(vcc)->old_pop(vcc, skb); -- tasklet_schedule(&p->task); --} -- --static const u8 llc_oui_ip[] = { -- 0xaa, /* DSAP: non-ISO */ -- 0xaa, /* SSAP: non-ISO */ -- 0x03, /* Ctrl: Unnumbered Information Command PDU */ -- 0x00, /* OUI: EtherType */ -- 0x00, 0x00, -- 0x08, 0x00 --}; /* Ethertype IP (0800) */ -- --static const struct nla_policy atm_policy[TCA_ATM_MAX + 1] = { -- [TCA_ATM_FD] = { .type = NLA_U32 }, -- [TCA_ATM_EXCESS] = { .type = NLA_U32 }, --}; -- --static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, -- struct nlattr **tca, unsigned long *arg, -- struct netlink_ext_ack *extack) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)*arg; -- struct atm_flow_data *excess = NULL; -- struct nlattr *opt = tca[TCA_OPTIONS]; -- struct nlattr *tb[TCA_ATM_MAX + 1]; -- struct socket *sock; -- int fd, error, hdr_len; -- void *hdr; -- -- pr_debug("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x," -- "flow %p,opt %p)\n", sch, p, classid, parent, flow, opt); -- /* -- * The concept of parents doesn't apply for this qdisc. -- */ -- if (parent && parent != TC_H_ROOT && parent != sch->handle) -- return -EINVAL; -- /* -- * ATM classes cannot be changed. In order to change properties of the -- * ATM connection, that socket needs to be modified directly (via the -- * native ATM API. In order to send a flow to a different VC, the old -- * class needs to be removed and a new one added. (This may be changed -- * later.) -- */ -- if (flow) -- return -EBUSY; -- if (opt == NULL) -- return -EINVAL; -- -- error = nla_parse_nested_deprecated(tb, TCA_ATM_MAX, opt, atm_policy, -- NULL); -- if (error < 0) -- return error; -- -- if (!tb[TCA_ATM_FD]) -- return -EINVAL; -- fd = nla_get_u32(tb[TCA_ATM_FD]); -- pr_debug("atm_tc_change: fd %d\n", fd); -- if (tb[TCA_ATM_HDR]) { -- hdr_len = nla_len(tb[TCA_ATM_HDR]); -- hdr = nla_data(tb[TCA_ATM_HDR]); -- } else { -- hdr_len = RFC1483LLC_LEN; -- hdr = NULL; /* default LLC/SNAP for IP */ -- } -- if (!tb[TCA_ATM_EXCESS]) -- excess = NULL; -- else { -- excess = (struct atm_flow_data *) -- atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); -- if (!excess) -- return -ENOENT; -- } -- pr_debug("atm_tc_change: type %d, payload %d, hdr_len %d\n", -- opt->nla_type, nla_len(opt), hdr_len); -- sock = sockfd_lookup(fd, &error); -- if (!sock) -- return error; /* f_count++ */ -- pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file)); -- if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) { -- error = -EPROTOTYPE; -- goto err_out; -- } -- /* @@@ should check if the socket is really operational or we'll crash -- on vcc->send */ -- if (classid) { -- if (TC_H_MAJ(classid ^ sch->handle)) { -- pr_debug("atm_tc_change: classid mismatch\n"); -- error = -EINVAL; -- goto err_out; -- } -- } else { -- int i; -- unsigned long cl; -- -- for (i = 1; i < 0x8000; i++) { -- classid = TC_H_MAKE(sch->handle, 0x8000 | i); -- cl = atm_tc_find(sch, classid); -- if (!cl) -- break; -- } -- } -- pr_debug("atm_tc_change: new id %x\n", classid); -- flow = kzalloc(sizeof(struct atm_flow_data) + hdr_len, GFP_KERNEL); -- pr_debug("atm_tc_change: flow %p\n", flow); -- if (!flow) { -- error = -ENOBUFS; -- goto err_out; -- } -- -- error = tcf_block_get(&flow->block, &flow->filter_list, sch, -- extack); -- if (error) { -- kfree(flow); -- goto err_out; -- } -- -- flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid, -- extack); -- if (!flow->q) -- flow->q = &noop_qdisc; -- pr_debug("atm_tc_change: qdisc %p\n", flow->q); -- flow->sock = sock; -- flow->vcc = ATM_SD(sock); /* speedup */ -- flow->vcc->user_back = flow; -- pr_debug("atm_tc_change: vcc %p\n", flow->vcc); -- flow->old_pop = flow->vcc->pop; -- flow->parent = p; -- flow->vcc->pop = sch_atm_pop; -- flow->common.classid = classid; -- flow->ref = 1; -- flow->excess = excess; -- list_add(&flow->list, &p->link.list); -- flow->hdr_len = hdr_len; -- if (hdr) -- memcpy(flow->hdr, hdr, hdr_len); -- else -- memcpy(flow->hdr, llc_oui_ip, sizeof(llc_oui_ip)); -- *arg = (unsigned long)flow; -- return 0; --err_out: -- sockfd_put(sock); -- return error; --} -- --static int atm_tc_delete(struct Qdisc *sch, unsigned long arg, -- struct netlink_ext_ack *extack) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)arg; -- -- pr_debug("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow); -- if (list_empty(&flow->list)) -- return -EINVAL; -- if (rcu_access_pointer(flow->filter_list) || flow == &p->link) -- return -EBUSY; -- /* -- * Reference count must be 2: one for "keepalive" (set at class -- * creation), and one for the reference held when calling delete. -- */ -- if (flow->ref < 2) { -- pr_err("atm_tc_delete: flow->ref == %d\n", flow->ref); -- return -EINVAL; -- } -- if (flow->ref > 2) -- return -EBUSY; /* catch references via excess, etc. */ -- atm_tc_put(sch, arg); -- return 0; --} -- --static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow; -- -- pr_debug("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker); -- if (walker->stop) -- return; -- list_for_each_entry(flow, &p->flows, list) { -- if (!tc_qdisc_stats_dump(sch, (unsigned long)flow, walker)) -- break; -- } --} -- --static struct tcf_block *atm_tc_tcf_block(struct Qdisc *sch, unsigned long cl, -- struct netlink_ext_ack *extack) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)cl; -- -- pr_debug("atm_tc_find_tcf(sch %p,[qdisc %p],flow %p)\n", sch, p, flow); -- return flow ? flow->block : p->link.block; --} -- --/* --------------------------- Qdisc operations ---------------------------- */ -- --static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch, -- struct sk_buff **to_free) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow; -- struct tcf_result res; -- int result; -- int ret = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; -- -- pr_debug("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); -- result = TC_ACT_OK; /* be nice to gcc */ -- flow = NULL; -- if (TC_H_MAJ(skb->priority) != sch->handle || -- !(flow = (struct atm_flow_data *)atm_tc_find(sch, skb->priority))) { -- struct tcf_proto *fl; -- -- list_for_each_entry(flow, &p->flows, list) { -- fl = rcu_dereference_bh(flow->filter_list); -- if (fl) { -- result = tcf_classify(skb, NULL, fl, &res, true); -- if (result < 0) -- continue; -- if (result == TC_ACT_SHOT) -- goto done; -- -- flow = (struct atm_flow_data *)res.class; -- if (!flow) -- flow = lookup_flow(sch, res.classid); -- goto drop; -- } -- } -- flow = NULL; --done: -- ; -- } -- if (!flow) { -- flow = &p->link; -- } else { -- if (flow->vcc) -- ATM_SKB(skb)->atm_options = flow->vcc->atm_options; -- /*@@@ looks good ... but it's not supposed to work :-) */ --#ifdef CONFIG_NET_CLS_ACT -- switch (result) { -- case TC_ACT_QUEUED: -- case TC_ACT_STOLEN: -- case TC_ACT_TRAP: -- __qdisc_drop(skb, to_free); -- return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; -- case TC_ACT_SHOT: -- __qdisc_drop(skb, to_free); -- goto drop; -- case TC_ACT_RECLASSIFY: -- if (flow->excess) -- flow = flow->excess; -- else -- ATM_SKB(skb)->atm_options |= ATM_ATMOPT_CLP; -- break; -- } --#endif -- } -- -- ret = qdisc_enqueue(skb, flow->q, to_free); -- if (ret != NET_XMIT_SUCCESS) { --drop: __maybe_unused -- if (net_xmit_drop_count(ret)) { -- qdisc_qstats_drop(sch); -- if (flow) -- flow->qstats.drops++; -- } -- return ret; -- } -- /* -- * Okay, this may seem weird. We pretend we've dropped the packet if -- * it goes via ATM. The reason for this is that the outer qdisc -- * expects to be able to q->dequeue the packet later on if we return -- * success at this place. Also, sch->q.qdisc needs to reflect whether -- * there is a packet egligible for dequeuing or not. Note that the -- * statistics of the outer qdisc are necessarily wrong because of all -- * this. There's currently no correct solution for this. -- */ -- if (flow == &p->link) { -- sch->q.qlen++; -- return NET_XMIT_SUCCESS; -- } -- tasklet_schedule(&p->task); -- return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; --} -- --/* -- * Dequeue packets and send them over ATM. Note that we quite deliberately -- * avoid checking net_device's flow control here, simply because sch_atm -- * uses its own channels, which have nothing to do with any CLIP/LANE/or -- * non-ATM interfaces. -- */ -- --static void sch_atm_dequeue(struct tasklet_struct *t) --{ -- struct atm_qdisc_data *p = from_tasklet(p, t, task); -- struct Qdisc *sch = qdisc_from_priv(p); -- struct atm_flow_data *flow; -- struct sk_buff *skb; -- -- pr_debug("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p); -- list_for_each_entry(flow, &p->flows, list) { -- if (flow == &p->link) -- continue; -- /* -- * If traffic is properly shaped, this won't generate nasty -- * little bursts. Otherwise, it may ... (but that's okay) -- */ -- while ((skb = flow->q->ops->peek(flow->q))) { -- if (!atm_may_send(flow->vcc, skb->truesize)) -- break; -- -- skb = qdisc_dequeue_peeked(flow->q); -- if (unlikely(!skb)) -- break; -- -- qdisc_bstats_update(sch, skb); -- bstats_update(&flow->bstats, skb); -- pr_debug("atm_tc_dequeue: sending on class %p\n", flow); -- /* remove any LL header somebody else has attached */ -- skb_pull(skb, skb_network_offset(skb)); -- if (skb_headroom(skb) < flow->hdr_len) { -- struct sk_buff *new; -- -- new = skb_realloc_headroom(skb, flow->hdr_len); -- dev_kfree_skb(skb); -- if (!new) -- continue; -- skb = new; -- } -- pr_debug("sch_atm_dequeue: ip %p, data %p\n", -- skb_network_header(skb), skb->data); -- ATM_SKB(skb)->vcc = flow->vcc; -- memcpy(skb_push(skb, flow->hdr_len), flow->hdr, -- flow->hdr_len); -- refcount_add(skb->truesize, -- &sk_atm(flow->vcc)->sk_wmem_alloc); -- /* atm.atm_options are already set by atm_tc_enqueue */ -- flow->vcc->send(flow->vcc, skb); -- } -- } --} -- --static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct sk_buff *skb; -- -- pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p); -- tasklet_schedule(&p->task); -- skb = qdisc_dequeue_peeked(p->link.q); -- if (skb) -- sch->q.qlen--; -- return skb; --} -- --static struct sk_buff *atm_tc_peek(struct Qdisc *sch) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- -- pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p); -- -- return p->link.q->ops->peek(p->link.q); --} -- --static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt, -- struct netlink_ext_ack *extack) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- int err; -- -- pr_debug("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt); -- INIT_LIST_HEAD(&p->flows); -- INIT_LIST_HEAD(&p->link.list); -- gnet_stats_basic_sync_init(&p->link.bstats); -- list_add(&p->link.list, &p->flows); -- p->link.q = qdisc_create_dflt(sch->dev_queue, -- &pfifo_qdisc_ops, sch->handle, extack); -- if (!p->link.q) -- p->link.q = &noop_qdisc; -- pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q); -- p->link.vcc = NULL; -- p->link.sock = NULL; -- p->link.common.classid = sch->handle; -- p->link.ref = 1; -- -- err = tcf_block_get(&p->link.block, &p->link.filter_list, sch, -- extack); -- if (err) -- return err; -- -- tasklet_setup(&p->task, sch_atm_dequeue); -- return 0; --} -- --static void atm_tc_reset(struct Qdisc *sch) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow; -- -- pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p); -- list_for_each_entry(flow, &p->flows, list) -- qdisc_reset(flow->q); --} -- --static void atm_tc_destroy(struct Qdisc *sch) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow, *tmp; -- -- pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); -- list_for_each_entry(flow, &p->flows, list) { -- tcf_block_put(flow->block); -- flow->block = NULL; -- } -- -- list_for_each_entry_safe(flow, tmp, &p->flows, list) { -- if (flow->ref > 1) -- pr_err("atm_destroy: %p->ref = %d\n", flow, flow->ref); -- atm_tc_put(sch, (unsigned long)flow); -- } -- tasklet_kill(&p->task); --} -- --static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl, -- struct sk_buff *skb, struct tcmsg *tcm) --{ -- struct atm_qdisc_data *p = qdisc_priv(sch); -- struct atm_flow_data *flow = (struct atm_flow_data *)cl; -- struct nlattr *nest; -- -- pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n", -- sch, p, flow, skb, tcm); -- if (list_empty(&flow->list)) -- return -EINVAL; -- tcm->tcm_handle = flow->common.classid; -- tcm->tcm_info = flow->q->handle; -- -- nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (nest == NULL) -- goto nla_put_failure; -- -- if (nla_put(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr)) -- goto nla_put_failure; -- if (flow->vcc) { -- struct sockaddr_atmpvc pvc; -- int state; -- -- memset(&pvc, 0, sizeof(pvc)); -- pvc.sap_family = AF_ATMPVC; -- pvc.sap_addr.itf = flow->vcc->dev ? flow->vcc->dev->number : -1; -- pvc.sap_addr.vpi = flow->vcc->vpi; -- pvc.sap_addr.vci = flow->vcc->vci; -- if (nla_put(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc)) -- goto nla_put_failure; -- state = ATM_VF2VS(flow->vcc->flags); -- if (nla_put_u32(skb, TCA_ATM_STATE, state)) -- goto nla_put_failure; -- } -- if (flow->excess) { -- if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->common.classid)) -- goto nla_put_failure; -- } else { -- if (nla_put_u32(skb, TCA_ATM_EXCESS, 0)) -- goto nla_put_failure; -- } -- return nla_nest_end(skb, nest); -- --nla_put_failure: -- nla_nest_cancel(skb, nest); -- return -1; --} --static int --atm_tc_dump_class_stats(struct Qdisc *sch, unsigned long arg, -- struct gnet_dump *d) --{ -- struct atm_flow_data *flow = (struct atm_flow_data *)arg; -- -- if (gnet_stats_copy_basic(d, NULL, &flow->bstats, true) < 0 || -- gnet_stats_copy_queue(d, NULL, &flow->qstats, flow->q->q.qlen) < 0) -- return -1; -- -- return 0; --} -- --static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb) --{ -- return 0; --} -- --static const struct Qdisc_class_ops atm_class_ops = { -- .graft = atm_tc_graft, -- .leaf = atm_tc_leaf, -- .find = atm_tc_find, -- .change = atm_tc_change, -- .delete = atm_tc_delete, -- .walk = atm_tc_walk, -- .tcf_block = atm_tc_tcf_block, -- .bind_tcf = atm_tc_bind_filter, -- .unbind_tcf = atm_tc_put, -- .dump = atm_tc_dump_class, -- .dump_stats = atm_tc_dump_class_stats, --}; -- --static struct Qdisc_ops atm_qdisc_ops __read_mostly = { -- .cl_ops = &atm_class_ops, -- .id = "atm", -- .priv_size = sizeof(struct atm_qdisc_data), -- .enqueue = atm_tc_enqueue, -- .dequeue = atm_tc_dequeue, -- .peek = atm_tc_peek, -- .init = atm_tc_init, -- .reset = atm_tc_reset, -- .destroy = atm_tc_destroy, -- .dump = atm_tc_dump, -- .owner = THIS_MODULE, --}; -- --static int __init atm_init(void) --{ -- return register_qdisc(&atm_qdisc_ops); --} -- --static void __exit atm_exit(void) --{ -- unregister_qdisc(&atm_qdisc_ops); --} -- --module_init(atm_init) --module_exit(atm_exit) --MODULE_LICENSE("GPL"); -diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c -deleted file mode 100644 -index 36db5f6782f2c..0000000000000 ---- a/net/sched/sch_cbq.c -+++ /dev/null -@@ -1,1727 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * net/sched/sch_cbq.c Class-Based Queueing discipline. -- * -- * Authors: Alexey Kuznetsov, -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- -- --/* Class-Based Queueing (CBQ) algorithm. -- ======================================= -- -- Sources: [1] Sally Floyd and Van Jacobson, "Link-sharing and Resource -- Management Models for Packet Networks", -- IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995 -- -- [2] Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995 -- -- [3] Sally Floyd, "Notes on Class-Based Queueing: Setting -- Parameters", 1996 -- -- [4] Sally Floyd and Michael Speer, "Experimental Results -- for Class-Based Queueing", 1998, not published. -- -- ----------------------------------------------------------------------- -- -- Algorithm skeleton was taken from NS simulator cbq.cc. -- If someone wants to check this code against the LBL version, -- he should take into account that ONLY the skeleton was borrowed, -- the implementation is different. Particularly: -- -- --- The WRR algorithm is different. Our version looks more -- reasonable (I hope) and works when quanta are allowed to be -- less than MTU, which is always the case when real time classes -- have small rates. Note, that the statement of [3] is -- incomplete, delay may actually be estimated even if class -- per-round allotment is less than MTU. Namely, if per-round -- allotment is W*r_i, and r_1+...+r_k = r < 1 -- -- delay_i <= ([MTU/(W*r_i)]*W*r + W*r + k*MTU)/B -- -- In the worst case we have IntServ estimate with D = W*r+k*MTU -- and C = MTU*r. The proof (if correct at all) is trivial. -- -- -- --- It seems that cbq-2.0 is not very accurate. At least, I cannot -- interpret some places, which look like wrong translations -- from NS. Anyone is advised to find these differences -- and explain to me, why I am wrong 8). -- -- --- Linux has no EOI event, so that we cannot estimate true class -- idle time. Workaround is to consider the next dequeue event -- as sign that previous packet is finished. This is wrong because of -- internal device queueing, but on a permanently loaded link it is true. -- Moreover, combined with clock integrator, this scheme looks -- very close to an ideal solution. */ -- --struct cbq_sched_data; -- -- --struct cbq_class { -- struct Qdisc_class_common common; -- struct cbq_class *next_alive; /* next class with backlog in this priority band */ -- --/* Parameters */ -- unsigned char priority; /* class priority */ -- unsigned char priority2; /* priority to be used after overlimit */ -- unsigned char ewma_log; /* time constant for idle time calculation */ -- -- u32 defmap; -- -- /* Link-sharing scheduler parameters */ -- long maxidle; /* Class parameters: see below. */ -- long offtime; -- long minidle; -- u32 avpkt; -- struct qdisc_rate_table *R_tab; -- -- /* General scheduler (WRR) parameters */ -- long allot; -- long quantum; /* Allotment per WRR round */ -- long weight; /* Relative allotment: see below */ -- -- struct Qdisc *qdisc; /* Ptr to CBQ discipline */ -- struct cbq_class *split; /* Ptr to split node */ -- struct cbq_class *share; /* Ptr to LS parent in the class tree */ -- struct cbq_class *tparent; /* Ptr to tree parent in the class tree */ -- struct cbq_class *borrow; /* NULL if class is bandwidth limited; -- parent otherwise */ -- struct cbq_class *sibling; /* Sibling chain */ -- struct cbq_class *children; /* Pointer to children chain */ -- -- struct Qdisc *q; /* Elementary queueing discipline */ -- -- --/* Variables */ -- unsigned char cpriority; /* Effective priority */ -- unsigned char delayed; -- unsigned char level; /* level of the class in hierarchy: -- 0 for leaf classes, and maximal -- level of children + 1 for nodes. -- */ -- -- psched_time_t last; /* Last end of service */ -- psched_time_t undertime; -- long avgidle; -- long deficit; /* Saved deficit for WRR */ -- psched_time_t penalized; -- struct gnet_stats_basic_sync bstats; -- struct gnet_stats_queue qstats; -- struct net_rate_estimator __rcu *rate_est; -- struct tc_cbq_xstats xstats; -- -- struct tcf_proto __rcu *filter_list; -- struct tcf_block *block; -- -- int filters; -- -- struct cbq_class *defaults[TC_PRIO_MAX + 1]; --}; -- --struct cbq_sched_data { -- struct Qdisc_class_hash clhash; /* Hash table of all classes */ -- int nclasses[TC_CBQ_MAXPRIO + 1]; -- unsigned int quanta[TC_CBQ_MAXPRIO + 1]; -- -- struct cbq_class link; -- -- unsigned int activemask; -- struct cbq_class *active[TC_CBQ_MAXPRIO + 1]; /* List of all classes -- with backlog */ -- --#ifdef CONFIG_NET_CLS_ACT -- struct cbq_class *rx_class; --#endif -- struct cbq_class *tx_class; -- struct cbq_class *tx_borrowed; -- int tx_len; -- psched_time_t now; /* Cached timestamp */ -- unsigned int pmask; -- -- struct qdisc_watchdog watchdog; /* Watchdog timer, -- started when CBQ has -- backlog, but cannot -- transmit just now */ -- psched_tdiff_t wd_expires; -- int toplevel; -- u32 hgenerator; --}; -- -- --#define L2T(cl, len) qdisc_l2t((cl)->R_tab, len) -- --static inline struct cbq_class * --cbq_class_lookup(struct cbq_sched_data *q, u32 classid) --{ -- struct Qdisc_class_common *clc; -- -- clc = qdisc_class_find(&q->clhash, classid); -- if (clc == NULL) -- return NULL; -- return container_of(clc, struct cbq_class, common); --} -- --#ifdef CONFIG_NET_CLS_ACT -- --static struct cbq_class * --cbq_reclassify(struct sk_buff *skb, struct cbq_class *this) --{ -- struct cbq_class *cl; -- -- for (cl = this->tparent; cl; cl = cl->tparent) { -- struct cbq_class *new = cl->defaults[TC_PRIO_BESTEFFORT]; -- -- if (new != NULL && new != this) -- return new; -- } -- return NULL; --} -- --#endif -- --/* Classify packet. The procedure is pretty complicated, but -- * it allows us to combine link sharing and priority scheduling -- * transparently. -- * -- * Namely, you can put link sharing rules (f.e. route based) at root of CBQ, -- * so that it resolves to split nodes. Then packets are classified -- * by logical priority, or a more specific classifier may be attached -- * to the split node. -- */ -- --static struct cbq_class * --cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *head = &q->link; -- struct cbq_class **defmap; -- struct cbq_class *cl = NULL; -- u32 prio = skb->priority; -- struct tcf_proto *fl; -- struct tcf_result res; -- -- /* -- * Step 1. If skb->priority points to one of our classes, use it. -- */ -- if (TC_H_MAJ(prio ^ sch->handle) == 0 && -- (cl = cbq_class_lookup(q, prio)) != NULL) -- return cl; -- -- *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; -- for (;;) { -- int result = 0; -- defmap = head->defaults; -- -- fl = rcu_dereference_bh(head->filter_list); -- /* -- * Step 2+n. Apply classifier. -- */ -- result = tcf_classify(skb, NULL, fl, &res, true); -- if (!fl || result < 0) -- goto fallback; -- if (result == TC_ACT_SHOT) -- return NULL; -- -- cl = (void *)res.class; -- if (!cl) { -- if (TC_H_MAJ(res.classid)) -- cl = cbq_class_lookup(q, res.classid); -- else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL) -- cl = defmap[TC_PRIO_BESTEFFORT]; -- -- if (cl == NULL) -- goto fallback; -- } -- if (cl->level >= head->level) -- goto fallback; --#ifdef CONFIG_NET_CLS_ACT -- switch (result) { -- case TC_ACT_QUEUED: -- case TC_ACT_STOLEN: -- case TC_ACT_TRAP: -- *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; -- fallthrough; -- case TC_ACT_RECLASSIFY: -- return cbq_reclassify(skb, cl); -- } --#endif -- if (cl->level == 0) -- return cl; -- -- /* -- * Step 3+n. If classifier selected a link sharing class, -- * apply agency specific classifier. -- * Repeat this procedure until we hit a leaf node. -- */ -- head = cl; -- } -- --fallback: -- cl = head; -- -- /* -- * Step 4. No success... -- */ -- if (TC_H_MAJ(prio) == 0 && -- !(cl = head->defaults[prio & TC_PRIO_MAX]) && -- !(cl = head->defaults[TC_PRIO_BESTEFFORT])) -- return head; -- -- return cl; --} -- --/* -- * A packet has just been enqueued on the empty class. -- * cbq_activate_class adds it to the tail of active class list -- * of its priority band. -- */ -- --static inline void cbq_activate_class(struct cbq_class *cl) --{ -- struct cbq_sched_data *q = qdisc_priv(cl->qdisc); -- int prio = cl->cpriority; -- struct cbq_class *cl_tail; -- -- cl_tail = q->active[prio]; -- q->active[prio] = cl; -- -- if (cl_tail != NULL) { -- cl->next_alive = cl_tail->next_alive; -- cl_tail->next_alive = cl; -- } else { -- cl->next_alive = cl; -- q->activemask |= (1<qdisc); -- int prio = this->cpriority; -- struct cbq_class *cl; -- struct cbq_class *cl_prev = q->active[prio]; -- -- do { -- cl = cl_prev->next_alive; -- if (cl == this) { -- cl_prev->next_alive = cl->next_alive; -- cl->next_alive = NULL; -- -- if (cl == q->active[prio]) { -- q->active[prio] = cl_prev; -- if (cl == q->active[prio]) { -- q->active[prio] = NULL; -- q->activemask &= ~(1<active[prio]); --} -- --static void --cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl) --{ -- int toplevel = q->toplevel; -- -- if (toplevel > cl->level) { -- psched_time_t now = psched_get_time(); -- -- do { -- if (cl->undertime < now) { -- q->toplevel = cl->level; -- return; -- } -- } while ((cl = cl->borrow) != NULL && toplevel > cl->level); -- } --} -- --static int --cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch, -- struct sk_buff **to_free) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- int ret; -- struct cbq_class *cl = cbq_classify(skb, sch, &ret); -- --#ifdef CONFIG_NET_CLS_ACT -- q->rx_class = cl; --#endif -- if (cl == NULL) { -- if (ret & __NET_XMIT_BYPASS) -- qdisc_qstats_drop(sch); -- __qdisc_drop(skb, to_free); -- return ret; -- } -- -- ret = qdisc_enqueue(skb, cl->q, to_free); -- if (ret == NET_XMIT_SUCCESS) { -- sch->q.qlen++; -- cbq_mark_toplevel(q, cl); -- if (!cl->next_alive) -- cbq_activate_class(cl); -- return ret; -- } -- -- if (net_xmit_drop_count(ret)) { -- qdisc_qstats_drop(sch); -- cbq_mark_toplevel(q, cl); -- cl->qstats.drops++; -- } -- return ret; --} -- --/* Overlimit action: penalize leaf class by adding offtime */ --static void cbq_overlimit(struct cbq_class *cl) --{ -- struct cbq_sched_data *q = qdisc_priv(cl->qdisc); -- psched_tdiff_t delay = cl->undertime - q->now; -- -- if (!cl->delayed) { -- delay += cl->offtime; -- -- /* -- * Class goes to sleep, so that it will have no -- * chance to work avgidle. Let's forgive it 8) -- * -- * BTW cbq-2.0 has a crap in this -- * place, apparently they forgot to shift it by cl->ewma_log. -- */ -- if (cl->avgidle < 0) -- delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log); -- if (cl->avgidle < cl->minidle) -- cl->avgidle = cl->minidle; -- if (delay <= 0) -- delay = 1; -- cl->undertime = q->now + delay; -- -- cl->xstats.overactions++; -- cl->delayed = 1; -- } -- if (q->wd_expires == 0 || q->wd_expires > delay) -- q->wd_expires = delay; -- -- /* Dirty work! We must schedule wakeups based on -- * real available rate, rather than leaf rate, -- * which may be tiny (even zero). -- */ -- if (q->toplevel == TC_CBQ_MAXLEVEL) { -- struct cbq_class *b; -- psched_tdiff_t base_delay = q->wd_expires; -- -- for (b = cl->borrow; b; b = b->borrow) { -- delay = b->undertime - q->now; -- if (delay < base_delay) { -- if (delay <= 0) -- delay = 1; -- base_delay = delay; -- } -- } -- -- q->wd_expires = base_delay; -- } --} -- --/* -- * It is mission critical procedure. -- * -- * We "regenerate" toplevel cutoff, if transmitting class -- * has backlog and it is not regulated. It is not part of -- * original CBQ description, but looks more reasonable. -- * Probably, it is wrong. This question needs further investigation. -- */ -- --static inline void --cbq_update_toplevel(struct cbq_sched_data *q, struct cbq_class *cl, -- struct cbq_class *borrowed) --{ -- if (cl && q->toplevel >= borrowed->level) { -- if (cl->q->q.qlen > 1) { -- do { -- if (borrowed->undertime == PSCHED_PASTPERFECT) { -- q->toplevel = borrowed->level; -- return; -- } -- } while ((borrowed = borrowed->borrow) != NULL); -- } --#if 0 -- /* It is not necessary now. Uncommenting it -- will save CPU cycles, but decrease fairness. -- */ -- q->toplevel = TC_CBQ_MAXLEVEL; --#endif -- } --} -- --static void --cbq_update(struct cbq_sched_data *q) --{ -- struct cbq_class *this = q->tx_class; -- struct cbq_class *cl = this; -- int len = q->tx_len; -- psched_time_t now; -- -- q->tx_class = NULL; -- /* Time integrator. We calculate EOS time -- * by adding expected packet transmission time. -- */ -- now = q->now + L2T(&q->link, len); -- -- for ( ; cl; cl = cl->share) { -- long avgidle = cl->avgidle; -- long idle; -- -- _bstats_update(&cl->bstats, len, 1); -- -- /* -- * (now - last) is total time between packet right edges. -- * (last_pktlen/rate) is "virtual" busy time, so that -- * -- * idle = (now - last) - last_pktlen/rate -- */ -- -- idle = now - cl->last; -- if ((unsigned long)idle > 128*1024*1024) { -- avgidle = cl->maxidle; -- } else { -- idle -= L2T(cl, len); -- -- /* true_avgidle := (1-W)*true_avgidle + W*idle, -- * where W=2^{-ewma_log}. But cl->avgidle is scaled: -- * cl->avgidle == true_avgidle/W, -- * hence: -- */ -- avgidle += idle - (avgidle>>cl->ewma_log); -- } -- -- if (avgidle <= 0) { -- /* Overlimit or at-limit */ -- -- if (avgidle < cl->minidle) -- avgidle = cl->minidle; -- -- cl->avgidle = avgidle; -- -- /* Calculate expected time, when this class -- * will be allowed to send. -- * It will occur, when: -- * (1-W)*true_avgidle + W*delay = 0, i.e. -- * idle = (1/W - 1)*(-true_avgidle) -- * or -- * idle = (1 - W)*(-cl->avgidle); -- */ -- idle = (-avgidle) - ((-avgidle) >> cl->ewma_log); -- -- /* -- * That is not all. -- * To maintain the rate allocated to the class, -- * we add to undertime virtual clock, -- * necessary to complete transmitted packet. -- * (len/phys_bandwidth has been already passed -- * to the moment of cbq_update) -- */ -- -- idle -= L2T(&q->link, len); -- idle += L2T(cl, len); -- -- cl->undertime = now + idle; -- } else { -- /* Underlimit */ -- -- cl->undertime = PSCHED_PASTPERFECT; -- if (avgidle > cl->maxidle) -- cl->avgidle = cl->maxidle; -- else -- cl->avgidle = avgidle; -- } -- if ((s64)(now - cl->last) > 0) -- cl->last = now; -- } -- -- cbq_update_toplevel(q, this, q->tx_borrowed); --} -- --static inline struct cbq_class * --cbq_under_limit(struct cbq_class *cl) --{ -- struct cbq_sched_data *q = qdisc_priv(cl->qdisc); -- struct cbq_class *this_cl = cl; -- -- if (cl->tparent == NULL) -- return cl; -- -- if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) { -- cl->delayed = 0; -- return cl; -- } -- -- do { -- /* It is very suspicious place. Now overlimit -- * action is generated for not bounded classes -- * only if link is completely congested. -- * Though it is in agree with ancestor-only paradigm, -- * it looks very stupid. Particularly, -- * it means that this chunk of code will either -- * never be called or result in strong amplification -- * of burstiness. Dangerous, silly, and, however, -- * no another solution exists. -- */ -- cl = cl->borrow; -- if (!cl) { -- this_cl->qstats.overlimits++; -- cbq_overlimit(this_cl); -- return NULL; -- } -- if (cl->level > q->toplevel) -- return NULL; -- } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime); -- -- cl->delayed = 0; -- return cl; --} -- --static inline struct sk_buff * --cbq_dequeue_prio(struct Qdisc *sch, int prio) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl_tail, *cl_prev, *cl; -- struct sk_buff *skb; -- int deficit; -- -- cl_tail = cl_prev = q->active[prio]; -- cl = cl_prev->next_alive; -- -- do { -- deficit = 0; -- -- /* Start round */ -- do { -- struct cbq_class *borrow = cl; -- -- if (cl->q->q.qlen && -- (borrow = cbq_under_limit(cl)) == NULL) -- goto skip_class; -- -- if (cl->deficit <= 0) { -- /* Class exhausted its allotment per -- * this round. Switch to the next one. -- */ -- deficit = 1; -- cl->deficit += cl->quantum; -- goto next_class; -- } -- -- skb = cl->q->dequeue(cl->q); -- -- /* Class did not give us any skb :-( -- * It could occur even if cl->q->q.qlen != 0 -- * f.e. if cl->q == "tbf" -- */ -- if (skb == NULL) -- goto skip_class; -- -- cl->deficit -= qdisc_pkt_len(skb); -- q->tx_class = cl; -- q->tx_borrowed = borrow; -- if (borrow != cl) { --#ifndef CBQ_XSTATS_BORROWS_BYTES -- borrow->xstats.borrows++; -- cl->xstats.borrows++; --#else -- borrow->xstats.borrows += qdisc_pkt_len(skb); -- cl->xstats.borrows += qdisc_pkt_len(skb); --#endif -- } -- q->tx_len = qdisc_pkt_len(skb); -- -- if (cl->deficit <= 0) { -- q->active[prio] = cl; -- cl = cl->next_alive; -- cl->deficit += cl->quantum; -- } -- return skb; -- --skip_class: -- if (cl->q->q.qlen == 0 || prio != cl->cpriority) { -- /* Class is empty or penalized. -- * Unlink it from active chain. -- */ -- cl_prev->next_alive = cl->next_alive; -- cl->next_alive = NULL; -- -- /* Did cl_tail point to it? */ -- if (cl == cl_tail) { -- /* Repair it! */ -- cl_tail = cl_prev; -- -- /* Was it the last class in this band? */ -- if (cl == cl_tail) { -- /* Kill the band! */ -- q->active[prio] = NULL; -- q->activemask &= ~(1<q->q.qlen) -- cbq_activate_class(cl); -- return NULL; -- } -- -- q->active[prio] = cl_tail; -- } -- if (cl->q->q.qlen) -- cbq_activate_class(cl); -- -- cl = cl_prev; -- } -- --next_class: -- cl_prev = cl; -- cl = cl->next_alive; -- } while (cl_prev != cl_tail); -- } while (deficit); -- -- q->active[prio] = cl_prev; -- -- return NULL; --} -- --static inline struct sk_buff * --cbq_dequeue_1(struct Qdisc *sch) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct sk_buff *skb; -- unsigned int activemask; -- -- activemask = q->activemask & 0xFF; -- while (activemask) { -- int prio = ffz(~activemask); -- activemask &= ~(1<tx_class) -- cbq_update(q); -- -- q->now = now; -- -- for (;;) { -- q->wd_expires = 0; -- -- skb = cbq_dequeue_1(sch); -- if (skb) { -- qdisc_bstats_update(sch, skb); -- sch->q.qlen--; -- return skb; -- } -- -- /* All the classes are overlimit. -- * -- * It is possible, if: -- * -- * 1. Scheduler is empty. -- * 2. Toplevel cutoff inhibited borrowing. -- * 3. Root class is overlimit. -- * -- * Reset 2d and 3d conditions and retry. -- * -- * Note, that NS and cbq-2.0 are buggy, peeking -- * an arbitrary class is appropriate for ancestor-only -- * sharing, but not for toplevel algorithm. -- * -- * Our version is better, but slower, because it requires -- * two passes, but it is unavoidable with top-level sharing. -- */ -- -- if (q->toplevel == TC_CBQ_MAXLEVEL && -- q->link.undertime == PSCHED_PASTPERFECT) -- break; -- -- q->toplevel = TC_CBQ_MAXLEVEL; -- q->link.undertime = PSCHED_PASTPERFECT; -- } -- -- /* No packets in scheduler or nobody wants to give them to us :-( -- * Sigh... start watchdog timer in the last case. -- */ -- -- if (sch->q.qlen) { -- qdisc_qstats_overlimit(sch); -- if (q->wd_expires) -- qdisc_watchdog_schedule(&q->watchdog, -- now + q->wd_expires); -- } -- return NULL; --} -- --/* CBQ class maintenance routines */ -- --static void cbq_adjust_levels(struct cbq_class *this) --{ -- if (this == NULL) -- return; -- -- do { -- int level = 0; -- struct cbq_class *cl; -- -- cl = this->children; -- if (cl) { -- do { -- if (cl->level > level) -- level = cl->level; -- } while ((cl = cl->sibling) != this->children); -- } -- this->level = level + 1; -- } while ((this = this->tparent) != NULL); --} -- --static void cbq_normalize_quanta(struct cbq_sched_data *q, int prio) --{ -- struct cbq_class *cl; -- unsigned int h; -- -- if (q->quanta[prio] == 0) -- return; -- -- for (h = 0; h < q->clhash.hashsize; h++) { -- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) { -- /* BUGGGG... Beware! This expression suffer of -- * arithmetic overflows! -- */ -- if (cl->priority == prio) { -- cl->quantum = (cl->weight*cl->allot*q->nclasses[prio])/ -- q->quanta[prio]; -- } -- if (cl->quantum <= 0 || -- cl->quantum > 32*qdisc_dev(cl->qdisc)->mtu) { -- pr_warn("CBQ: class %08x has bad quantum==%ld, repaired.\n", -- cl->common.classid, cl->quantum); -- cl->quantum = qdisc_dev(cl->qdisc)->mtu/2 + 1; -- } -- } -- } --} -- --static void cbq_sync_defmap(struct cbq_class *cl) --{ -- struct cbq_sched_data *q = qdisc_priv(cl->qdisc); -- struct cbq_class *split = cl->split; -- unsigned int h; -- int i; -- -- if (split == NULL) -- return; -- -- for (i = 0; i <= TC_PRIO_MAX; i++) { -- if (split->defaults[i] == cl && !(cl->defmap & (1<defaults[i] = NULL; -- } -- -- for (i = 0; i <= TC_PRIO_MAX; i++) { -- int level = split->level; -- -- if (split->defaults[i]) -- continue; -- -- for (h = 0; h < q->clhash.hashsize; h++) { -- struct cbq_class *c; -- -- hlist_for_each_entry(c, &q->clhash.hash[h], -- common.hnode) { -- if (c->split == split && c->level < level && -- c->defmap & (1<defaults[i] = c; -- level = c->level; -- } -- } -- } -- } --} -- --static void cbq_change_defmap(struct cbq_class *cl, u32 splitid, u32 def, u32 mask) --{ -- struct cbq_class *split = NULL; -- -- if (splitid == 0) { -- split = cl->split; -- if (!split) -- return; -- splitid = split->common.classid; -- } -- -- if (split == NULL || split->common.classid != splitid) { -- for (split = cl->tparent; split; split = split->tparent) -- if (split->common.classid == splitid) -- break; -- } -- -- if (split == NULL) -- return; -- -- if (cl->split != split) { -- cl->defmap = 0; -- cbq_sync_defmap(cl); -- cl->split = split; -- cl->defmap = def & mask; -- } else -- cl->defmap = (cl->defmap & ~mask) | (def & mask); -- -- cbq_sync_defmap(cl); --} -- --static void cbq_unlink_class(struct cbq_class *this) --{ -- struct cbq_class *cl, **clp; -- struct cbq_sched_data *q = qdisc_priv(this->qdisc); -- -- qdisc_class_hash_remove(&q->clhash, &this->common); -- -- if (this->tparent) { -- clp = &this->sibling; -- cl = *clp; -- do { -- if (cl == this) { -- *clp = cl->sibling; -- break; -- } -- clp = &cl->sibling; -- } while ((cl = *clp) != this->sibling); -- -- if (this->tparent->children == this) { -- this->tparent->children = this->sibling; -- if (this->sibling == this) -- this->tparent->children = NULL; -- } -- } else { -- WARN_ON(this->sibling != this); -- } --} -- --static void cbq_link_class(struct cbq_class *this) --{ -- struct cbq_sched_data *q = qdisc_priv(this->qdisc); -- struct cbq_class *parent = this->tparent; -- -- this->sibling = this; -- qdisc_class_hash_insert(&q->clhash, &this->common); -- -- if (parent == NULL) -- return; -- -- if (parent->children == NULL) { -- parent->children = this; -- } else { -- this->sibling = parent->children->sibling; -- parent->children->sibling = this; -- } --} -- --static void --cbq_reset(struct Qdisc *sch) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl; -- int prio; -- unsigned int h; -- -- q->activemask = 0; -- q->pmask = 0; -- q->tx_class = NULL; -- q->tx_borrowed = NULL; -- qdisc_watchdog_cancel(&q->watchdog); -- q->toplevel = TC_CBQ_MAXLEVEL; -- q->now = psched_get_time(); -- -- for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++) -- q->active[prio] = NULL; -- -- for (h = 0; h < q->clhash.hashsize; h++) { -- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) { -- qdisc_reset(cl->q); -- -- cl->next_alive = NULL; -- cl->undertime = PSCHED_PASTPERFECT; -- cl->avgidle = cl->maxidle; -- cl->deficit = cl->quantum; -- cl->cpriority = cl->priority; -- } -- } --} -- -- --static void cbq_set_lss(struct cbq_class *cl, struct tc_cbq_lssopt *lss) --{ -- if (lss->change & TCF_CBQ_LSS_FLAGS) { -- cl->share = (lss->flags & TCF_CBQ_LSS_ISOLATED) ? NULL : cl->tparent; -- cl->borrow = (lss->flags & TCF_CBQ_LSS_BOUNDED) ? NULL : cl->tparent; -- } -- if (lss->change & TCF_CBQ_LSS_EWMA) -- cl->ewma_log = lss->ewma_log; -- if (lss->change & TCF_CBQ_LSS_AVPKT) -- cl->avpkt = lss->avpkt; -- if (lss->change & TCF_CBQ_LSS_MINIDLE) -- cl->minidle = -(long)lss->minidle; -- if (lss->change & TCF_CBQ_LSS_MAXIDLE) { -- cl->maxidle = lss->maxidle; -- cl->avgidle = lss->maxidle; -- } -- if (lss->change & TCF_CBQ_LSS_OFFTIME) -- cl->offtime = lss->offtime; --} -- --static void cbq_rmprio(struct cbq_sched_data *q, struct cbq_class *cl) --{ -- q->nclasses[cl->priority]--; -- q->quanta[cl->priority] -= cl->weight; -- cbq_normalize_quanta(q, cl->priority); --} -- --static void cbq_addprio(struct cbq_sched_data *q, struct cbq_class *cl) --{ -- q->nclasses[cl->priority]++; -- q->quanta[cl->priority] += cl->weight; -- cbq_normalize_quanta(q, cl->priority); --} -- --static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr) --{ -- struct cbq_sched_data *q = qdisc_priv(cl->qdisc); -- -- if (wrr->allot) -- cl->allot = wrr->allot; -- if (wrr->weight) -- cl->weight = wrr->weight; -- if (wrr->priority) { -- cl->priority = wrr->priority - 1; -- cl->cpriority = cl->priority; -- if (cl->priority >= cl->priority2) -- cl->priority2 = TC_CBQ_MAXPRIO - 1; -- } -- -- cbq_addprio(q, cl); -- return 0; --} -- --static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt) --{ -- cbq_change_defmap(cl, fopt->split, fopt->defmap, fopt->defchange); -- return 0; --} -- --static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = { -- [TCA_CBQ_LSSOPT] = { .len = sizeof(struct tc_cbq_lssopt) }, -- [TCA_CBQ_WRROPT] = { .len = sizeof(struct tc_cbq_wrropt) }, -- [TCA_CBQ_FOPT] = { .len = sizeof(struct tc_cbq_fopt) }, -- [TCA_CBQ_OVL_STRATEGY] = { .len = sizeof(struct tc_cbq_ovl) }, -- [TCA_CBQ_RATE] = { .len = sizeof(struct tc_ratespec) }, -- [TCA_CBQ_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, -- [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) }, --}; -- --static int cbq_opt_parse(struct nlattr *tb[TCA_CBQ_MAX + 1], -- struct nlattr *opt, -- struct netlink_ext_ack *extack) --{ -- int err; -- -- if (!opt) { -- NL_SET_ERR_MSG(extack, "CBQ options are required for this operation"); -- return -EINVAL; -- } -- -- err = nla_parse_nested_deprecated(tb, TCA_CBQ_MAX, opt, -- cbq_policy, extack); -- if (err < 0) -- return err; -- -- if (tb[TCA_CBQ_WRROPT]) { -- const struct tc_cbq_wrropt *wrr = nla_data(tb[TCA_CBQ_WRROPT]); -- -- if (wrr->priority > TC_CBQ_MAXPRIO) { -- NL_SET_ERR_MSG(extack, "priority is bigger than TC_CBQ_MAXPRIO"); -- err = -EINVAL; -- } -- } -- return err; --} -- --static int cbq_init(struct Qdisc *sch, struct nlattr *opt, -- struct netlink_ext_ack *extack) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct nlattr *tb[TCA_CBQ_MAX + 1]; -- struct tc_ratespec *r; -- int err; -- -- qdisc_watchdog_init(&q->watchdog, sch); -- -- err = cbq_opt_parse(tb, opt, extack); -- if (err < 0) -- return err; -- -- if (!tb[TCA_CBQ_RTAB] || !tb[TCA_CBQ_RATE]) { -- NL_SET_ERR_MSG(extack, "Rate specification missing or incomplete"); -- return -EINVAL; -- } -- -- r = nla_data(tb[TCA_CBQ_RATE]); -- -- q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB], extack); -- if (!q->link.R_tab) -- return -EINVAL; -- -- err = tcf_block_get(&q->link.block, &q->link.filter_list, sch, extack); -- if (err) -- goto put_rtab; -- -- err = qdisc_class_hash_init(&q->clhash); -- if (err < 0) -- goto put_block; -- -- q->link.sibling = &q->link; -- q->link.common.classid = sch->handle; -- q->link.qdisc = sch; -- q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, -- sch->handle, NULL); -- if (!q->link.q) -- q->link.q = &noop_qdisc; -- else -- qdisc_hash_add(q->link.q, true); -- -- q->link.priority = TC_CBQ_MAXPRIO - 1; -- q->link.priority2 = TC_CBQ_MAXPRIO - 1; -- q->link.cpriority = TC_CBQ_MAXPRIO - 1; -- q->link.allot = psched_mtu(qdisc_dev(sch)); -- q->link.quantum = q->link.allot; -- q->link.weight = q->link.R_tab->rate.rate; -- -- q->link.ewma_log = TC_CBQ_DEF_EWMA; -- q->link.avpkt = q->link.allot/2; -- q->link.minidle = -0x7FFFFFFF; -- -- q->toplevel = TC_CBQ_MAXLEVEL; -- q->now = psched_get_time(); -- -- cbq_link_class(&q->link); -- -- if (tb[TCA_CBQ_LSSOPT]) -- cbq_set_lss(&q->link, nla_data(tb[TCA_CBQ_LSSOPT])); -- -- cbq_addprio(q, &q->link); -- return 0; -- --put_block: -- tcf_block_put(q->link.block); -- --put_rtab: -- qdisc_put_rtab(q->link.R_tab); -- return err; --} -- --static int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl) --{ -- unsigned char *b = skb_tail_pointer(skb); -- -- if (nla_put(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate)) -- goto nla_put_failure; -- return skb->len; -- --nla_put_failure: -- nlmsg_trim(skb, b); -- return -1; --} -- --static int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl) --{ -- unsigned char *b = skb_tail_pointer(skb); -- struct tc_cbq_lssopt opt; -- -- opt.flags = 0; -- if (cl->borrow == NULL) -- opt.flags |= TCF_CBQ_LSS_BOUNDED; -- if (cl->share == NULL) -- opt.flags |= TCF_CBQ_LSS_ISOLATED; -- opt.ewma_log = cl->ewma_log; -- opt.level = cl->level; -- opt.avpkt = cl->avpkt; -- opt.maxidle = cl->maxidle; -- opt.minidle = (u32)(-cl->minidle); -- opt.offtime = cl->offtime; -- opt.change = ~0; -- if (nla_put(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt)) -- goto nla_put_failure; -- return skb->len; -- --nla_put_failure: -- nlmsg_trim(skb, b); -- return -1; --} -- --static int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl) --{ -- unsigned char *b = skb_tail_pointer(skb); -- struct tc_cbq_wrropt opt; -- -- memset(&opt, 0, sizeof(opt)); -- opt.flags = 0; -- opt.allot = cl->allot; -- opt.priority = cl->priority + 1; -- opt.cpriority = cl->cpriority + 1; -- opt.weight = cl->weight; -- if (nla_put(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt)) -- goto nla_put_failure; -- return skb->len; -- --nla_put_failure: -- nlmsg_trim(skb, b); -- return -1; --} -- --static int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl) --{ -- unsigned char *b = skb_tail_pointer(skb); -- struct tc_cbq_fopt opt; -- -- if (cl->split || cl->defmap) { -- opt.split = cl->split ? cl->split->common.classid : 0; -- opt.defmap = cl->defmap; -- opt.defchange = ~0; -- if (nla_put(skb, TCA_CBQ_FOPT, sizeof(opt), &opt)) -- goto nla_put_failure; -- } -- return skb->len; -- --nla_put_failure: -- nlmsg_trim(skb, b); -- return -1; --} -- --static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl) --{ -- if (cbq_dump_lss(skb, cl) < 0 || -- cbq_dump_rate(skb, cl) < 0 || -- cbq_dump_wrr(skb, cl) < 0 || -- cbq_dump_fopt(skb, cl) < 0) -- return -1; -- return 0; --} -- --static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct nlattr *nest; -- -- nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (nest == NULL) -- goto nla_put_failure; -- if (cbq_dump_attr(skb, &q->link) < 0) -- goto nla_put_failure; -- return nla_nest_end(skb, nest); -- --nla_put_failure: -- nla_nest_cancel(skb, nest); -- return -1; --} -- --static int --cbq_dump_stats(struct Qdisc *sch, struct gnet_dump *d) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- -- q->link.xstats.avgidle = q->link.avgidle; -- return gnet_stats_copy_app(d, &q->link.xstats, sizeof(q->link.xstats)); --} -- --static int --cbq_dump_class(struct Qdisc *sch, unsigned long arg, -- struct sk_buff *skb, struct tcmsg *tcm) --{ -- struct cbq_class *cl = (struct cbq_class *)arg; -- struct nlattr *nest; -- -- if (cl->tparent) -- tcm->tcm_parent = cl->tparent->common.classid; -- else -- tcm->tcm_parent = TC_H_ROOT; -- tcm->tcm_handle = cl->common.classid; -- tcm->tcm_info = cl->q->handle; -- -- nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (nest == NULL) -- goto nla_put_failure; -- if (cbq_dump_attr(skb, cl) < 0) -- goto nla_put_failure; -- return nla_nest_end(skb, nest); -- --nla_put_failure: -- nla_nest_cancel(skb, nest); -- return -1; --} -- --static int --cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg, -- struct gnet_dump *d) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl = (struct cbq_class *)arg; -- __u32 qlen; -- -- cl->xstats.avgidle = cl->avgidle; -- cl->xstats.undertime = 0; -- qdisc_qstats_qlen_backlog(cl->q, &qlen, &cl->qstats.backlog); -- -- if (cl->undertime != PSCHED_PASTPERFECT) -- cl->xstats.undertime = cl->undertime - q->now; -- -- if (gnet_stats_copy_basic(d, NULL, &cl->bstats, true) < 0 || -- gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 || -- gnet_stats_copy_queue(d, NULL, &cl->qstats, qlen) < 0) -- return -1; -- -- return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats)); --} -- --static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, -- struct Qdisc **old, struct netlink_ext_ack *extack) --{ -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- if (new == NULL) { -- new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, -- cl->common.classid, extack); -- if (new == NULL) -- return -ENOBUFS; -- } -- -- *old = qdisc_replace(sch, new, &cl->q); -- return 0; --} -- --static struct Qdisc *cbq_leaf(struct Qdisc *sch, unsigned long arg) --{ -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- return cl->q; --} -- --static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg) --{ -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- cbq_deactivate_class(cl); --} -- --static unsigned long cbq_find(struct Qdisc *sch, u32 classid) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- -- return (unsigned long)cbq_class_lookup(q, classid); --} -- --static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- -- WARN_ON(cl->filters); -- -- tcf_block_put(cl->block); -- qdisc_put(cl->q); -- qdisc_put_rtab(cl->R_tab); -- gen_kill_estimator(&cl->rate_est); -- if (cl != &q->link) -- kfree(cl); --} -- --static void cbq_destroy(struct Qdisc *sch) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct hlist_node *next; -- struct cbq_class *cl; -- unsigned int h; -- --#ifdef CONFIG_NET_CLS_ACT -- q->rx_class = NULL; --#endif -- /* -- * Filters must be destroyed first because we don't destroy the -- * classes from root to leafs which means that filters can still -- * be bound to classes which have been destroyed already. --TGR '04 -- */ -- for (h = 0; h < q->clhash.hashsize; h++) { -- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) { -- tcf_block_put(cl->block); -- cl->block = NULL; -- } -- } -- for (h = 0; h < q->clhash.hashsize; h++) { -- hlist_for_each_entry_safe(cl, next, &q->clhash.hash[h], -- common.hnode) -- cbq_destroy_class(sch, cl); -- } -- qdisc_class_hash_destroy(&q->clhash); --} -- --static int --cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, -- unsigned long *arg, struct netlink_ext_ack *extack) --{ -- int err; -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl = (struct cbq_class *)*arg; -- struct nlattr *opt = tca[TCA_OPTIONS]; -- struct nlattr *tb[TCA_CBQ_MAX + 1]; -- struct cbq_class *parent; -- struct qdisc_rate_table *rtab = NULL; -- -- err = cbq_opt_parse(tb, opt, extack); -- if (err < 0) -- return err; -- -- if (tb[TCA_CBQ_OVL_STRATEGY] || tb[TCA_CBQ_POLICE]) { -- NL_SET_ERR_MSG(extack, "Neither overlimit strategy nor policing attributes can be used for changing class params"); -- return -EOPNOTSUPP; -- } -- -- if (cl) { -- /* Check parent */ -- if (parentid) { -- if (cl->tparent && -- cl->tparent->common.classid != parentid) { -- NL_SET_ERR_MSG(extack, "Invalid parent id"); -- return -EINVAL; -- } -- if (!cl->tparent && parentid != TC_H_ROOT) { -- NL_SET_ERR_MSG(extack, "Parent must be root"); -- return -EINVAL; -- } -- } -- -- if (tb[TCA_CBQ_RATE]) { -- rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), -- tb[TCA_CBQ_RTAB], extack); -- if (rtab == NULL) -- return -EINVAL; -- } -- -- if (tca[TCA_RATE]) { -- err = gen_replace_estimator(&cl->bstats, NULL, -- &cl->rate_est, -- NULL, -- true, -- tca[TCA_RATE]); -- if (err) { -- NL_SET_ERR_MSG(extack, "Failed to replace specified rate estimator"); -- qdisc_put_rtab(rtab); -- return err; -- } -- } -- -- /* Change class parameters */ -- sch_tree_lock(sch); -- -- if (cl->next_alive != NULL) -- cbq_deactivate_class(cl); -- -- if (rtab) { -- qdisc_put_rtab(cl->R_tab); -- cl->R_tab = rtab; -- } -- -- if (tb[TCA_CBQ_LSSOPT]) -- cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT])); -- -- if (tb[TCA_CBQ_WRROPT]) { -- cbq_rmprio(q, cl); -- cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT])); -- } -- -- if (tb[TCA_CBQ_FOPT]) -- cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT])); -- -- if (cl->q->q.qlen) -- cbq_activate_class(cl); -- -- sch_tree_unlock(sch); -- -- return 0; -- } -- -- if (parentid == TC_H_ROOT) -- return -EINVAL; -- -- if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT]) { -- NL_SET_ERR_MSG(extack, "One of the following attributes MUST be specified: WRR, rate or link sharing"); -- return -EINVAL; -- } -- -- rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB], -- extack); -- if (rtab == NULL) -- return -EINVAL; -- -- if (classid) { -- err = -EINVAL; -- if (TC_H_MAJ(classid ^ sch->handle) || -- cbq_class_lookup(q, classid)) { -- NL_SET_ERR_MSG(extack, "Specified class not found"); -- goto failure; -- } -- } else { -- int i; -- classid = TC_H_MAKE(sch->handle, 0x8000); -- -- for (i = 0; i < 0x8000; i++) { -- if (++q->hgenerator >= 0x8000) -- q->hgenerator = 1; -- if (cbq_class_lookup(q, classid|q->hgenerator) == NULL) -- break; -- } -- err = -ENOSR; -- if (i >= 0x8000) { -- NL_SET_ERR_MSG(extack, "Unable to generate classid"); -- goto failure; -- } -- classid = classid|q->hgenerator; -- } -- -- parent = &q->link; -- if (parentid) { -- parent = cbq_class_lookup(q, parentid); -- err = -EINVAL; -- if (!parent) { -- NL_SET_ERR_MSG(extack, "Failed to find parentid"); -- goto failure; -- } -- } -- -- err = -ENOBUFS; -- cl = kzalloc(sizeof(*cl), GFP_KERNEL); -- if (cl == NULL) -- goto failure; -- -- gnet_stats_basic_sync_init(&cl->bstats); -- err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); -- if (err) { -- kfree(cl); -- goto failure; -- } -- -- if (tca[TCA_RATE]) { -- err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est, -- NULL, true, tca[TCA_RATE]); -- if (err) { -- NL_SET_ERR_MSG(extack, "Couldn't create new estimator"); -- tcf_block_put(cl->block); -- kfree(cl); -- goto failure; -- } -- } -- -- cl->R_tab = rtab; -- rtab = NULL; -- cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid, -- NULL); -- if (!cl->q) -- cl->q = &noop_qdisc; -- else -- qdisc_hash_add(cl->q, true); -- -- cl->common.classid = classid; -- cl->tparent = parent; -- cl->qdisc = sch; -- cl->allot = parent->allot; -- cl->quantum = cl->allot; -- cl->weight = cl->R_tab->rate.rate; -- -- sch_tree_lock(sch); -- cbq_link_class(cl); -- cl->borrow = cl->tparent; -- if (cl->tparent != &q->link) -- cl->share = cl->tparent; -- cbq_adjust_levels(parent); -- cl->minidle = -0x7FFFFFFF; -- cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT])); -- cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT])); -- if (cl->ewma_log == 0) -- cl->ewma_log = q->link.ewma_log; -- if (cl->maxidle == 0) -- cl->maxidle = q->link.maxidle; -- if (cl->avpkt == 0) -- cl->avpkt = q->link.avpkt; -- if (tb[TCA_CBQ_FOPT]) -- cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT])); -- sch_tree_unlock(sch); -- -- qdisc_class_hash_grow(sch, &q->clhash); -- -- *arg = (unsigned long)cl; -- return 0; -- --failure: -- qdisc_put_rtab(rtab); -- return err; --} -- --static int cbq_delete(struct Qdisc *sch, unsigned long arg, -- struct netlink_ext_ack *extack) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- if (cl->filters || cl->children || cl == &q->link) -- return -EBUSY; -- -- sch_tree_lock(sch); -- -- qdisc_purge_queue(cl->q); -- -- if (cl->next_alive) -- cbq_deactivate_class(cl); -- -- if (q->tx_borrowed == cl) -- q->tx_borrowed = q->tx_class; -- if (q->tx_class == cl) { -- q->tx_class = NULL; -- q->tx_borrowed = NULL; -- } --#ifdef CONFIG_NET_CLS_ACT -- if (q->rx_class == cl) -- q->rx_class = NULL; --#endif -- -- cbq_unlink_class(cl); -- cbq_adjust_levels(cl->tparent); -- cl->defmap = 0; -- cbq_sync_defmap(cl); -- -- cbq_rmprio(q, cl); -- sch_tree_unlock(sch); -- -- cbq_destroy_class(sch, cl); -- return 0; --} -- --static struct tcf_block *cbq_tcf_block(struct Qdisc *sch, unsigned long arg, -- struct netlink_ext_ack *extack) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- if (cl == NULL) -- cl = &q->link; -- -- return cl->block; --} -- --static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent, -- u32 classid) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *p = (struct cbq_class *)parent; -- struct cbq_class *cl = cbq_class_lookup(q, classid); -- -- if (cl) { -- if (p && p->level <= cl->level) -- return 0; -- cl->filters++; -- return (unsigned long)cl; -- } -- return 0; --} -- --static void cbq_unbind_filter(struct Qdisc *sch, unsigned long arg) --{ -- struct cbq_class *cl = (struct cbq_class *)arg; -- -- cl->filters--; --} -- --static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg) --{ -- struct cbq_sched_data *q = qdisc_priv(sch); -- struct cbq_class *cl; -- unsigned int h; -- -- if (arg->stop) -- return; -- -- for (h = 0; h < q->clhash.hashsize; h++) { -- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) { -- if (!tc_qdisc_stats_dump(sch, (unsigned long)cl, arg)) -- return; -- } -- } --} -- --static const struct Qdisc_class_ops cbq_class_ops = { -- .graft = cbq_graft, -- .leaf = cbq_leaf, -- .qlen_notify = cbq_qlen_notify, -- .find = cbq_find, -- .change = cbq_change_class, -- .delete = cbq_delete, -- .walk = cbq_walk, -- .tcf_block = cbq_tcf_block, -- .bind_tcf = cbq_bind_filter, -- .unbind_tcf = cbq_unbind_filter, -- .dump = cbq_dump_class, -- .dump_stats = cbq_dump_class_stats, --}; -- --static struct Qdisc_ops cbq_qdisc_ops __read_mostly = { -- .next = NULL, -- .cl_ops = &cbq_class_ops, -- .id = "cbq", -- .priv_size = sizeof(struct cbq_sched_data), -- .enqueue = cbq_enqueue, -- .dequeue = cbq_dequeue, -- .peek = qdisc_peek_dequeued, -- .init = cbq_init, -- .reset = cbq_reset, -- .destroy = cbq_destroy, -- .change = NULL, -- .dump = cbq_dump, -- .dump_stats = cbq_dump_stats, -- .owner = THIS_MODULE, --}; -- --static int __init cbq_module_init(void) --{ -- return register_qdisc(&cbq_qdisc_ops); --} --static void __exit cbq_module_exit(void) --{ -- unregister_qdisc(&cbq_qdisc_ops); --} --module_init(cbq_module_init) --module_exit(cbq_module_exit) --MODULE_LICENSE("GPL"); -diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c -deleted file mode 100644 -index 401ffaf87d622..0000000000000 ---- a/net/sched/sch_dsmark.c -+++ /dev/null -@@ -1,518 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* net/sched/sch_dsmark.c - Differentiated Services field marker */ -- --/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ -- -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --/* -- * classid class marking -- * ------- ----- ------- -- * n/a 0 n/a -- * x:0 1 use entry [0] -- * ... ... ... -- * x:y y>0 y+1 use entry [y] -- * ... ... ... -- * x:indices-1 indices use entry [indices-1] -- * ... ... ... -- * x:y y+1 use entry [y & (indices-1)] -- * ... ... ... -- * 0xffff 0x10000 use entry [indices-1] -- */ -- -- --#define NO_DEFAULT_INDEX (1 << 16) -- --struct mask_value { -- u8 mask; -- u8 value; --}; -- --struct dsmark_qdisc_data { -- struct Qdisc *q; -- struct tcf_proto __rcu *filter_list; -- struct tcf_block *block; -- struct mask_value *mv; -- u16 indices; -- u8 set_tc_index; -- u32 default_index; /* index range is 0...0xffff */ --#define DSMARK_EMBEDDED_SZ 16 -- struct mask_value embedded[DSMARK_EMBEDDED_SZ]; --}; -- --static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index) --{ -- return index <= p->indices && index > 0; --} -- --/* ------------------------- Class/flow operations ------------------------- */ -- --static int dsmark_graft(struct Qdisc *sch, unsigned long arg, -- struct Qdisc *new, struct Qdisc **old, -- struct netlink_ext_ack *extack) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- pr_debug("%s(sch %p,[qdisc %p],new %p,old %p)\n", -- __func__, sch, p, new, old); -- -- if (new == NULL) { -- new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, -- sch->handle, NULL); -- if (new == NULL) -- new = &noop_qdisc; -- } -- -- *old = qdisc_replace(sch, new, &p->q); -- return 0; --} -- --static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- return p->q; --} -- --static unsigned long dsmark_find(struct Qdisc *sch, u32 classid) --{ -- return TC_H_MIN(classid) + 1; --} -- --static unsigned long dsmark_bind_filter(struct Qdisc *sch, -- unsigned long parent, u32 classid) --{ -- pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", -- __func__, sch, qdisc_priv(sch), classid); -- -- return dsmark_find(sch, classid); --} -- --static void dsmark_unbind_filter(struct Qdisc *sch, unsigned long cl) --{ --} -- --static const struct nla_policy dsmark_policy[TCA_DSMARK_MAX + 1] = { -- [TCA_DSMARK_INDICES] = { .type = NLA_U16 }, -- [TCA_DSMARK_DEFAULT_INDEX] = { .type = NLA_U16 }, -- [TCA_DSMARK_SET_TC_INDEX] = { .type = NLA_FLAG }, -- [TCA_DSMARK_MASK] = { .type = NLA_U8 }, -- [TCA_DSMARK_VALUE] = { .type = NLA_U8 }, --}; -- --static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, -- struct nlattr **tca, unsigned long *arg, -- struct netlink_ext_ack *extack) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- struct nlattr *opt = tca[TCA_OPTIONS]; -- struct nlattr *tb[TCA_DSMARK_MAX + 1]; -- int err = -EINVAL; -- -- pr_debug("%s(sch %p,[qdisc %p],classid %x,parent %x), arg 0x%lx\n", -- __func__, sch, p, classid, parent, *arg); -- -- if (!dsmark_valid_index(p, *arg)) { -- err = -ENOENT; -- goto errout; -- } -- -- if (!opt) -- goto errout; -- -- err = nla_parse_nested_deprecated(tb, TCA_DSMARK_MAX, opt, -- dsmark_policy, NULL); -- if (err < 0) -- goto errout; -- -- if (tb[TCA_DSMARK_VALUE]) -- p->mv[*arg - 1].value = nla_get_u8(tb[TCA_DSMARK_VALUE]); -- -- if (tb[TCA_DSMARK_MASK]) -- p->mv[*arg - 1].mask = nla_get_u8(tb[TCA_DSMARK_MASK]); -- -- err = 0; -- --errout: -- return err; --} -- --static int dsmark_delete(struct Qdisc *sch, unsigned long arg, -- struct netlink_ext_ack *extack) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- if (!dsmark_valid_index(p, arg)) -- return -EINVAL; -- -- p->mv[arg - 1].mask = 0xff; -- p->mv[arg - 1].value = 0; -- -- return 0; --} -- --static void dsmark_walk(struct Qdisc *sch, struct qdisc_walker *walker) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- int i; -- -- pr_debug("%s(sch %p,[qdisc %p],walker %p)\n", -- __func__, sch, p, walker); -- -- if (walker->stop) -- return; -- -- for (i = 0; i < p->indices; i++) { -- if (p->mv[i].mask == 0xff && !p->mv[i].value) { -- walker->count++; -- continue; -- } -- if (!tc_qdisc_stats_dump(sch, i + 1, walker)) -- break; -- } --} -- --static struct tcf_block *dsmark_tcf_block(struct Qdisc *sch, unsigned long cl, -- struct netlink_ext_ack *extack) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- return p->block; --} -- --/* --------------------------- Qdisc operations ---------------------------- */ -- --static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch, -- struct sk_buff **to_free) --{ -- unsigned int len = qdisc_pkt_len(skb); -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- int err; -- -- pr_debug("%s(skb %p,sch %p,[qdisc %p])\n", __func__, skb, sch, p); -- -- if (p->set_tc_index) { -- int wlen = skb_network_offset(skb); -- -- switch (skb_protocol(skb, true)) { -- case htons(ETH_P_IP): -- wlen += sizeof(struct iphdr); -- if (!pskb_may_pull(skb, wlen) || -- skb_try_make_writable(skb, wlen)) -- goto drop; -- -- skb->tc_index = ipv4_get_dsfield(ip_hdr(skb)) -- & ~INET_ECN_MASK; -- break; -- -- case htons(ETH_P_IPV6): -- wlen += sizeof(struct ipv6hdr); -- if (!pskb_may_pull(skb, wlen) || -- skb_try_make_writable(skb, wlen)) -- goto drop; -- -- skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb)) -- & ~INET_ECN_MASK; -- break; -- default: -- skb->tc_index = 0; -- break; -- } -- } -- -- if (TC_H_MAJ(skb->priority) == sch->handle) -- skb->tc_index = TC_H_MIN(skb->priority); -- else { -- struct tcf_result res; -- struct tcf_proto *fl = rcu_dereference_bh(p->filter_list); -- int result = tcf_classify(skb, NULL, fl, &res, false); -- -- pr_debug("result %d class 0x%04x\n", result, res.classid); -- -- switch (result) { --#ifdef CONFIG_NET_CLS_ACT -- case TC_ACT_QUEUED: -- case TC_ACT_STOLEN: -- case TC_ACT_TRAP: -- __qdisc_drop(skb, to_free); -- return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; -- -- case TC_ACT_SHOT: -- goto drop; --#endif -- case TC_ACT_OK: -- skb->tc_index = TC_H_MIN(res.classid); -- break; -- -- default: -- if (p->default_index != NO_DEFAULT_INDEX) -- skb->tc_index = p->default_index; -- break; -- } -- } -- -- err = qdisc_enqueue(skb, p->q, to_free); -- if (err != NET_XMIT_SUCCESS) { -- if (net_xmit_drop_count(err)) -- qdisc_qstats_drop(sch); -- return err; -- } -- -- sch->qstats.backlog += len; -- sch->q.qlen++; -- -- return NET_XMIT_SUCCESS; -- --drop: -- qdisc_drop(skb, sch, to_free); -- return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; --} -- --static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- struct sk_buff *skb; -- u32 index; -- -- pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); -- -- skb = qdisc_dequeue_peeked(p->q); -- if (skb == NULL) -- return NULL; -- -- qdisc_bstats_update(sch, skb); -- qdisc_qstats_backlog_dec(sch, skb); -- sch->q.qlen--; -- -- index = skb->tc_index & (p->indices - 1); -- pr_debug("index %d->%d\n", skb->tc_index, index); -- -- switch (skb_protocol(skb, true)) { -- case htons(ETH_P_IP): -- ipv4_change_dsfield(ip_hdr(skb), p->mv[index].mask, -- p->mv[index].value); -- break; -- case htons(ETH_P_IPV6): -- ipv6_change_dsfield(ipv6_hdr(skb), p->mv[index].mask, -- p->mv[index].value); -- break; -- default: -- /* -- * Only complain if a change was actually attempted. -- * This way, we can send non-IP traffic through dsmark -- * and don't need yet another qdisc as a bypass. -- */ -- if (p->mv[index].mask != 0xff || p->mv[index].value) -- pr_warn("%s: unsupported protocol %d\n", -- __func__, ntohs(skb_protocol(skb, true))); -- break; -- } -- -- return skb; --} -- --static struct sk_buff *dsmark_peek(struct Qdisc *sch) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); -- -- return p->q->ops->peek(p->q); --} -- --static int dsmark_init(struct Qdisc *sch, struct nlattr *opt, -- struct netlink_ext_ack *extack) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- struct nlattr *tb[TCA_DSMARK_MAX + 1]; -- int err = -EINVAL; -- u32 default_index = NO_DEFAULT_INDEX; -- u16 indices; -- int i; -- -- pr_debug("%s(sch %p,[qdisc %p],opt %p)\n", __func__, sch, p, opt); -- -- if (!opt) -- goto errout; -- -- err = tcf_block_get(&p->block, &p->filter_list, sch, extack); -- if (err) -- return err; -- -- err = nla_parse_nested_deprecated(tb, TCA_DSMARK_MAX, opt, -- dsmark_policy, NULL); -- if (err < 0) -- goto errout; -- -- err = -EINVAL; -- if (!tb[TCA_DSMARK_INDICES]) -- goto errout; -- indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); -- -- if (hweight32(indices) != 1) -- goto errout; -- -- if (tb[TCA_DSMARK_DEFAULT_INDEX]) -- default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); -- -- if (indices <= DSMARK_EMBEDDED_SZ) -- p->mv = p->embedded; -- else -- p->mv = kmalloc_array(indices, sizeof(*p->mv), GFP_KERNEL); -- if (!p->mv) { -- err = -ENOMEM; -- goto errout; -- } -- for (i = 0; i < indices; i++) { -- p->mv[i].mask = 0xff; -- p->mv[i].value = 0; -- } -- p->indices = indices; -- p->default_index = default_index; -- p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]); -- -- p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle, -- NULL); -- if (p->q == NULL) -- p->q = &noop_qdisc; -- else -- qdisc_hash_add(p->q, true); -- -- pr_debug("%s: qdisc %p\n", __func__, p->q); -- -- err = 0; --errout: -- return err; --} -- --static void dsmark_reset(struct Qdisc *sch) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); -- if (p->q) -- qdisc_reset(p->q); --} -- --static void dsmark_destroy(struct Qdisc *sch) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- -- pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); -- -- tcf_block_put(p->block); -- qdisc_put(p->q); -- if (p->mv != p->embedded) -- kfree(p->mv); --} -- --static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl, -- struct sk_buff *skb, struct tcmsg *tcm) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- struct nlattr *opts = NULL; -- -- pr_debug("%s(sch %p,[qdisc %p],class %ld\n", __func__, sch, p, cl); -- -- if (!dsmark_valid_index(p, cl)) -- return -EINVAL; -- -- tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl - 1); -- tcm->tcm_info = p->q->handle; -- -- opts = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (opts == NULL) -- goto nla_put_failure; -- if (nla_put_u8(skb, TCA_DSMARK_MASK, p->mv[cl - 1].mask) || -- nla_put_u8(skb, TCA_DSMARK_VALUE, p->mv[cl - 1].value)) -- goto nla_put_failure; -- -- return nla_nest_end(skb, opts); -- --nla_put_failure: -- nla_nest_cancel(skb, opts); -- return -EMSGSIZE; --} -- --static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) --{ -- struct dsmark_qdisc_data *p = qdisc_priv(sch); -- struct nlattr *opts = NULL; -- -- opts = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (opts == NULL) -- goto nla_put_failure; -- if (nla_put_u16(skb, TCA_DSMARK_INDICES, p->indices)) -- goto nla_put_failure; -- -- if (p->default_index != NO_DEFAULT_INDEX && -- nla_put_u16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index)) -- goto nla_put_failure; -- -- if (p->set_tc_index && -- nla_put_flag(skb, TCA_DSMARK_SET_TC_INDEX)) -- goto nla_put_failure; -- -- return nla_nest_end(skb, opts); -- --nla_put_failure: -- nla_nest_cancel(skb, opts); -- return -EMSGSIZE; --} -- --static const struct Qdisc_class_ops dsmark_class_ops = { -- .graft = dsmark_graft, -- .leaf = dsmark_leaf, -- .find = dsmark_find, -- .change = dsmark_change, -- .delete = dsmark_delete, -- .walk = dsmark_walk, -- .tcf_block = dsmark_tcf_block, -- .bind_tcf = dsmark_bind_filter, -- .unbind_tcf = dsmark_unbind_filter, -- .dump = dsmark_dump_class, --}; -- --static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = { -- .next = NULL, -- .cl_ops = &dsmark_class_ops, -- .id = "dsmark", -- .priv_size = sizeof(struct dsmark_qdisc_data), -- .enqueue = dsmark_enqueue, -- .dequeue = dsmark_dequeue, -- .peek = dsmark_peek, -- .init = dsmark_init, -- .reset = dsmark_reset, -- .destroy = dsmark_destroy, -- .change = NULL, -- .dump = dsmark_dump, -- .owner = THIS_MODULE, --}; -- --static int __init dsmark_module_init(void) --{ -- return register_qdisc(&dsmark_qdisc_ops); --} -- --static void __exit dsmark_module_exit(void) --{ -- unregister_qdisc(&dsmark_qdisc_ops); --} -- --module_init(dsmark_module_init) --module_exit(dsmark_module_exit) -- --MODULE_LICENSE("GPL"); -diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c -index 8cc42aea19c7e..2e14d4c37e2dc 100644 ---- a/net/switchdev/switchdev.c -+++ b/net/switchdev/switchdev.c -@@ -19,6 +19,35 @@ - #include - #include - -+static bool switchdev_obj_eq(const struct switchdev_obj *a, -+ const struct switchdev_obj *b) -+{ -+ const struct switchdev_obj_port_vlan *va, *vb; -+ const struct switchdev_obj_port_mdb *ma, *mb; -+ -+ if (a->id != b->id || a->orig_dev != b->orig_dev) -+ return false; -+ -+ switch (a->id) { -+ case SWITCHDEV_OBJ_ID_PORT_VLAN: -+ va = SWITCHDEV_OBJ_PORT_VLAN(a); -+ vb = SWITCHDEV_OBJ_PORT_VLAN(b); -+ return va->flags == vb->flags && -+ va->vid == vb->vid && -+ va->changed == vb->changed; -+ case SWITCHDEV_OBJ_ID_PORT_MDB: -+ case SWITCHDEV_OBJ_ID_HOST_MDB: -+ ma = SWITCHDEV_OBJ_PORT_MDB(a); -+ mb = SWITCHDEV_OBJ_PORT_MDB(b); -+ return ma->vid == mb->vid && -+ ether_addr_equal(ma->addr, mb->addr); -+ default: -+ break; -+ } -+ -+ BUG(); -+} -+ - static LIST_HEAD(deferred); - static DEFINE_SPINLOCK(deferred_lock); - -@@ -307,6 +336,50 @@ int switchdev_port_obj_del(struct net_device *dev, - } - EXPORT_SYMBOL_GPL(switchdev_port_obj_del); - -+/** -+ * switchdev_port_obj_act_is_deferred - Is object action pending? -+ * -+ * @dev: port device -+ * @nt: type of action; add or delete -+ * @obj: object to test -+ * -+ * Returns true if a deferred item is pending, which is -+ * equivalent to the action @nt on an object @obj. -+ * -+ * rtnl_lock must be held. -+ */ -+bool switchdev_port_obj_act_is_deferred(struct net_device *dev, -+ enum switchdev_notifier_type nt, -+ const struct switchdev_obj *obj) -+{ -+ struct switchdev_deferred_item *dfitem; -+ bool found = false; -+ -+ ASSERT_RTNL(); -+ -+ spin_lock_bh(&deferred_lock); -+ -+ list_for_each_entry(dfitem, &deferred, list) { -+ if (dfitem->dev != dev) -+ continue; -+ -+ if ((dfitem->func == switchdev_port_obj_add_deferred && -+ nt == SWITCHDEV_PORT_OBJ_ADD) || -+ (dfitem->func == switchdev_port_obj_del_deferred && -+ nt == SWITCHDEV_PORT_OBJ_DEL)) { -+ if (switchdev_obj_eq((const void *)dfitem->data, obj)) { -+ found = true; -+ break; -+ } -+ } -+ } -+ -+ spin_unlock_bh(&deferred_lock); -+ -+ return found; -+} -+EXPORT_SYMBOL_GPL(switchdev_port_obj_act_is_deferred); -+ - static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain); - static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain); - -diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c -index 80b42a3e78830..6b7189a520af7 100644 ---- a/net/tls/tls_main.c -+++ b/net/tls/tls_main.c -@@ -1098,7 +1098,7 @@ static u16 tls_user_config(struct tls_context *ctx, bool tx) - return 0; - } - --static int tls_get_info(const struct sock *sk, struct sk_buff *skb) -+static int tls_get_info(struct sock *sk, struct sk_buff *skb) - { - u16 version, cipher_type; - struct tls_context *ctx; -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index c8cbdd02a784e..93e1bfa72d791 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -1845,7 +1845,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, - u8 *control, - size_t skip, - size_t len, -- bool is_peek) -+ bool is_peek, -+ bool *more) - { - struct sk_buff *skb = skb_peek(&ctx->rx_list); - struct tls_msg *tlm; -@@ -1858,7 +1859,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, - - err = tls_record_content_type(msg, tlm, control); - if (err <= 0) -- goto out; -+ goto more; - - if (skip < rxm->full_len) - break; -@@ -1876,12 +1877,12 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, - - err = tls_record_content_type(msg, tlm, control); - if (err <= 0) -- goto out; -+ goto more; - - err = skb_copy_datagram_msg(skb, rxm->offset + skip, - msg, chunk); - if (err < 0) -- goto out; -+ goto more; - - len = len - chunk; - copied = copied + chunk; -@@ -1917,6 +1918,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx, - - out: - return copied ? : err; -+more: -+ if (more) -+ *more = true; -+ goto out; - } - - static bool -@@ -2020,6 +2025,7 @@ int tls_sw_recvmsg(struct sock *sk, - int target, err; - bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); - bool is_peek = flags & MSG_PEEK; -+ bool rx_more = false; - bool released = true; - bool bpf_strp_enabled; - bool zc_capable; -@@ -2039,12 +2045,12 @@ int tls_sw_recvmsg(struct sock *sk, - goto end; - - /* Process pending decrypted records. It must be non-zero-copy */ -- err = process_rx_list(ctx, msg, &control, 0, len, is_peek); -+ err = process_rx_list(ctx, msg, &control, 0, len, is_peek, &rx_more); - if (err < 0) - goto end; - - copied = err; -- if (len <= copied) -+ if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more) - goto end; - - target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); -@@ -2137,6 +2143,8 @@ int tls_sw_recvmsg(struct sock *sk, - decrypted += chunk; - len -= chunk; - __skb_queue_tail(&ctx->rx_list, skb); -+ if (unlikely(control != TLS_RECORD_TYPE_DATA)) -+ break; - continue; - } - -@@ -2201,10 +2209,10 @@ int tls_sw_recvmsg(struct sock *sk, - /* Drain records from the rx_list & copy if required */ - if (is_peek || is_kvec) - err = process_rx_list(ctx, msg, &control, copied, -- decrypted, is_peek); -+ decrypted, is_peek, NULL); - else - err = process_rx_list(ctx, msg, &control, 0, -- async_copy_bytes, is_peek); -+ async_copy_bytes, is_peek, NULL); - } - - copied += decrypted; -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 70fb14b8bab07..c259d3227a9e2 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -3960,6 +3960,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * - if_idx++; - } - -+ if_start = 0; - wp_idx++; - } - out: -diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py -index d5c389df6045e..4de98b7bbea95 100755 ---- a/scripts/bpf_doc.py -+++ b/scripts/bpf_doc.py -@@ -495,7 +495,7 @@ eBPF programs can have an associated license, passed along with the bytecode - instructions to the kernel when the programs are loaded. The format for that - string is identical to the one in use for kernel modules (Dual licenses, such - as "Dual BSD/GPL", may be used). Some helper functions are only accessible to --programs that are compatible with the GNU Privacy License (GPL). -+programs that are compatible with the GNU General Public License (GNU GPL). - - In order to use such helpers, the eBPF program must be loaded with the correct - license string passed (via **attr**) to the **bpf**\ () system call, and this -diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c -index 2cfca78f0401f..47a4c363227cc 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -740,19 +740,25 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, - const char *filetype) - { - struct cs_dsp *cs_dsp = &dsp->cs_dsp; -+ const char *fwf; - char *s, c; - int ret = 0; - -+ if (dsp->fwf_name) -+ fwf = dsp->fwf_name; -+ else -+ fwf = dsp->cs_dsp.name; -+ - if (system_name && asoc_component_prefix) - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part, -- dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, -+ fwf, wm_adsp_fw[dsp->fw].file, system_name, - asoc_component_prefix, filetype); - else if (system_name) - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part, -- dsp->fwf_name, wm_adsp_fw[dsp->fw].file, system_name, -+ fwf, wm_adsp_fw[dsp->fw].file, system_name, - filetype); - else -- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, dsp->fwf_name, -+ *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, fwf, - wm_adsp_fw[dsp->fw].file, filetype); - - if (*filename == NULL) -@@ -842,29 +848,18 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, - } - - adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n", -- cirrus_dir, dsp->part, dsp->fwf_name, wm_adsp_fw[dsp->fw].file, -- system_name, asoc_component_prefix); -+ cirrus_dir, dsp->part, -+ dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name, -+ wm_adsp_fw[dsp->fw].file, system_name, asoc_component_prefix); - - return -ENOENT; - } - - static int wm_adsp_common_init(struct wm_adsp *dsp) - { -- char *p; -- - INIT_LIST_HEAD(&dsp->compr_list); - INIT_LIST_HEAD(&dsp->buffer_list); - -- if (!dsp->fwf_name) { -- p = devm_kstrdup(dsp->cs_dsp.dev, dsp->cs_dsp.name, GFP_KERNEL); -- if (!p) -- return -ENOMEM; -- -- dsp->fwf_name = p; -- for (; *p != 0; ++p) -- *p = tolower(*p); -- } -- - return 0; - } - -diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c -index bcceebca915ac..484b0e7c2defa 100644 ---- a/sound/soc/sunxi/sun4i-spdif.c -+++ b/sound/soc/sunxi/sun4i-spdif.c -@@ -578,6 +578,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = { - .compatible = "allwinner,sun50i-h6-spdif", - .data = &sun50i_h6_spdif_quirks, - }, -+ { -+ .compatible = "allwinner,sun50i-h616-spdif", -+ /* Essentially the same as the H6, but without RX */ -+ .data = &sun50i_h6_spdif_quirks, -+ }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); -diff --git a/sound/usb/clock.c b/sound/usb/clock.c -index 33db334e65566..a676ad093d189 100644 ---- a/sound/usb/clock.c -+++ b/sound/usb/clock.c -@@ -328,8 +328,16 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, - if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR) - return ret; - err = uac_clock_selector_set_val(chip, entity_id, cur); -- if (err < 0) -+ if (err < 0) { -+ if (pins == 1) { -+ usb_audio_dbg(chip, -+ "%s(): selector returned an error, " -+ "assuming a firmware bug, id %d, ret %d\n", -+ __func__, clock_id, err); -+ return ret; -+ } - return err; -+ } - } - - if (!validate || ret > 0 || !chip->autoclock) -diff --git a/sound/usb/format.c b/sound/usb/format.c -index ab5fed9f55b60..3b45d0ee76938 100644 ---- a/sound/usb/format.c -+++ b/sound/usb/format.c -@@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, - int clock) - { - struct usb_device *dev = chip->dev; -+ struct usb_host_interface *alts; - unsigned int *table; - unsigned int nr_rates; - int i, err; -+ u32 bmControls; - - /* performing the rate verification may lead to unexpected USB bus - * behavior afterwards by some unknown reason. Do this only for the -@@ -481,6 +483,24 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, - if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES)) - return 0; /* don't perform the validation as default */ - -+ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); -+ if (!alts) -+ return 0; -+ -+ if (fp->protocol == UAC_VERSION_3) { -+ struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc( -+ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); -+ bmControls = le32_to_cpu(as->bmControls); -+ } else { -+ struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc( -+ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); -+ bmControls = as->bmControls; -+ } -+ -+ if (!uac_v2v3_control_is_readable(bmControls, -+ UAC2_AS_VAL_ALT_SETTINGS)) -+ return 0; -+ - table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL); - if (!table) - return -ENOMEM; -diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/atm.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/atm.json -deleted file mode 100644 -index f5bc8670a67d1..0000000000000 ---- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/atm.json -+++ /dev/null -@@ -1,94 +0,0 @@ --[ -- { -- "id": "7628", -- "name": "Create ATM with default setting", -- "category": [ -- "qdisc", -- "atm" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root atm", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc atm 1: root refcnt", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "390a", -- "name": "Delete ATM with valid handle", -- "category": [ -- "qdisc", -- "atm" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true", -- "$TC qdisc add dev $DUMMY handle 1: root atm" -- ], -- "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc atm 1: root refcnt", -- "matchCount": "0", -- "teardown": [ -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "32a0", -- "name": "Show ATM class", -- "category": [ -- "qdisc", -- "atm" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root atm", -- "expExitCode": "0", -- "verifyCmd": "$TC class show dev $DUMMY", -- "matchPattern": "class atm 1: parent 1:", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "6310", -- "name": "Dump ATM stats", -- "category": [ -- "qdisc", -- "atm" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root atm", -- "expExitCode": "0", -- "verifyCmd": "$TC -s qdisc show dev $DUMMY", -- "matchPattern": "qdisc atm 1: root refcnt", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- } --] -diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json -deleted file mode 100644 -index 1ab21c83a1223..0000000000000 ---- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json -+++ /dev/null -@@ -1,184 +0,0 @@ --[ -- { -- "id": "3460", -- "name": "Create CBQ with default setting", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "0592", -- "name": "Create CBQ with mpu", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 mpu 1000", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "4684", -- "name": "Create CBQ with valid cell num", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 cell 128", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "4345", -- "name": "Create CBQ with invalid cell num", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 cell 100", -- "expExitCode": "1", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "0", -- "teardown": [ -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "4525", -- "name": "Create CBQ with valid ewma", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 ewma 16", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "6784", -- "name": "Create CBQ with invalid ewma", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 ewma 128", -- "expExitCode": "1", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "0", -- "teardown": [ -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "5468", -- "name": "Delete CBQ with handle", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true", -- "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000" -- ], -- "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "0", -- "teardown": [ -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "492a", -- "name": "Show CBQ class", -- "category": [ -- "qdisc", -- "cbq" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000", -- "expExitCode": "0", -- "verifyCmd": "$TC class show dev $DUMMY", -- "matchPattern": "class cbq 1: root rate 10Kbit \\(bounded,isolated\\) prio no-transmit", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- } --] -diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/dsmark.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/dsmark.json -deleted file mode 100644 -index c030795f9c37d..0000000000000 ---- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/dsmark.json -+++ /dev/null -@@ -1,140 +0,0 @@ --[ -- { -- "id": "6345", -- "name": "Create DSMARK with default setting", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc dsmark 1: root refcnt [0-9]+ indices 0x0400", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "3462", -- "name": "Create DSMARK with default_index setting", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024 default_index 512", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc dsmark 1: root refcnt [0-9]+ indices 0x0400 default_index 0x0200", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "ca95", -- "name": "Create DSMARK with set_tc_index flag", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024 set_tc_index", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc dsmark 1: root refcnt [0-9]+ indices 0x0400 set_tc_index", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "a950", -- "name": "Create DSMARK with multiple setting", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024 default_index 1024 set_tc_index", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc dsmark 1: root refcnt [0-9]+ indices 0x0400 default_index 0x0400 set_tc_index", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "4092", -- "name": "Delete DSMARK with handle", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true", -- "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024 default_index 1024" -- ], -- "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root", -- "expExitCode": "0", -- "verifyCmd": "$TC qdisc show dev $DUMMY", -- "matchPattern": "qdisc dsmark 1: root refcnt [0-9]+ indices 0x0400", -- "matchCount": "0", -- "teardown": [ -- "$IP link del dev $DUMMY type dummy" -- ] -- }, -- { -- "id": "5930", -- "name": "Show DSMARK class", -- "category": [ -- "qdisc", -- "dsmark" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$IP link add dev $DUMMY type dummy || /bin/true" -- ], -- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dsmark indices 1024", -- "expExitCode": "0", -- "verifyCmd": "$TC class show dev $DUMMY", -- "matchPattern": "class dsmark 1:", -- "matchCount": "0", -- "teardown": [ -- "$TC qdisc del dev $DUMMY handle 1: root", -- "$IP link del dev $DUMMY type dummy" -- ] -- } --] diff --git a/patch/kernel/odroidxu4-current/patch-6.1.80-81.patch b/patch/kernel/odroidxu4-current/patch-6.1.80-81.patch deleted file mode 100644 index 59f3b367cc..0000000000 --- a/patch/kernel/odroidxu4-current/patch-6.1.80-81.patch +++ /dev/null @@ -1,14458 +0,0 @@ -diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst -index 894a198970055..bac3789f3e8fa 100644 ---- a/Documentation/x86/boot.rst -+++ b/Documentation/x86/boot.rst -@@ -1416,7 +1416,7 @@ execution context provided by the EFI firmware. - - The function prototype for the handover entry point looks like this:: - -- efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp) -+ efi_stub_entry(void *handle, efi_system_table_t *table, struct boot_params *bp) - - 'handle' is the EFI image handle passed to the boot loader by the EFI - firmware, 'table' is the EFI system table - these are the first two -diff --git a/Documentation/x86/mds.rst b/Documentation/x86/mds.rst -index 5d4330be200f9..e801df0bb3a81 100644 ---- a/Documentation/x86/mds.rst -+++ b/Documentation/x86/mds.rst -@@ -95,6 +95,9 @@ The kernel provides a function to invoke the buffer clearing: - - mds_clear_cpu_buffers() - -+Also macro CLEAR_CPU_BUFFERS can be used in ASM late in exit-to-user path. -+Other than CFLAGS.ZF, this macro doesn't clobber any registers. -+ - The mitigation is invoked on kernel/userspace, hypervisor/guest and C-state - (idle) transitions. - -@@ -138,17 +141,30 @@ Mitigation points - - When transitioning from kernel to user space the CPU buffers are flushed - on affected CPUs when the mitigation is not disabled on the kernel -- command line. The migitation is enabled through the static key -- mds_user_clear. -- -- The mitigation is invoked in prepare_exit_to_usermode() which covers -- all but one of the kernel to user space transitions. The exception -- is when we return from a Non Maskable Interrupt (NMI), which is -- handled directly in do_nmi(). -- -- (The reason that NMI is special is that prepare_exit_to_usermode() can -- enable IRQs. In NMI context, NMIs are blocked, and we don't want to -- enable IRQs with NMIs blocked.) -+ command line. The mitigation is enabled through the feature flag -+ X86_FEATURE_CLEAR_CPU_BUF. -+ -+ The mitigation is invoked just before transitioning to userspace after -+ user registers are restored. This is done to minimize the window in -+ which kernel data could be accessed after VERW e.g. via an NMI after -+ VERW. -+ -+ **Corner case not handled** -+ Interrupts returning to kernel don't clear CPUs buffers since the -+ exit-to-user path is expected to do that anyways. But, there could be -+ a case when an NMI is generated in kernel after the exit-to-user path -+ has cleared the buffers. This case is not handled and NMI returning to -+ kernel don't clear CPU buffers because: -+ -+ 1. It is rare to get an NMI after VERW, but before returning to userspace. -+ 2. For an unprivileged user, there is no known way to make that NMI -+ less rare or target it. -+ 3. It would take a large number of these precisely-timed NMIs to mount -+ an actual attack. There's presumably not enough bandwidth. -+ 4. The NMI in question occurs after a VERW, i.e. when user state is -+ restored and most interesting data is already scrubbed. Whats left -+ is only the data that NMI touches, and that may or may not be of -+ any interest. - - - 2. C-State transition -diff --git a/MAINTAINERS b/MAINTAINERS -index 13d1078808bb5..bbfedb0b20938 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -10051,6 +10051,7 @@ F: drivers/infiniband/ - F: include/rdma/ - F: include/trace/events/ib_mad.h - F: include/trace/events/ib_umad.h -+F: include/trace/misc/rdma.h - F: include/uapi/linux/if_infiniband.h - F: include/uapi/rdma/ - F: samples/bpf/ibumad_kern.c -@@ -11139,6 +11140,12 @@ F: fs/nfs_common/ - F: fs/nfsd/ - F: include/linux/lockd/ - F: include/linux/sunrpc/ -+F: include/trace/events/rpcgss.h -+F: include/trace/events/rpcrdma.h -+F: include/trace/events/sunrpc.h -+F: include/trace/misc/fs.h -+F: include/trace/misc/nfs.h -+F: include/trace/misc/sunrpc.h - F: include/uapi/linux/nfsd/ - F: include/uapi/linux/sunrpc/ - F: net/sunrpc/ -diff --git a/Makefile b/Makefile -index bc4adb561a7cf..e13df565a1cb6 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 80 -+SUBLEVEL = 81 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi -index ec476b1596496..b236d23f80715 100644 ---- a/arch/arm/boot/dts/imx23.dtsi -+++ b/arch/arm/boot/dts/imx23.dtsi -@@ -59,7 +59,7 @@ icoll: interrupt-controller@80000000 { - reg = <0x80000000 0x2000>; - }; - -- dma_apbh: dma-apbh@80004000 { -+ dma_apbh: dma-controller@80004000 { - compatible = "fsl,imx23-dma-apbh"; - reg = <0x80004000 0x2000>; - interrupts = <0 14 20 0 -diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi -index b15df16ecb01a..b81592a613112 100644 ---- a/arch/arm/boot/dts/imx28.dtsi -+++ b/arch/arm/boot/dts/imx28.dtsi -@@ -78,7 +78,7 @@ hsadc: hsadc@80002000 { - status = "disabled"; - }; - -- dma_apbh: dma-apbh@80004000 { -+ dma_apbh: dma-controller@80004000 { - compatible = "fsl,imx28-dma-apbh"; - reg = <0x80004000 0x2000>; - interrupts = <82 83 84 85 -diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi -index ff1e0173b39be..2c6eada01d792 100644 ---- a/arch/arm/boot/dts/imx6qdl.dtsi -+++ b/arch/arm/boot/dts/imx6qdl.dtsi -@@ -150,7 +150,7 @@ soc: soc { - interrupt-parent = <&gpc>; - ranges; - -- dma_apbh: dma-apbh@110000 { -+ dma_apbh: dma-controller@110000 { - compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; - reg = <0x00110000 0x2000>; - interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>, -diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi -index 1f1053a898fbf..67d344ae76b51 100644 ---- a/arch/arm/boot/dts/imx6sx.dtsi -+++ b/arch/arm/boot/dts/imx6sx.dtsi -@@ -209,7 +209,7 @@ gpu: gpu@1800000 { - power-domains = <&pd_pu>; - }; - -- dma_apbh: dma-apbh@1804000 { -+ dma_apbh: dma-controller@1804000 { - compatible = "fsl,imx6sx-dma-apbh", "fsl,imx28-dma-apbh"; - reg = <0x01804000 0x2000>; - interrupts = , -diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi -index 2b5996395701a..aac081b6daaac 100644 ---- a/arch/arm/boot/dts/imx6ul.dtsi -+++ b/arch/arm/boot/dts/imx6ul.dtsi -@@ -164,7 +164,7 @@ intc: interrupt-controller@a01000 { - <0x00a06000 0x2000>; - }; - -- dma_apbh: dma-apbh@1804000 { -+ dma_apbh: dma-controller@1804000 { - compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; - reg = <0x01804000 0x2000>; - interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>, -diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi -index 4b23630fc738d..69aebc691526f 100644 ---- a/arch/arm/boot/dts/imx7s.dtsi -+++ b/arch/arm/boot/dts/imx7s.dtsi -@@ -1267,14 +1267,13 @@ fec1: ethernet@30be0000 { - }; - }; - -- dma_apbh: dma-apbh@33000000 { -+ dma_apbh: dma-controller@33000000 { - compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh"; - reg = <0x33000000 0x2000>; - interrupts = , - , - , - ; -- interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; - #dma-cells = <1>; - dma-channels = <4>; - clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; -diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c -index bac4cabef6073..467ac2f768ac2 100644 ---- a/arch/arm64/crypto/aes-neonbs-glue.c -+++ b/arch/arm64/crypto/aes-neonbs-glue.c -@@ -227,8 +227,19 @@ static int ctr_encrypt(struct skcipher_request *req) - src += blocks * AES_BLOCK_SIZE; - } - if (nbytes && walk.nbytes == walk.total) { -+ u8 buf[AES_BLOCK_SIZE]; -+ u8 *d = dst; -+ -+ if (unlikely(nbytes < AES_BLOCK_SIZE)) -+ src = dst = memcpy(buf + sizeof(buf) - nbytes, -+ src, nbytes); -+ - neon_aes_ctr_encrypt(dst, src, ctx->enc, ctx->key.rounds, - nbytes, walk.iv); -+ -+ if (unlikely(nbytes < AES_BLOCK_SIZE)) -+ memcpy(d, dst, nbytes); -+ - nbytes = 0; - } - kernel_neon_end(); -diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h -index 62c846be2d76a..a75c0772ecfca 100644 ---- a/arch/arm64/include/asm/efi.h -+++ b/arch/arm64/include/asm/efi.h -@@ -103,6 +103,7 @@ static inline void free_screen_info(struct screen_info *si) - } - - #define EFI_ALLOC_ALIGN SZ_64K -+#define EFI_ALLOC_LIMIT ((1UL << 48) - 1) - - /* - * On ARM systems, virtually remapped UEFI runtime services are set up in two -diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c -index 97b026130c71b..1e5f083cdb720 100644 ---- a/arch/powerpc/platforms/pseries/iommu.c -+++ b/arch/powerpc/platforms/pseries/iommu.c -@@ -569,29 +569,6 @@ static void iommu_table_setparms(struct pci_controller *phb, - - struct iommu_table_ops iommu_table_lpar_multi_ops; - --/* -- * iommu_table_setparms_lpar -- * -- * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. -- */ --static void iommu_table_setparms_lpar(struct pci_controller *phb, -- struct device_node *dn, -- struct iommu_table *tbl, -- struct iommu_table_group *table_group, -- const __be32 *dma_window) --{ -- unsigned long offset, size, liobn; -- -- of_parse_dma_window(dn, dma_window, &liobn, &offset, &size); -- -- iommu_table_setparms_common(tbl, phb->bus->number, liobn, offset, size, IOMMU_PAGE_SHIFT_4K, NULL, -- &iommu_table_lpar_multi_ops); -- -- -- table_group->tce32_start = offset; -- table_group->tce32_size = size; --} -- - struct iommu_table_ops iommu_table_pseries_ops = { - .set = tce_build_pSeries, - .clear = tce_free_pSeries, -@@ -719,26 +696,71 @@ struct iommu_table_ops iommu_table_lpar_multi_ops = { - * dynamic 64bit DMA window, walking up the device tree. - */ - static struct device_node *pci_dma_find(struct device_node *dn, -- const __be32 **dma_window) -+ struct dynamic_dma_window_prop *prop) - { -- const __be32 *dw = NULL; -+ const __be32 *default_prop = NULL; -+ const __be32 *ddw_prop = NULL; -+ struct device_node *rdn = NULL; -+ bool default_win = false, ddw_win = false; - - for ( ; dn && PCI_DN(dn); dn = dn->parent) { -- dw = of_get_property(dn, "ibm,dma-window", NULL); -- if (dw) { -- if (dma_window) -- *dma_window = dw; -- return dn; -+ default_prop = of_get_property(dn, "ibm,dma-window", NULL); -+ if (default_prop) { -+ rdn = dn; -+ default_win = true; -+ } -+ ddw_prop = of_get_property(dn, DIRECT64_PROPNAME, NULL); -+ if (ddw_prop) { -+ rdn = dn; -+ ddw_win = true; -+ break; -+ } -+ ddw_prop = of_get_property(dn, DMA64_PROPNAME, NULL); -+ if (ddw_prop) { -+ rdn = dn; -+ ddw_win = true; -+ break; - } -- dw = of_get_property(dn, DIRECT64_PROPNAME, NULL); -- if (dw) -- return dn; -- dw = of_get_property(dn, DMA64_PROPNAME, NULL); -- if (dw) -- return dn; -+ -+ /* At least found default window, which is the case for normal boot */ -+ if (default_win) -+ break; - } - -- return NULL; -+ /* For PCI devices there will always be a DMA window, either on the device -+ * or parent bus -+ */ -+ WARN_ON(!(default_win | ddw_win)); -+ -+ /* caller doesn't want to get DMA window property */ -+ if (!prop) -+ return rdn; -+ -+ /* parse DMA window property. During normal system boot, only default -+ * DMA window is passed in OF. But, for kdump, a dedicated adapter might -+ * have both default and DDW in FDT. In this scenario, DDW takes precedence -+ * over default window. -+ */ -+ if (ddw_win) { -+ struct dynamic_dma_window_prop *p; -+ -+ p = (struct dynamic_dma_window_prop *)ddw_prop; -+ prop->liobn = p->liobn; -+ prop->dma_base = p->dma_base; -+ prop->tce_shift = p->tce_shift; -+ prop->window_shift = p->window_shift; -+ } else if (default_win) { -+ unsigned long offset, size, liobn; -+ -+ of_parse_dma_window(rdn, default_prop, &liobn, &offset, &size); -+ -+ prop->liobn = cpu_to_be32((u32)liobn); -+ prop->dma_base = cpu_to_be64(offset); -+ prop->tce_shift = cpu_to_be32(IOMMU_PAGE_SHIFT_4K); -+ prop->window_shift = cpu_to_be32(order_base_2(size)); -+ } -+ -+ return rdn; - } - - static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) -@@ -746,17 +768,20 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) - struct iommu_table *tbl; - struct device_node *dn, *pdn; - struct pci_dn *ppci; -- const __be32 *dma_window = NULL; -+ struct dynamic_dma_window_prop prop; - - dn = pci_bus_to_OF_node(bus); - - pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n", - dn); - -- pdn = pci_dma_find(dn, &dma_window); -+ pdn = pci_dma_find(dn, &prop); - -- if (dma_window == NULL) -- pr_debug(" no ibm,dma-window property !\n"); -+ /* In PPC architecture, there will always be DMA window on bus or one of the -+ * parent bus. During reboot, there will be ibm,dma-window property to -+ * define DMA window. For kdump, there will at least be default window or DDW -+ * or both. -+ */ - - ppci = PCI_DN(pdn); - -@@ -766,13 +791,24 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) - if (!ppci->table_group) { - ppci->table_group = iommu_pseries_alloc_group(ppci->phb->node); - tbl = ppci->table_group->tables[0]; -- if (dma_window) { -- iommu_table_setparms_lpar(ppci->phb, pdn, tbl, -- ppci->table_group, dma_window); - -- if (!iommu_init_table(tbl, ppci->phb->node, 0, 0)) -- panic("Failed to initialize iommu table"); -- } -+ iommu_table_setparms_common(tbl, ppci->phb->bus->number, -+ be32_to_cpu(prop.liobn), -+ be64_to_cpu(prop.dma_base), -+ 1ULL << be32_to_cpu(prop.window_shift), -+ be32_to_cpu(prop.tce_shift), NULL, -+ &iommu_table_lpar_multi_ops); -+ -+ /* Only for normal boot with default window. Doesn't matter even -+ * if we set these with DDW which is 64bit during kdump, since -+ * these will not be used during kdump. -+ */ -+ ppci->table_group->tce32_start = be64_to_cpu(prop.dma_base); -+ ppci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift); -+ -+ if (!iommu_init_table(tbl, ppci->phb->node, 0, 0)) -+ panic("Failed to initialize iommu table"); -+ - iommu_register_group(ppci->table_group, - pci_domain_nr(bus), 0); - pr_debug(" created table: %p\n", ppci->table_group); -@@ -960,6 +996,12 @@ static void find_existing_ddw_windows_named(const char *name) - continue; - } - -+ /* If at the time of system initialization, there are DDWs in OF, -+ * it means this is during kexec. DDW could be direct or dynamic. -+ * We will just mark DDWs as "dynamic" since this is kdump path, -+ * no need to worry about perforance. ddw_list_new_entry() will -+ * set window->direct = false. -+ */ - window = ddw_list_new_entry(pdn, dma64); - if (!window) { - of_node_put(pdn); -@@ -1525,8 +1567,8 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) - { - struct device_node *pdn, *dn; - struct iommu_table *tbl; -- const __be32 *dma_window = NULL; - struct pci_dn *pci; -+ struct dynamic_dma_window_prop prop; - - pr_debug("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev)); - -@@ -1539,7 +1581,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) - dn = pci_device_to_OF_node(dev); - pr_debug(" node is %pOF\n", dn); - -- pdn = pci_dma_find(dn, &dma_window); -+ pdn = pci_dma_find(dn, &prop); - if (!pdn || !PCI_DN(pdn)) { - printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: " - "no DMA window found for pci dev=%s dn=%pOF\n", -@@ -1552,8 +1594,20 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) - if (!pci->table_group) { - pci->table_group = iommu_pseries_alloc_group(pci->phb->node); - tbl = pci->table_group->tables[0]; -- iommu_table_setparms_lpar(pci->phb, pdn, tbl, -- pci->table_group, dma_window); -+ -+ iommu_table_setparms_common(tbl, pci->phb->bus->number, -+ be32_to_cpu(prop.liobn), -+ be64_to_cpu(prop.dma_base), -+ 1ULL << be32_to_cpu(prop.window_shift), -+ be32_to_cpu(prop.tce_shift), NULL, -+ &iommu_table_lpar_multi_ops); -+ -+ /* Only for normal boot with default window. Doesn't matter even -+ * if we set these with DDW which is 64bit during kdump, since -+ * these will not be used during kdump. -+ */ -+ pci->table_group->tce32_start = be64_to_cpu(prop.dma_base); -+ pci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift); - - iommu_init_table(tbl, pci->phb->node, 0, 0); - iommu_register_group(pci->table_group, -diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h -index d47d87c2d7e3d..dcf1bc9de5841 100644 ---- a/arch/riscv/include/asm/ftrace.h -+++ b/arch/riscv/include/asm/ftrace.h -@@ -25,6 +25,11 @@ - - #define ARCH_SUPPORTS_FTRACE_OPS 1 - #ifndef __ASSEMBLY__ -+ -+extern void *return_address(unsigned int level); -+ -+#define ftrace_return_address(n) return_address(n) -+ - void MCOUNT_NAME(void); - static inline unsigned long ftrace_call_adjust(unsigned long addr) - { -diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h -index 59bb53da473dd..63055c6ad2c25 100644 ---- a/arch/riscv/include/asm/pgtable.h -+++ b/arch/riscv/include/asm/pgtable.h -@@ -79,7 +79,7 @@ - * Define vmemmap for pfn_to_page & page_to_pfn calls. Needed if kernel - * is configured with CONFIG_SPARSEMEM_VMEMMAP enabled. - */ --#define vmemmap ((struct page *)VMEMMAP_START) -+#define vmemmap ((struct page *)VMEMMAP_START - (phys_ram_base >> PAGE_SHIFT)) - - #define PCI_IO_SIZE SZ_16M - #define PCI_IO_END VMEMMAP_START -diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile -index ab333cb792fd9..4c0805d264ca8 100644 ---- a/arch/riscv/kernel/Makefile -+++ b/arch/riscv/kernel/Makefile -@@ -7,6 +7,7 @@ ifdef CONFIG_FTRACE - CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) - CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) - CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) -+CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) - endif - CFLAGS_syscall_table.o += $(call cc-option,-Wno-override-init,) - CFLAGS_compat_syscall_table.o += $(call cc-option,-Wno-override-init,) -@@ -41,6 +42,7 @@ obj-y += irq.o - obj-y += process.o - obj-y += ptrace.o - obj-y += reset.o -+obj-y += return_address.o - obj-y += setup.o - obj-y += signal.o - obj-y += syscall_table.o -diff --git a/arch/riscv/kernel/return_address.c b/arch/riscv/kernel/return_address.c -new file mode 100644 -index 0000000000000..c8115ec8fb304 ---- /dev/null -+++ b/arch/riscv/kernel/return_address.c -@@ -0,0 +1,48 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * This code come from arch/arm64/kernel/return_address.c -+ * -+ * Copyright (C) 2023 SiFive. -+ */ -+ -+#include -+#include -+#include -+ -+struct return_address_data { -+ unsigned int level; -+ void *addr; -+}; -+ -+static bool save_return_addr(void *d, unsigned long pc) -+{ -+ struct return_address_data *data = d; -+ -+ if (!data->level) { -+ data->addr = (void *)pc; -+ return false; -+ } -+ -+ --data->level; -+ -+ return true; -+} -+NOKPROBE_SYMBOL(save_return_addr); -+ -+noinline void *return_address(unsigned int level) -+{ -+ struct return_address_data data; -+ -+ data.level = level + 3; -+ data.addr = NULL; -+ -+ arch_stack_walk(save_return_addr, &data, current, NULL); -+ -+ if (!data.level) -+ return data.addr; -+ else -+ return NULL; -+ -+} -+EXPORT_SYMBOL_GPL(return_address); -+NOKPROBE_SYMBOL(return_address); -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 4c9bfc4be58d4..2f7af61b49b6c 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -1982,6 +1982,23 @@ config EFI_STUB - - See Documentation/admin-guide/efi-stub.rst for more information. - -+config EFI_HANDOVER_PROTOCOL -+ bool "EFI handover protocol (DEPRECATED)" -+ depends on EFI_STUB -+ default y -+ help -+ Select this in order to include support for the deprecated EFI -+ handover protocol, which defines alternative entry points into the -+ EFI stub. This is a practice that has no basis in the UEFI -+ specification, and requires a priori knowledge on the part of the -+ bootloader about Linux/x86 specific ways of passing the command line -+ and initrd, and where in memory those assets may be loaded. -+ -+ If in doubt, say Y. Even though the corresponding support is not -+ present in upstream GRUB or other bootloaders, most distros build -+ GRUB with numerous downstream patches applied, and may rely on the -+ handover protocol as as result. -+ - config EFI_MIXED - bool "EFI mixed-mode support" - depends on EFI_STUB && X86_64 -diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile -index 15b7b403a4bd0..3965b2c9efee0 100644 ---- a/arch/x86/boot/compressed/Makefile -+++ b/arch/x86/boot/compressed/Makefile -@@ -74,6 +74,11 @@ LDFLAGS_vmlinux += -z noexecstack - ifeq ($(CONFIG_LD_IS_BFD),y) - LDFLAGS_vmlinux += $(call ld-option,--no-warn-rwx-segments) - endif -+ifeq ($(CONFIG_EFI_STUB),y) -+# ensure that the static EFI stub library will be pulled in, even if it is -+# never referenced explicitly from the startup code -+LDFLAGS_vmlinux += -u efi_pe_entry -+endif - LDFLAGS_vmlinux += -T - - hostprogs := mkpiggy -@@ -100,7 +105,7 @@ vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o - ifdef CONFIG_X86_64 - vmlinux-objs-y += $(obj)/ident_map_64.o - vmlinux-objs-y += $(obj)/idt_64.o $(obj)/idt_handlers_64.o -- vmlinux-objs-y += $(obj)/mem_encrypt.o -+ vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/mem_encrypt.o - vmlinux-objs-y += $(obj)/pgtable_64.o - vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/sev.o - endif -@@ -108,11 +113,11 @@ endif - vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o - vmlinux-objs-$(CONFIG_INTEL_TDX_GUEST) += $(obj)/tdx.o $(obj)/tdcall.o - --vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o - vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o --efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a -+vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o -+vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a - --$(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE -+$(obj)/vmlinux: $(vmlinux-objs-y) FORCE - $(call if_changed,ld) - - OBJCOPYFLAGS_vmlinux.bin := -R .comment -S -diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c -index 9caf89063e775..55c98fdd67d2b 100644 ---- a/arch/x86/boot/compressed/acpi.c -+++ b/arch/x86/boot/compressed/acpi.c -@@ -30,13 +30,13 @@ __efi_get_rsdp_addr(unsigned long cfg_tbl_pa, unsigned int cfg_tbl_len) - * Search EFI system tables for RSDP. Preferred is ACPI_20_TABLE_GUID to - * ACPI_TABLE_GUID because it has more features. - */ -- rsdp_addr = efi_find_vendor_table(boot_params, cfg_tbl_pa, cfg_tbl_len, -+ rsdp_addr = efi_find_vendor_table(boot_params_ptr, cfg_tbl_pa, cfg_tbl_len, - ACPI_20_TABLE_GUID); - if (rsdp_addr) - return (acpi_physical_address)rsdp_addr; - - /* No ACPI_20_TABLE_GUID found, fallback to ACPI_TABLE_GUID. */ -- rsdp_addr = efi_find_vendor_table(boot_params, cfg_tbl_pa, cfg_tbl_len, -+ rsdp_addr = efi_find_vendor_table(boot_params_ptr, cfg_tbl_pa, cfg_tbl_len, - ACPI_TABLE_GUID); - if (rsdp_addr) - return (acpi_physical_address)rsdp_addr; -@@ -56,15 +56,15 @@ static acpi_physical_address efi_get_rsdp_addr(void) - enum efi_type et; - int ret; - -- et = efi_get_type(boot_params); -+ et = efi_get_type(boot_params_ptr); - if (et == EFI_TYPE_NONE) - return 0; - -- systab_pa = efi_get_system_table(boot_params); -+ systab_pa = efi_get_system_table(boot_params_ptr); - if (!systab_pa) - error("EFI support advertised, but unable to locate system table."); - -- ret = efi_get_conf_table(boot_params, &cfg_tbl_pa, &cfg_tbl_len); -+ ret = efi_get_conf_table(boot_params_ptr, &cfg_tbl_pa, &cfg_tbl_len); - if (ret || !cfg_tbl_pa) - error("EFI config table not found."); - -@@ -156,7 +156,7 @@ acpi_physical_address get_rsdp_addr(void) - { - acpi_physical_address pa; - -- pa = boot_params->acpi_rsdp_addr; -+ pa = boot_params_ptr->acpi_rsdp_addr; - - if (!pa) - pa = efi_get_rsdp_addr(); -@@ -210,7 +210,7 @@ static unsigned long get_acpi_srat_table(void) - rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp(); - if (!rsdp) - rsdp = (struct acpi_table_rsdp *)(long) -- boot_params->acpi_rsdp_addr; -+ boot_params_ptr->acpi_rsdp_addr; - - if (!rsdp) - return 0; -diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c -index f1add5d85da9d..c1bb180973ea2 100644 ---- a/arch/x86/boot/compressed/cmdline.c -+++ b/arch/x86/boot/compressed/cmdline.c -@@ -14,9 +14,9 @@ static inline char rdfs8(addr_t addr) - #include "../cmdline.c" - unsigned long get_cmd_line_ptr(void) - { -- unsigned long cmd_line_ptr = boot_params->hdr.cmd_line_ptr; -+ unsigned long cmd_line_ptr = boot_params_ptr->hdr.cmd_line_ptr; - -- cmd_line_ptr |= (u64)boot_params->ext_cmd_line_ptr << 32; -+ cmd_line_ptr |= (u64)boot_params_ptr->ext_cmd_line_ptr << 32; - - return cmd_line_ptr; - } -diff --git a/arch/x86/boot/compressed/efi_mixed.S b/arch/x86/boot/compressed/efi_mixed.S -new file mode 100644 -index 0000000000000..8232c5b2a9bf5 ---- /dev/null -+++ b/arch/x86/boot/compressed/efi_mixed.S -@@ -0,0 +1,328 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming -+ * -+ * Early support for invoking 32-bit EFI services from a 64-bit kernel. -+ * -+ * Because this thunking occurs before ExitBootServices() we have to -+ * restore the firmware's 32-bit GDT and IDT before we make EFI service -+ * calls. -+ * -+ * On the plus side, we don't have to worry about mangling 64-bit -+ * addresses into 32-bits because we're executing with an identity -+ * mapped pagetable and haven't transitioned to 64-bit virtual addresses -+ * yet. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+ .code64 -+ .text -+/* -+ * When booting in 64-bit mode on 32-bit EFI firmware, startup_64_mixed_mode() -+ * is the first thing that runs after switching to long mode. Depending on -+ * whether the EFI handover protocol or the compat entry point was used to -+ * enter the kernel, it will either branch to the common 64-bit EFI stub -+ * entrypoint efi_stub_entry() directly, or via the 64-bit EFI PE/COFF -+ * entrypoint efi_pe_entry(). In the former case, the bootloader must provide a -+ * struct bootparams pointer as the third argument, so the presence of such a -+ * pointer is used to disambiguate. -+ * -+ * +--------------+ -+ * +------------------+ +------------+ +------>| efi_pe_entry | -+ * | efi32_pe_entry |---->| | | +-----------+--+ -+ * +------------------+ | | +------+----------------+ | -+ * | startup_32 |---->| startup_64_mixed_mode | | -+ * +------------------+ | | +------+----------------+ | -+ * | efi32_stub_entry |---->| | | | -+ * +------------------+ +------------+ | | -+ * V | -+ * +------------+ +----------------+ | -+ * | startup_64 |<----| efi_stub_entry |<--------+ -+ * +------------+ +----------------+ -+ */ -+SYM_FUNC_START(startup_64_mixed_mode) -+ lea efi32_boot_args(%rip), %rdx -+ mov 0(%rdx), %edi -+ mov 4(%rdx), %esi -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL -+ mov 8(%rdx), %edx // saved bootparams pointer -+ test %edx, %edx -+ jnz efi_stub_entry -+#endif -+ /* -+ * efi_pe_entry uses MS calling convention, which requires 32 bytes of -+ * shadow space on the stack even if all arguments are passed in -+ * registers. We also need an additional 8 bytes for the space that -+ * would be occupied by the return address, and this also results in -+ * the correct stack alignment for entry. -+ */ -+ sub $40, %rsp -+ mov %rdi, %rcx // MS calling convention -+ mov %rsi, %rdx -+ jmp efi_pe_entry -+SYM_FUNC_END(startup_64_mixed_mode) -+ -+SYM_FUNC_START(__efi64_thunk) -+ push %rbp -+ push %rbx -+ -+ movl %ds, %eax -+ push %rax -+ movl %es, %eax -+ push %rax -+ movl %ss, %eax -+ push %rax -+ -+ /* Copy args passed on stack */ -+ movq 0x30(%rsp), %rbp -+ movq 0x38(%rsp), %rbx -+ movq 0x40(%rsp), %rax -+ -+ /* -+ * Convert x86-64 ABI params to i386 ABI -+ */ -+ subq $64, %rsp -+ movl %esi, 0x0(%rsp) -+ movl %edx, 0x4(%rsp) -+ movl %ecx, 0x8(%rsp) -+ movl %r8d, 0xc(%rsp) -+ movl %r9d, 0x10(%rsp) -+ movl %ebp, 0x14(%rsp) -+ movl %ebx, 0x18(%rsp) -+ movl %eax, 0x1c(%rsp) -+ -+ leaq 0x20(%rsp), %rbx -+ sgdt (%rbx) -+ sidt 16(%rbx) -+ -+ leaq 1f(%rip), %rbp -+ -+ /* -+ * Switch to IDT and GDT with 32-bit segments. These are the firmware -+ * GDT and IDT that were installed when the kernel started executing. -+ * The pointers were saved by the efi32_entry() routine below. -+ * -+ * Pass the saved DS selector to the 32-bit code, and use far return to -+ * restore the saved CS selector. -+ */ -+ lidt efi32_boot_idt(%rip) -+ lgdt efi32_boot_gdt(%rip) -+ -+ movzwl efi32_boot_ds(%rip), %edx -+ movzwq efi32_boot_cs(%rip), %rax -+ pushq %rax -+ leaq efi_enter32(%rip), %rax -+ pushq %rax -+ lretq -+ -+1: addq $64, %rsp -+ movq %rdi, %rax -+ -+ pop %rbx -+ movl %ebx, %ss -+ pop %rbx -+ movl %ebx, %es -+ pop %rbx -+ movl %ebx, %ds -+ /* Clear out 32-bit selector from FS and GS */ -+ xorl %ebx, %ebx -+ movl %ebx, %fs -+ movl %ebx, %gs -+ -+ /* -+ * Convert 32-bit status code into 64-bit. -+ */ -+ roll $1, %eax -+ rorq $1, %rax -+ -+ pop %rbx -+ pop %rbp -+ RET -+SYM_FUNC_END(__efi64_thunk) -+ -+ .code32 -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL -+SYM_FUNC_START(efi32_stub_entry) -+ call 1f -+1: popl %ecx -+ -+ /* Clear BSS */ -+ xorl %eax, %eax -+ leal (_bss - 1b)(%ecx), %edi -+ leal (_ebss - 1b)(%ecx), %ecx -+ subl %edi, %ecx -+ shrl $2, %ecx -+ cld -+ rep stosl -+ -+ add $0x4, %esp /* Discard return address */ -+ popl %ecx -+ popl %edx -+ popl %esi -+ jmp efi32_entry -+SYM_FUNC_END(efi32_stub_entry) -+#endif -+ -+/* -+ * EFI service pointer must be in %edi. -+ * -+ * The stack should represent the 32-bit calling convention. -+ */ -+SYM_FUNC_START_LOCAL(efi_enter32) -+ /* Load firmware selector into data and stack segment registers */ -+ movl %edx, %ds -+ movl %edx, %es -+ movl %edx, %fs -+ movl %edx, %gs -+ movl %edx, %ss -+ -+ /* Reload pgtables */ -+ movl %cr3, %eax -+ movl %eax, %cr3 -+ -+ /* Disable paging */ -+ movl %cr0, %eax -+ btrl $X86_CR0_PG_BIT, %eax -+ movl %eax, %cr0 -+ -+ /* Disable long mode via EFER */ -+ movl $MSR_EFER, %ecx -+ rdmsr -+ btrl $_EFER_LME, %eax -+ wrmsr -+ -+ call *%edi -+ -+ /* We must preserve return value */ -+ movl %eax, %edi -+ -+ /* -+ * Some firmware will return with interrupts enabled. Be sure to -+ * disable them before we switch GDTs and IDTs. -+ */ -+ cli -+ -+ lidtl 16(%ebx) -+ lgdtl (%ebx) -+ -+ movl %cr4, %eax -+ btsl $(X86_CR4_PAE_BIT), %eax -+ movl %eax, %cr4 -+ -+ movl %cr3, %eax -+ movl %eax, %cr3 -+ -+ movl $MSR_EFER, %ecx -+ rdmsr -+ btsl $_EFER_LME, %eax -+ wrmsr -+ -+ xorl %eax, %eax -+ lldt %ax -+ -+ pushl $__KERNEL_CS -+ pushl %ebp -+ -+ /* Enable paging */ -+ movl %cr0, %eax -+ btsl $X86_CR0_PG_BIT, %eax -+ movl %eax, %cr0 -+ lret -+SYM_FUNC_END(efi_enter32) -+ -+/* -+ * This is the common EFI stub entry point for mixed mode. -+ * -+ * Arguments: %ecx image handle -+ * %edx EFI system table pointer -+ * %esi struct bootparams pointer (or NULL when not using -+ * the EFI handover protocol) -+ * -+ * Since this is the point of no return for ordinary execution, no registers -+ * are considered live except for the function parameters. [Note that the EFI -+ * stub may still exit and return to the firmware using the Exit() EFI boot -+ * service.] -+ */ -+SYM_FUNC_START_LOCAL(efi32_entry) -+ call 1f -+1: pop %ebx -+ -+ /* Save firmware GDTR and code/data selectors */ -+ sgdtl (efi32_boot_gdt - 1b)(%ebx) -+ movw %cs, (efi32_boot_cs - 1b)(%ebx) -+ movw %ds, (efi32_boot_ds - 1b)(%ebx) -+ -+ /* Store firmware IDT descriptor */ -+ sidtl (efi32_boot_idt - 1b)(%ebx) -+ -+ /* Store boot arguments */ -+ leal (efi32_boot_args - 1b)(%ebx), %ebx -+ movl %ecx, 0(%ebx) -+ movl %edx, 4(%ebx) -+ movl %esi, 8(%ebx) -+ movb $0x0, 12(%ebx) // efi_is64 -+ -+ /* Disable paging */ -+ movl %cr0, %eax -+ btrl $X86_CR0_PG_BIT, %eax -+ movl %eax, %cr0 -+ -+ jmp startup_32 -+SYM_FUNC_END(efi32_entry) -+ -+/* -+ * efi_status_t efi32_pe_entry(efi_handle_t image_handle, -+ * efi_system_table_32_t *sys_table) -+ */ -+SYM_FUNC_START(efi32_pe_entry) -+ pushl %ebp -+ movl %esp, %ebp -+ pushl %ebx // save callee-save registers -+ pushl %edi -+ -+ call verify_cpu // check for long mode support -+ testl %eax, %eax -+ movl $0x80000003, %eax // EFI_UNSUPPORTED -+ jnz 2f -+ -+ movl 8(%ebp), %ecx // image_handle -+ movl 12(%ebp), %edx // sys_table -+ xorl %esi, %esi -+ jmp efi32_entry // pass %ecx, %edx, %esi -+ // no other registers remain live -+ -+2: popl %edi // restore callee-save registers -+ popl %ebx -+ leave -+ RET -+SYM_FUNC_END(efi32_pe_entry) -+ -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL -+ .org efi32_stub_entry + 0x200 -+ .code64 -+SYM_FUNC_START_NOALIGN(efi64_stub_entry) -+ jmp efi_handover_entry -+SYM_FUNC_END(efi64_stub_entry) -+#endif -+ -+ .data -+ .balign 8 -+SYM_DATA_START_LOCAL(efi32_boot_gdt) -+ .word 0 -+ .quad 0 -+SYM_DATA_END(efi32_boot_gdt) -+ -+SYM_DATA_START_LOCAL(efi32_boot_idt) -+ .word 0 -+ .quad 0 -+SYM_DATA_END(efi32_boot_idt) -+ -+SYM_DATA_LOCAL(efi32_boot_cs, .word 0) -+SYM_DATA_LOCAL(efi32_boot_ds, .word 0) -+SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) -+SYM_DATA(efi_is64, .byte 1) -diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compressed/efi_thunk_64.S -deleted file mode 100644 -index 67e7edcdfea8f..0000000000000 ---- a/arch/x86/boot/compressed/efi_thunk_64.S -+++ /dev/null -@@ -1,195 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming -- * -- * Early support for invoking 32-bit EFI services from a 64-bit kernel. -- * -- * Because this thunking occurs before ExitBootServices() we have to -- * restore the firmware's 32-bit GDT and IDT before we make EFI service -- * calls. -- * -- * On the plus side, we don't have to worry about mangling 64-bit -- * addresses into 32-bits because we're executing with an identity -- * mapped pagetable and haven't transitioned to 64-bit virtual addresses -- * yet. -- */ -- --#include --#include --#include --#include --#include -- -- .code64 -- .text --SYM_FUNC_START(__efi64_thunk) -- push %rbp -- push %rbx -- -- movl %ds, %eax -- push %rax -- movl %es, %eax -- push %rax -- movl %ss, %eax -- push %rax -- -- /* Copy args passed on stack */ -- movq 0x30(%rsp), %rbp -- movq 0x38(%rsp), %rbx -- movq 0x40(%rsp), %rax -- -- /* -- * Convert x86-64 ABI params to i386 ABI -- */ -- subq $64, %rsp -- movl %esi, 0x0(%rsp) -- movl %edx, 0x4(%rsp) -- movl %ecx, 0x8(%rsp) -- movl %r8d, 0xc(%rsp) -- movl %r9d, 0x10(%rsp) -- movl %ebp, 0x14(%rsp) -- movl %ebx, 0x18(%rsp) -- movl %eax, 0x1c(%rsp) -- -- leaq 0x20(%rsp), %rbx -- sgdt (%rbx) -- -- addq $16, %rbx -- sidt (%rbx) -- -- leaq 1f(%rip), %rbp -- -- /* -- * Switch to IDT and GDT with 32-bit segments. This is the firmware GDT -- * and IDT that was installed when the kernel started executing. The -- * pointers were saved at the EFI stub entry point in head_64.S. -- * -- * Pass the saved DS selector to the 32-bit code, and use far return to -- * restore the saved CS selector. -- */ -- leaq efi32_boot_idt(%rip), %rax -- lidt (%rax) -- leaq efi32_boot_gdt(%rip), %rax -- lgdt (%rax) -- -- movzwl efi32_boot_ds(%rip), %edx -- movzwq efi32_boot_cs(%rip), %rax -- pushq %rax -- leaq efi_enter32(%rip), %rax -- pushq %rax -- lretq -- --1: addq $64, %rsp -- movq %rdi, %rax -- -- pop %rbx -- movl %ebx, %ss -- pop %rbx -- movl %ebx, %es -- pop %rbx -- movl %ebx, %ds -- /* Clear out 32-bit selector from FS and GS */ -- xorl %ebx, %ebx -- movl %ebx, %fs -- movl %ebx, %gs -- -- /* -- * Convert 32-bit status code into 64-bit. -- */ -- roll $1, %eax -- rorq $1, %rax -- -- pop %rbx -- pop %rbp -- RET --SYM_FUNC_END(__efi64_thunk) -- -- .code32 --/* -- * EFI service pointer must be in %edi. -- * -- * The stack should represent the 32-bit calling convention. -- */ --SYM_FUNC_START_LOCAL(efi_enter32) -- /* Load firmware selector into data and stack segment registers */ -- movl %edx, %ds -- movl %edx, %es -- movl %edx, %fs -- movl %edx, %gs -- movl %edx, %ss -- -- /* Reload pgtables */ -- movl %cr3, %eax -- movl %eax, %cr3 -- -- /* Disable paging */ -- movl %cr0, %eax -- btrl $X86_CR0_PG_BIT, %eax -- movl %eax, %cr0 -- -- /* Disable long mode via EFER */ -- movl $MSR_EFER, %ecx -- rdmsr -- btrl $_EFER_LME, %eax -- wrmsr -- -- call *%edi -- -- /* We must preserve return value */ -- movl %eax, %edi -- -- /* -- * Some firmware will return with interrupts enabled. Be sure to -- * disable them before we switch GDTs and IDTs. -- */ -- cli -- -- lidtl (%ebx) -- subl $16, %ebx -- -- lgdtl (%ebx) -- -- movl %cr4, %eax -- btsl $(X86_CR4_PAE_BIT), %eax -- movl %eax, %cr4 -- -- movl %cr3, %eax -- movl %eax, %cr3 -- -- movl $MSR_EFER, %ecx -- rdmsr -- btsl $_EFER_LME, %eax -- wrmsr -- -- xorl %eax, %eax -- lldt %ax -- -- pushl $__KERNEL_CS -- pushl %ebp -- -- /* Enable paging */ -- movl %cr0, %eax -- btsl $X86_CR0_PG_BIT, %eax -- movl %eax, %cr0 -- lret --SYM_FUNC_END(efi_enter32) -- -- .data -- .balign 8 --SYM_DATA_START(efi32_boot_gdt) -- .word 0 -- .quad 0 --SYM_DATA_END(efi32_boot_gdt) -- --SYM_DATA_START(efi32_boot_idt) -- .word 0 -- .quad 0 --SYM_DATA_END(efi32_boot_idt) -- --SYM_DATA_START(efi32_boot_cs) -- .word 0 --SYM_DATA_END(efi32_boot_cs) -- --SYM_DATA_START(efi32_boot_ds) -- .word 0 --SYM_DATA_END(efi32_boot_ds) -diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S -index 3b354eb9516df..1cfe9802a42fe 100644 ---- a/arch/x86/boot/compressed/head_32.S -+++ b/arch/x86/boot/compressed/head_32.S -@@ -84,19 +84,6 @@ SYM_FUNC_START(startup_32) - - #ifdef CONFIG_RELOCATABLE - leal startup_32@GOTOFF(%edx), %ebx -- --#ifdef CONFIG_EFI_STUB --/* -- * If we were loaded via the EFI LoadImage service, startup_32() will be at an -- * offset to the start of the space allocated for the image. efi_pe_entry() will -- * set up image_offset to tell us where the image actually starts, so that we -- * can use the full available buffer. -- * image_offset = startup_32 - image_base -- * Otherwise image_offset will be zero and has no effect on the calculations. -- */ -- subl image_offset@GOTOFF(%edx), %ebx --#endif -- - movl BP_kernel_alignment(%esi), %eax - decl %eax - addl %eax, %ebx -@@ -150,17 +137,6 @@ SYM_FUNC_START(startup_32) - jmp *%eax - SYM_FUNC_END(startup_32) - --#ifdef CONFIG_EFI_STUB --SYM_FUNC_START(efi32_stub_entry) -- add $0x4, %esp -- movl 8(%esp), %esi /* save boot_params pointer */ -- call efi_main -- /* efi_main returns the possibly relocated address of startup_32 */ -- jmp *%eax --SYM_FUNC_END(efi32_stub_entry) --SYM_FUNC_ALIAS(efi_stub_entry, efi32_stub_entry) --#endif -- - .text - SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) - -@@ -179,15 +155,9 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) - */ - /* push arguments for extract_kernel: */ - -- pushl output_len@GOTOFF(%ebx) /* decompressed length, end of relocs */ - pushl %ebp /* output address */ -- pushl input_len@GOTOFF(%ebx) /* input_len */ -- leal input_data@GOTOFF(%ebx), %eax -- pushl %eax /* input_data */ -- leal boot_heap@GOTOFF(%ebx), %eax -- pushl %eax /* heap area */ - pushl %esi /* real mode pointer */ -- call extract_kernel /* returns kernel location in %eax */ -+ call extract_kernel /* returns kernel entry point in %eax */ - addl $24, %esp - - /* -@@ -208,17 +178,11 @@ SYM_DATA_START_LOCAL(gdt) - .quad 0x00cf92000000ffff /* __KERNEL_DS */ - SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) - --#ifdef CONFIG_EFI_STUB --SYM_DATA(image_offset, .long 0) --#endif -- - /* - * Stack and heap for uncompression - */ - .bss - .balign 4 --boot_heap: -- .fill BOOT_HEAP_SIZE, 1, 0 - boot_stack: - .fill BOOT_STACK_SIZE, 1, 0 - boot_stack_end: -diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S -index b4bd6df29116f..0d7aef10b19ad 100644 ---- a/arch/x86/boot/compressed/head_64.S -+++ b/arch/x86/boot/compressed/head_64.S -@@ -118,7 +118,9 @@ SYM_FUNC_START(startup_32) - 1: - - /* Setup Exception handling for SEV-ES */ -+#ifdef CONFIG_AMD_MEM_ENCRYPT - call startup32_load_idt -+#endif - - /* Make sure cpu supports long mode. */ - call verify_cpu -@@ -136,19 +138,6 @@ SYM_FUNC_START(startup_32) - - #ifdef CONFIG_RELOCATABLE - movl %ebp, %ebx -- --#ifdef CONFIG_EFI_STUB --/* -- * If we were loaded via the EFI LoadImage service, startup_32 will be at an -- * offset to the start of the space allocated for the image. efi_pe_entry will -- * set up image_offset to tell us where the image actually starts, so that we -- * can use the full available buffer. -- * image_offset = startup_32 - image_base -- * Otherwise image_offset will be zero and has no effect on the calculations. -- */ -- subl rva(image_offset)(%ebp), %ebx --#endif -- - movl BP_kernel_alignment(%esi), %eax - decl %eax - addl %eax, %ebx -@@ -178,12 +167,13 @@ SYM_FUNC_START(startup_32) - */ - /* - * If SEV is active then set the encryption mask in the page tables. -- * This will insure that when the kernel is copied and decompressed -+ * This will ensure that when the kernel is copied and decompressed - * it will be done so encrypted. - */ -- call get_sev_encryption_bit - xorl %edx, %edx - #ifdef CONFIG_AMD_MEM_ENCRYPT -+ call get_sev_encryption_bit -+ xorl %edx, %edx - testl %eax, %eax - jz 1f - subl $32, %eax /* Encryption bit is always above bit 31 */ -@@ -249,6 +239,11 @@ SYM_FUNC_START(startup_32) - movl $__BOOT_TSS, %eax - ltr %ax - -+#ifdef CONFIG_AMD_MEM_ENCRYPT -+ /* Check if the C-bit position is correct when SEV is active */ -+ call startup32_check_sev_cbit -+#endif -+ - /* - * Setup for the jump to 64bit mode - * -@@ -261,29 +256,11 @@ SYM_FUNC_START(startup_32) - */ - leal rva(startup_64)(%ebp), %eax - #ifdef CONFIG_EFI_MIXED -- movl rva(efi32_boot_args)(%ebp), %edi -- testl %edi, %edi -- jz 1f -- leal rva(efi64_stub_entry)(%ebp), %eax -- movl rva(efi32_boot_args+4)(%ebp), %esi -- movl rva(efi32_boot_args+8)(%ebp), %edx // saved bootparams pointer -- testl %edx, %edx -- jnz 1f -- /* -- * efi_pe_entry uses MS calling convention, which requires 32 bytes of -- * shadow space on the stack even if all arguments are passed in -- * registers. We also need an additional 8 bytes for the space that -- * would be occupied by the return address, and this also results in -- * the correct stack alignment for entry. -- */ -- subl $40, %esp -- leal rva(efi_pe_entry)(%ebp), %eax -- movl %edi, %ecx // MS calling convention -- movl %esi, %edx -+ cmpb $1, rva(efi_is64)(%ebp) -+ je 1f -+ leal rva(startup_64_mixed_mode)(%ebp), %eax - 1: - #endif -- /* Check if the C-bit position is correct when SEV is active */ -- call startup32_check_sev_cbit - - pushl $__KERNEL_CS - pushl %eax -@@ -296,41 +273,6 @@ SYM_FUNC_START(startup_32) - lret - SYM_FUNC_END(startup_32) - --#ifdef CONFIG_EFI_MIXED -- .org 0x190 --SYM_FUNC_START(efi32_stub_entry) -- add $0x4, %esp /* Discard return address */ -- popl %ecx -- popl %edx -- popl %esi -- -- call 1f --1: pop %ebp -- subl $ rva(1b), %ebp -- -- movl %esi, rva(efi32_boot_args+8)(%ebp) --SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL) -- movl %ecx, rva(efi32_boot_args)(%ebp) -- movl %edx, rva(efi32_boot_args+4)(%ebp) -- movb $0, rva(efi_is64)(%ebp) -- -- /* Save firmware GDTR and code/data selectors */ -- sgdtl rva(efi32_boot_gdt)(%ebp) -- movw %cs, rva(efi32_boot_cs)(%ebp) -- movw %ds, rva(efi32_boot_ds)(%ebp) -- -- /* Store firmware IDT descriptor */ -- sidtl rva(efi32_boot_idt)(%ebp) -- -- /* Disable paging */ -- movl %cr0, %eax -- btrl $X86_CR0_PG_BIT, %eax -- movl %eax, %cr0 -- -- jmp startup_32 --SYM_FUNC_END(efi32_stub_entry) --#endif -- - .code64 - .org 0x200 - SYM_CODE_START(startup_64) -@@ -372,20 +314,6 @@ SYM_CODE_START(startup_64) - /* Start with the delta to where the kernel will run at. */ - #ifdef CONFIG_RELOCATABLE - leaq startup_32(%rip) /* - $startup_32 */, %rbp -- --#ifdef CONFIG_EFI_STUB --/* -- * If we were loaded via the EFI LoadImage service, startup_32 will be at an -- * offset to the start of the space allocated for the image. efi_pe_entry will -- * set up image_offset to tell us where the image actually starts, so that we -- * can use the full available buffer. -- * image_offset = startup_32 - image_base -- * Otherwise image_offset will be zero and has no effect on the calculations. -- */ -- movl image_offset(%rip), %eax -- subq %rax, %rbp --#endif -- - movl BP_kernel_alignment(%rsi), %eax - decl %eax - addq %rax, %rbp -@@ -424,10 +352,6 @@ SYM_CODE_START(startup_64) - * For the trampoline, we need the top page table to reside in lower - * memory as we don't have a way to load 64-bit values into CR3 in - * 32-bit mode. -- * -- * We go though the trampoline even if we don't have to: if we're -- * already in a desired paging mode. This way the trampoline code gets -- * tested on every boot. - */ - - /* Make sure we have GDT with 32-bit code segment */ -@@ -442,10 +366,14 @@ SYM_CODE_START(startup_64) - lretq - - .Lon_kernel_cs: -+ /* -+ * RSI holds a pointer to a boot_params structure provided by the -+ * loader, and this needs to be preserved across C function calls. So -+ * move it into a callee saved register. -+ */ -+ movq %rsi, %r15 - -- pushq %rsi - call load_stage1_idt -- popq %rsi - - #ifdef CONFIG_AMD_MEM_ENCRYPT - /* -@@ -456,82 +384,24 @@ SYM_CODE_START(startup_64) - * CPUID instructions being issued, so go ahead and do that now via - * sev_enable(), which will also handle the rest of the SEV-related - * detection/setup to ensure that has been done in advance of any dependent -- * code. -+ * code. Pass the boot_params pointer as the first argument. - */ -- pushq %rsi -- movq %rsi, %rdi /* real mode address */ -+ movq %r15, %rdi - call sev_enable -- popq %rsi - #endif - - /* -- * paging_prepare() sets up the trampoline and checks if we need to -- * enable 5-level paging. -- * -- * paging_prepare() returns a two-quadword structure which lands -- * into RDX:RAX: -- * - Address of the trampoline is returned in RAX. -- * - Non zero RDX means trampoline needs to enable 5-level -- * paging. -- * -- * RSI holds real mode data and needs to be preserved across -- * this function call. -- */ -- pushq %rsi -- movq %rsi, %rdi /* real mode address */ -- call paging_prepare -- popq %rsi -- -- /* Save the trampoline address in RCX */ -- movq %rax, %rcx -- -- /* Set up 32-bit addressable stack */ -- leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp -- -- /* -- * Preserve live 64-bit registers on the stack: this is necessary -- * because the architecture does not guarantee that GPRs will retain -- * their full 64-bit values across a 32-bit mode switch. -- */ -- pushq %rbp -- pushq %rbx -- pushq %rsi -- -- /* -- * Push the 64-bit address of trampoline_return() onto the new stack. -- * It will be used by the trampoline to return to the main code. Due to -- * the 32-bit mode switch, it cannot be kept it in a register either. -- */ -- leaq trampoline_return(%rip), %rdi -- pushq %rdi -- -- /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ -- pushq $__KERNEL32_CS -- leaq TRAMPOLINE_32BIT_CODE_OFFSET(%rax), %rax -- pushq %rax -- lretq --trampoline_return: -- /* Restore live 64-bit registers */ -- popq %rsi -- popq %rbx -- popq %rbp -- -- /* Restore the stack, the 32-bit trampoline uses its own stack */ -- leaq rva(boot_stack_end)(%rbx), %rsp -- -- /* -- * cleanup_trampoline() would restore trampoline memory. -- * -- * RDI is address of the page table to use instead of page table -- * in trampoline memory (if required). -+ * configure_5level_paging() updates the number of paging levels using -+ * a trampoline in 32-bit addressable memory if the current number does -+ * not match the desired number. - * -- * RSI holds real mode data and needs to be preserved across -- * this function call. -+ * Pass the boot_params pointer as the first argument. The second -+ * argument is the relocated address of the page table to use instead -+ * of the page table in trampoline memory (if required). - */ -- pushq %rsi -- leaq rva(top_pgtable)(%rbx), %rdi -- call cleanup_trampoline -- popq %rsi -+ movq %r15, %rdi -+ leaq rva(top_pgtable)(%rbx), %rsi -+ call configure_5level_paging - - /* Zero EFLAGS */ - pushq $0 -@@ -541,7 +411,6 @@ trampoline_return: - * Copy the compressed kernel to the end of our buffer - * where decompression in place becomes safe. - */ -- pushq %rsi - leaq (_bss-8)(%rip), %rsi - leaq rva(_bss-8)(%rbx), %rdi - movl $(_bss - startup_32), %ecx -@@ -549,7 +418,6 @@ trampoline_return: - std - rep movsq - cld -- popq %rsi - - /* - * The GDT may get overwritten either during the copy we just did or -@@ -568,19 +436,6 @@ trampoline_return: - jmp *%rax - SYM_CODE_END(startup_64) - --#ifdef CONFIG_EFI_STUB -- .org 0x390 --SYM_FUNC_START(efi64_stub_entry) -- and $~0xf, %rsp /* realign the stack */ -- movq %rdx, %rbx /* save boot_params pointer */ -- call efi_main -- movq %rbx,%rsi -- leaq rva(startup_64)(%rax), %rax -- jmp *%rax --SYM_FUNC_END(efi64_stub_entry) --SYM_FUNC_ALIAS(efi_stub_entry, efi64_stub_entry) --#endif -- - .text - SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) - -@@ -594,125 +449,122 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) - shrq $3, %rcx - rep stosq - -- pushq %rsi - call load_stage2_idt - - /* Pass boot_params to initialize_identity_maps() */ -- movq (%rsp), %rdi -+ movq %r15, %rdi - call initialize_identity_maps -- popq %rsi - - /* - * Do the extraction, and jump to the new kernel.. - */ -- pushq %rsi /* Save the real mode argument */ -- movq %rsi, %rdi /* real mode address */ -- leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ -- leaq input_data(%rip), %rdx /* input_data */ -- movl input_len(%rip), %ecx /* input_len */ -- movq %rbp, %r8 /* output target address */ -- movl output_len(%rip), %r9d /* decompressed length, end of relocs */ -- call extract_kernel /* returns kernel location in %rax */ -- popq %rsi -+ /* pass struct boot_params pointer and output target address */ -+ movq %r15, %rdi -+ movq %rbp, %rsi -+ call extract_kernel /* returns kernel entry point in %rax */ - - /* - * Jump to the decompressed kernel. - */ -+ movq %r15, %rsi - jmp *%rax - SYM_FUNC_END(.Lrelocated) - -- .code32 - /* -- * This is the 32-bit trampoline that will be copied over to low memory. -+ * This is the 32-bit trampoline that will be copied over to low memory. It -+ * will be called using the ordinary 64-bit calling convention from code -+ * running in 64-bit mode. - * - * Return address is at the top of the stack (might be above 4G). -- * ECX contains the base address of the trampoline memory. -- * Non zero RDX means trampoline needs to enable 5-level paging. -+ * The first argument (EDI) contains the address of the temporary PGD level -+ * page table in 32-bit addressable memory which will be programmed into -+ * register CR3. - */ -+ .section ".rodata", "a", @progbits - SYM_CODE_START(trampoline_32bit_src) -- /* Set up data and stack segments */ -- movl $__KERNEL_DS, %eax -- movl %eax, %ds -- movl %eax, %ss -+ /* -+ * Preserve callee save 64-bit registers on the stack: this is -+ * necessary because the architecture does not guarantee that GPRs will -+ * retain their full 64-bit values across a 32-bit mode switch. -+ */ -+ pushq %r15 -+ pushq %r14 -+ pushq %r13 -+ pushq %r12 -+ pushq %rbp -+ pushq %rbx -+ -+ /* Preserve top half of RSP in a legacy mode GPR to avoid truncation */ -+ movq %rsp, %rbx -+ shrq $32, %rbx - -+ /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ -+ pushq $__KERNEL32_CS -+ leaq 0f(%rip), %rax -+ pushq %rax -+ lretq -+ -+ /* -+ * The 32-bit code below will do a far jump back to long mode and end -+ * up here after reconfiguring the number of paging levels. First, the -+ * stack pointer needs to be restored to its full 64-bit value before -+ * the callee save register contents can be popped from the stack. -+ */ -+.Lret: -+ shlq $32, %rbx -+ orq %rbx, %rsp -+ -+ /* Restore the preserved 64-bit registers */ -+ popq %rbx -+ popq %rbp -+ popq %r12 -+ popq %r13 -+ popq %r14 -+ popq %r15 -+ retq -+ -+ .code32 -+0: - /* Disable paging */ - movl %cr0, %eax - btrl $X86_CR0_PG_BIT, %eax - movl %eax, %cr0 - -- /* Check what paging mode we want to be in after the trampoline */ -- testl %edx, %edx -- jz 1f -- -- /* We want 5-level paging: don't touch CR3 if it already points to 5-level page tables */ -- movl %cr4, %eax -- testl $X86_CR4_LA57, %eax -- jnz 3f -- jmp 2f --1: -- /* We want 4-level paging: don't touch CR3 if it already points to 4-level page tables */ -- movl %cr4, %eax -- testl $X86_CR4_LA57, %eax -- jz 3f --2: - /* Point CR3 to the trampoline's new top level page table */ -- leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax -- movl %eax, %cr3 --3: -+ movl %edi, %cr3 -+ - /* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */ -- pushl %ecx -- pushl %edx - movl $MSR_EFER, %ecx - rdmsr - btsl $_EFER_LME, %eax - /* Avoid writing EFER if no change was made (for TDX guest) */ - jc 1f - wrmsr --1: popl %edx -- popl %ecx -- --#ifdef CONFIG_X86_MCE -- /* -- * Preserve CR4.MCE if the kernel will enable #MC support. -- * Clearing MCE may fault in some environments (that also force #MC -- * support). Any machine check that occurs before #MC support is fully -- * configured will crash the system regardless of the CR4.MCE value set -- * here. -- */ -- movl %cr4, %eax -- andl $X86_CR4_MCE, %eax --#else -- movl $0, %eax --#endif -- -- /* Enable PAE and LA57 (if required) paging modes */ -- orl $X86_CR4_PAE, %eax -- testl %edx, %edx -- jz 1f -- orl $X86_CR4_LA57, %eax - 1: -+ /* Toggle CR4.LA57 */ -+ movl %cr4, %eax -+ btcl $X86_CR4_LA57_BIT, %eax - movl %eax, %cr4 - -- /* Calculate address of paging_enabled() once we are executing in the trampoline */ -- leal .Lpaging_enabled - trampoline_32bit_src + TRAMPOLINE_32BIT_CODE_OFFSET(%ecx), %eax -- -- /* Prepare the stack for far return to Long Mode */ -- pushl $__KERNEL_CS -- pushl %eax -- - /* Enable paging again. */ - movl %cr0, %eax - btsl $X86_CR0_PG_BIT, %eax - movl %eax, %cr0 - -- lret -+ /* -+ * Return to the 64-bit calling code using LJMP rather than LRET, to -+ * avoid the need for a 32-bit addressable stack. The destination -+ * address will be adjusted after the template code is copied into a -+ * 32-bit addressable buffer. -+ */ -+.Ljmp: ljmpl $__KERNEL_CS, $(.Lret - trampoline_32bit_src) - SYM_CODE_END(trampoline_32bit_src) - -- .code64 --SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled) -- /* Return from the trampoline */ -- retq --SYM_FUNC_END(.Lpaging_enabled) -+/* -+ * This symbol is placed right after trampoline_32bit_src() so its address can -+ * be used to infer the size of the trampoline code. -+ */ -+SYM_DATA(trampoline_ljmp_imm_offset, .word .Ljmp + 1 - trampoline_32bit_src) - - /* - * The trampoline code has a size limit. -@@ -721,7 +573,7 @@ SYM_FUNC_END(.Lpaging_enabled) - */ - .org trampoline_32bit_src + TRAMPOLINE_32BIT_CODE_SIZE - -- .code32 -+ .text - SYM_FUNC_START_LOCAL_NOALIGN(.Lno_longmode) - /* This isn't an x86-64 CPU, so hang intentionally, we cannot continue */ - 1: -@@ -729,6 +581,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lno_longmode) - jmp 1b - SYM_FUNC_END(.Lno_longmode) - -+ .globl verify_cpu - #include "../../kernel/verify_cpu.S" - - .data -@@ -760,249 +613,11 @@ SYM_DATA_START(boot_idt) - .endr - SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end) - --#ifdef CONFIG_AMD_MEM_ENCRYPT --SYM_DATA_START(boot32_idt_desc) -- .word boot32_idt_end - boot32_idt - 1 -- .long 0 --SYM_DATA_END(boot32_idt_desc) -- .balign 8 --SYM_DATA_START(boot32_idt) -- .rept 32 -- .quad 0 -- .endr --SYM_DATA_END_LABEL(boot32_idt, SYM_L_GLOBAL, boot32_idt_end) --#endif -- --#ifdef CONFIG_EFI_STUB --SYM_DATA(image_offset, .long 0) --#endif --#ifdef CONFIG_EFI_MIXED --SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) --SYM_DATA(efi_is64, .byte 1) -- --#define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime) --#define BS32_handle_protocol 88 // offsetof(efi_boot_services_32_t, handle_protocol) --#define LI32_image_base 32 // offsetof(efi_loaded_image_32_t, image_base) -- -- __HEAD -- .code32 --SYM_FUNC_START(efi32_pe_entry) --/* -- * efi_status_t efi32_pe_entry(efi_handle_t image_handle, -- * efi_system_table_32_t *sys_table) -- */ -- -- pushl %ebp -- movl %esp, %ebp -- pushl %eax // dummy push to allocate loaded_image -- -- pushl %ebx // save callee-save registers -- pushl %edi -- -- call verify_cpu // check for long mode support -- testl %eax, %eax -- movl $0x80000003, %eax // EFI_UNSUPPORTED -- jnz 2f -- -- call 1f --1: pop %ebx -- subl $ rva(1b), %ebx -- -- /* Get the loaded image protocol pointer from the image handle */ -- leal -4(%ebp), %eax -- pushl %eax // &loaded_image -- leal rva(loaded_image_proto)(%ebx), %eax -- pushl %eax // pass the GUID address -- pushl 8(%ebp) // pass the image handle -- -- /* -- * Note the alignment of the stack frame. -- * sys_table -- * handle <-- 16-byte aligned on entry by ABI -- * return address -- * frame pointer -- * loaded_image <-- local variable -- * saved %ebx <-- 16-byte aligned here -- * saved %edi -- * &loaded_image -- * &loaded_image_proto -- * handle <-- 16-byte aligned for call to handle_protocol -- */ -- -- movl 12(%ebp), %eax // sys_table -- movl ST32_boottime(%eax), %eax // sys_table->boottime -- call *BS32_handle_protocol(%eax) // sys_table->boottime->handle_protocol -- addl $12, %esp // restore argument space -- testl %eax, %eax -- jnz 2f -- -- movl 8(%ebp), %ecx // image_handle -- movl 12(%ebp), %edx // sys_table -- movl -4(%ebp), %esi // loaded_image -- movl LI32_image_base(%esi), %esi // loaded_image->image_base -- movl %ebx, %ebp // startup_32 for efi32_pe_stub_entry -- /* -- * We need to set the image_offset variable here since startup_32() will -- * use it before we get to the 64-bit efi_pe_entry() in C code. -- */ -- subl %esi, %ebx -- movl %ebx, rva(image_offset)(%ebp) // save image_offset -- jmp efi32_pe_stub_entry -- --2: popl %edi // restore callee-save registers -- popl %ebx -- leave -- RET --SYM_FUNC_END(efi32_pe_entry) -- -- .section ".rodata" -- /* EFI loaded image protocol GUID */ -- .balign 4 --SYM_DATA_START_LOCAL(loaded_image_proto) -- .long 0x5b1b31a1 -- .word 0x9562, 0x11d2 -- .byte 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b --SYM_DATA_END(loaded_image_proto) --#endif -- --#ifdef CONFIG_AMD_MEM_ENCRYPT -- __HEAD -- .code32 --/* -- * Write an IDT entry into boot32_idt -- * -- * Parameters: -- * -- * %eax: Handler address -- * %edx: Vector number -- * -- * Physical offset is expected in %ebp -- */ --SYM_FUNC_START(startup32_set_idt_entry) -- push %ebx -- push %ecx -- -- /* IDT entry address to %ebx */ -- leal rva(boot32_idt)(%ebp), %ebx -- shl $3, %edx -- addl %edx, %ebx -- -- /* Build IDT entry, lower 4 bytes */ -- movl %eax, %edx -- andl $0x0000ffff, %edx # Target code segment offset [15:0] -- movl $__KERNEL32_CS, %ecx # Target code segment selector -- shl $16, %ecx -- orl %ecx, %edx -- -- /* Store lower 4 bytes to IDT */ -- movl %edx, (%ebx) -- -- /* Build IDT entry, upper 4 bytes */ -- movl %eax, %edx -- andl $0xffff0000, %edx # Target code segment offset [31:16] -- orl $0x00008e00, %edx # Present, Type 32-bit Interrupt Gate -- -- /* Store upper 4 bytes to IDT */ -- movl %edx, 4(%ebx) -- -- pop %ecx -- pop %ebx -- RET --SYM_FUNC_END(startup32_set_idt_entry) --#endif -- --SYM_FUNC_START(startup32_load_idt) --#ifdef CONFIG_AMD_MEM_ENCRYPT -- /* #VC handler */ -- leal rva(startup32_vc_handler)(%ebp), %eax -- movl $X86_TRAP_VC, %edx -- call startup32_set_idt_entry -- -- /* Load IDT */ -- leal rva(boot32_idt)(%ebp), %eax -- movl %eax, rva(boot32_idt_desc+2)(%ebp) -- lidt rva(boot32_idt_desc)(%ebp) --#endif -- RET --SYM_FUNC_END(startup32_load_idt) -- --/* -- * Check for the correct C-bit position when the startup_32 boot-path is used. -- * -- * The check makes use of the fact that all memory is encrypted when paging is -- * disabled. The function creates 64 bits of random data using the RDRAND -- * instruction. RDRAND is mandatory for SEV guests, so always available. If the -- * hypervisor violates that the kernel will crash right here. -- * -- * The 64 bits of random data are stored to a memory location and at the same -- * time kept in the %eax and %ebx registers. Since encryption is always active -- * when paging is off the random data will be stored encrypted in main memory. -- * -- * Then paging is enabled. When the C-bit position is correct all memory is -- * still mapped encrypted and comparing the register values with memory will -- * succeed. An incorrect C-bit position will map all memory unencrypted, so that -- * the compare will use the encrypted random data and fail. -- */ --SYM_FUNC_START(startup32_check_sev_cbit) --#ifdef CONFIG_AMD_MEM_ENCRYPT -- pushl %eax -- pushl %ebx -- pushl %ecx -- pushl %edx -- -- /* Check for non-zero sev_status */ -- movl rva(sev_status)(%ebp), %eax -- testl %eax, %eax -- jz 4f -- -- /* -- * Get two 32-bit random values - Don't bail out if RDRAND fails -- * because it is better to prevent forward progress if no random value -- * can be gathered. -- */ --1: rdrand %eax -- jnc 1b --2: rdrand %ebx -- jnc 2b -- -- /* Store to memory and keep it in the registers */ -- movl %eax, rva(sev_check_data)(%ebp) -- movl %ebx, rva(sev_check_data+4)(%ebp) -- -- /* Enable paging to see if encryption is active */ -- movl %cr0, %edx /* Backup %cr0 in %edx */ -- movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */ -- movl %ecx, %cr0 -- -- cmpl %eax, rva(sev_check_data)(%ebp) -- jne 3f -- cmpl %ebx, rva(sev_check_data+4)(%ebp) -- jne 3f -- -- movl %edx, %cr0 /* Restore previous %cr0 */ -- -- jmp 4f -- --3: /* Check failed - hlt the machine */ -- hlt -- jmp 3b -- --4: -- popl %edx -- popl %ecx -- popl %ebx -- popl %eax --#endif -- RET --SYM_FUNC_END(startup32_check_sev_cbit) -- - /* - * Stack and heap for uncompression - */ - .bss - .balign 4 --SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0) -- - SYM_DATA_START_LOCAL(boot_stack) - .fill BOOT_STACK_SIZE, 1, 0 - .balign 16 -diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c -index d34222816c9f5..b8c42339bc355 100644 ---- a/arch/x86/boot/compressed/ident_map_64.c -+++ b/arch/x86/boot/compressed/ident_map_64.c -@@ -167,8 +167,9 @@ void initialize_identity_maps(void *rmode) - * or does not touch all the pages covering them. - */ - kernel_add_identity_map((unsigned long)_head, (unsigned long)_end); -- boot_params = rmode; -- kernel_add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); -+ boot_params_ptr = rmode; -+ kernel_add_identity_map((unsigned long)boot_params_ptr, -+ (unsigned long)(boot_params_ptr + 1)); - cmdline = get_cmd_line_ptr(); - kernel_add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); - -@@ -176,7 +177,7 @@ void initialize_identity_maps(void *rmode) - * Also map the setup_data entries passed via boot_params in case they - * need to be accessed by uncompressed kernel via the identity mapping. - */ -- sd = (struct setup_data *)boot_params->hdr.setup_data; -+ sd = (struct setup_data *)boot_params_ptr->hdr.setup_data; - while (sd) { - unsigned long sd_addr = (unsigned long)sd; - -diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c -index e476bcbd9b422..9794d9174795d 100644 ---- a/arch/x86/boot/compressed/kaslr.c -+++ b/arch/x86/boot/compressed/kaslr.c -@@ -63,7 +63,7 @@ static unsigned long get_boot_seed(void) - unsigned long hash = 0; - - hash = rotate_xor(hash, build_str, sizeof(build_str)); -- hash = rotate_xor(hash, boot_params, sizeof(*boot_params)); -+ hash = rotate_xor(hash, boot_params_ptr, sizeof(*boot_params_ptr)); - - return hash; - } -@@ -383,7 +383,7 @@ static void handle_mem_options(void) - static void mem_avoid_init(unsigned long input, unsigned long input_size, - unsigned long output) - { -- unsigned long init_size = boot_params->hdr.init_size; -+ unsigned long init_size = boot_params_ptr->hdr.init_size; - u64 initrd_start, initrd_size; - unsigned long cmd_line, cmd_line_size; - -@@ -395,10 +395,10 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, - mem_avoid[MEM_AVOID_ZO_RANGE].size = (output + init_size) - input; - - /* Avoid initrd. */ -- initrd_start = (u64)boot_params->ext_ramdisk_image << 32; -- initrd_start |= boot_params->hdr.ramdisk_image; -- initrd_size = (u64)boot_params->ext_ramdisk_size << 32; -- initrd_size |= boot_params->hdr.ramdisk_size; -+ initrd_start = (u64)boot_params_ptr->ext_ramdisk_image << 32; -+ initrd_start |= boot_params_ptr->hdr.ramdisk_image; -+ initrd_size = (u64)boot_params_ptr->ext_ramdisk_size << 32; -+ initrd_size |= boot_params_ptr->hdr.ramdisk_size; - mem_avoid[MEM_AVOID_INITRD].start = initrd_start; - mem_avoid[MEM_AVOID_INITRD].size = initrd_size; - /* No need to set mapping for initrd, it will be handled in VO. */ -@@ -413,8 +413,8 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, - } - - /* Avoid boot parameters. */ -- mem_avoid[MEM_AVOID_BOOTPARAMS].start = (unsigned long)boot_params; -- mem_avoid[MEM_AVOID_BOOTPARAMS].size = sizeof(*boot_params); -+ mem_avoid[MEM_AVOID_BOOTPARAMS].start = (unsigned long)boot_params_ptr; -+ mem_avoid[MEM_AVOID_BOOTPARAMS].size = sizeof(*boot_params_ptr); - - /* We don't need to set a mapping for setup_data. */ - -@@ -447,7 +447,7 @@ static bool mem_avoid_overlap(struct mem_vector *img, - } - - /* Avoid all entries in the setup_data linked list. */ -- ptr = (struct setup_data *)(unsigned long)boot_params->hdr.setup_data; -+ ptr = (struct setup_data *)(unsigned long)boot_params_ptr->hdr.setup_data; - while (ptr) { - struct mem_vector avoid; - -@@ -679,7 +679,7 @@ static bool process_mem_region(struct mem_vector *region, - static bool - process_efi_entries(unsigned long minimum, unsigned long image_size) - { -- struct efi_info *e = &boot_params->efi_info; -+ struct efi_info *e = &boot_params_ptr->efi_info; - bool efi_mirror_found = false; - struct mem_vector region; - efi_memory_desc_t *md; -@@ -761,8 +761,8 @@ static void process_e820_entries(unsigned long minimum, - struct boot_e820_entry *entry; - - /* Verify potential e820 positions, appending to slots list. */ -- for (i = 0; i < boot_params->e820_entries; i++) { -- entry = &boot_params->e820_table[i]; -+ for (i = 0; i < boot_params_ptr->e820_entries; i++) { -+ entry = &boot_params_ptr->e820_table[i]; - /* Skip non-RAM entries. */ - if (entry->type != E820_TYPE_RAM) - continue; -@@ -836,7 +836,7 @@ void choose_random_location(unsigned long input, - return; - } - -- boot_params->hdr.loadflags |= KASLR_FLAG; -+ boot_params_ptr->hdr.loadflags |= KASLR_FLAG; - - if (IS_ENABLED(CONFIG_X86_32)) - mem_limit = KERNEL_IMAGE_SIZE; -diff --git a/arch/x86/boot/compressed/mem_encrypt.S b/arch/x86/boot/compressed/mem_encrypt.S -index a73e4d783cae2..32f7cc8a86254 100644 ---- a/arch/x86/boot/compressed/mem_encrypt.S -+++ b/arch/x86/boot/compressed/mem_encrypt.S -@@ -12,16 +12,13 @@ - #include - #include - #include -+#include -+#include - - .text - .code32 - SYM_FUNC_START(get_sev_encryption_bit) -- xor %eax, %eax -- --#ifdef CONFIG_AMD_MEM_ENCRYPT - push %ebx -- push %ecx -- push %edx - - movl $0x80000000, %eax /* CPUID to check the highest leaf */ - cpuid -@@ -52,12 +49,7 @@ SYM_FUNC_START(get_sev_encryption_bit) - xor %eax, %eax - - .Lsev_exit: -- pop %edx -- pop %ecx - pop %ebx -- --#endif /* CONFIG_AMD_MEM_ENCRYPT */ -- - RET - SYM_FUNC_END(get_sev_encryption_bit) - -@@ -98,7 +90,7 @@ SYM_CODE_START_LOCAL(sev_es_req_cpuid) - jmp 1b - SYM_CODE_END(sev_es_req_cpuid) - --SYM_CODE_START(startup32_vc_handler) -+SYM_CODE_START_LOCAL(startup32_vc_handler) - pushl %eax - pushl %ebx - pushl %ecx -@@ -184,15 +176,149 @@ SYM_CODE_START(startup32_vc_handler) - jmp .Lfail - SYM_CODE_END(startup32_vc_handler) - -+/* -+ * Write an IDT entry into boot32_idt -+ * -+ * Parameters: -+ * -+ * %eax: Handler address -+ * %edx: Vector number -+ * %ecx: IDT address -+ */ -+SYM_FUNC_START_LOCAL(startup32_set_idt_entry) -+ /* IDT entry address to %ecx */ -+ leal (%ecx, %edx, 8), %ecx -+ -+ /* Build IDT entry, lower 4 bytes */ -+ movl %eax, %edx -+ andl $0x0000ffff, %edx # Target code segment offset [15:0] -+ orl $(__KERNEL32_CS << 16), %edx # Target code segment selector -+ -+ /* Store lower 4 bytes to IDT */ -+ movl %edx, (%ecx) -+ -+ /* Build IDT entry, upper 4 bytes */ -+ movl %eax, %edx -+ andl $0xffff0000, %edx # Target code segment offset [31:16] -+ orl $0x00008e00, %edx # Present, Type 32-bit Interrupt Gate -+ -+ /* Store upper 4 bytes to IDT */ -+ movl %edx, 4(%ecx) -+ -+ RET -+SYM_FUNC_END(startup32_set_idt_entry) -+ -+SYM_FUNC_START(startup32_load_idt) -+ push %ebp -+ push %ebx -+ -+ call 1f -+1: pop %ebp -+ -+ leal (boot32_idt - 1b)(%ebp), %ebx -+ -+ /* #VC handler */ -+ leal (startup32_vc_handler - 1b)(%ebp), %eax -+ movl $X86_TRAP_VC, %edx -+ movl %ebx, %ecx -+ call startup32_set_idt_entry -+ -+ /* Load IDT */ -+ leal (boot32_idt_desc - 1b)(%ebp), %ecx -+ movl %ebx, 2(%ecx) -+ lidt (%ecx) -+ -+ pop %ebx -+ pop %ebp -+ RET -+SYM_FUNC_END(startup32_load_idt) -+ -+/* -+ * Check for the correct C-bit position when the startup_32 boot-path is used. -+ * -+ * The check makes use of the fact that all memory is encrypted when paging is -+ * disabled. The function creates 64 bits of random data using the RDRAND -+ * instruction. RDRAND is mandatory for SEV guests, so always available. If the -+ * hypervisor violates that the kernel will crash right here. -+ * -+ * The 64 bits of random data are stored to a memory location and at the same -+ * time kept in the %eax and %ebx registers. Since encryption is always active -+ * when paging is off the random data will be stored encrypted in main memory. -+ * -+ * Then paging is enabled. When the C-bit position is correct all memory is -+ * still mapped encrypted and comparing the register values with memory will -+ * succeed. An incorrect C-bit position will map all memory unencrypted, so that -+ * the compare will use the encrypted random data and fail. -+ */ -+SYM_FUNC_START(startup32_check_sev_cbit) -+ pushl %ebx -+ pushl %ebp -+ -+ call 0f -+0: popl %ebp -+ -+ /* Check for non-zero sev_status */ -+ movl (sev_status - 0b)(%ebp), %eax -+ testl %eax, %eax -+ jz 4f -+ -+ /* -+ * Get two 32-bit random values - Don't bail out if RDRAND fails -+ * because it is better to prevent forward progress if no random value -+ * can be gathered. -+ */ -+1: rdrand %eax -+ jnc 1b -+2: rdrand %ebx -+ jnc 2b -+ -+ /* Store to memory and keep it in the registers */ -+ leal (sev_check_data - 0b)(%ebp), %ebp -+ movl %eax, 0(%ebp) -+ movl %ebx, 4(%ebp) -+ -+ /* Enable paging to see if encryption is active */ -+ movl %cr0, %edx /* Backup %cr0 in %edx */ -+ movl $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */ -+ movl %ecx, %cr0 -+ -+ cmpl %eax, 0(%ebp) -+ jne 3f -+ cmpl %ebx, 4(%ebp) -+ jne 3f -+ -+ movl %edx, %cr0 /* Restore previous %cr0 */ -+ -+ jmp 4f -+ -+3: /* Check failed - hlt the machine */ -+ hlt -+ jmp 3b -+ -+4: -+ popl %ebp -+ popl %ebx -+ RET -+SYM_FUNC_END(startup32_check_sev_cbit) -+ - .code64 - - #include "../../kernel/sev_verify_cbit.S" - - .data - --#ifdef CONFIG_AMD_MEM_ENCRYPT - .balign 8 - SYM_DATA(sme_me_mask, .quad 0) - SYM_DATA(sev_status, .quad 0) - SYM_DATA(sev_check_data, .quad 0) --#endif -+ -+SYM_DATA_START_LOCAL(boot32_idt) -+ .rept 32 -+ .quad 0 -+ .endr -+SYM_DATA_END(boot32_idt) -+ -+SYM_DATA_START_LOCAL(boot32_idt_desc) -+ .word . - boot32_idt - 1 -+ .long 0 -+SYM_DATA_END(boot32_idt_desc) -diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c -index cf690d8712f4e..8ae7893d712ff 100644 ---- a/arch/x86/boot/compressed/misc.c -+++ b/arch/x86/boot/compressed/misc.c -@@ -46,7 +46,7 @@ void *memmove(void *dest, const void *src, size_t n); - /* - * This is set up by the setup-routine at boot-time - */ --struct boot_params *boot_params; -+struct boot_params *boot_params_ptr; - - struct port_io_ops pio_ops; - -@@ -132,8 +132,8 @@ void __putstr(const char *s) - if (lines == 0 || cols == 0) - return; - -- x = boot_params->screen_info.orig_x; -- y = boot_params->screen_info.orig_y; -+ x = boot_params_ptr->screen_info.orig_x; -+ y = boot_params_ptr->screen_info.orig_y; - - while ((c = *s++) != '\0') { - if (c == '\n') { -@@ -154,8 +154,8 @@ void __putstr(const char *s) - } - } - -- boot_params->screen_info.orig_x = x; -- boot_params->screen_info.orig_y = y; -+ boot_params_ptr->screen_info.orig_x = x; -+ boot_params_ptr->screen_info.orig_y = y; - - pos = (x + cols * y) * 2; /* Update cursor position */ - outb(14, vidport); -@@ -277,7 +277,7 @@ static inline void handle_relocations(void *output, unsigned long output_len, - { } - #endif - --static void parse_elf(void *output) -+static size_t parse_elf(void *output) - { - #ifdef CONFIG_X86_64 - Elf64_Ehdr ehdr; -@@ -293,10 +293,8 @@ static void parse_elf(void *output) - if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || - ehdr.e_ident[EI_MAG1] != ELFMAG1 || - ehdr.e_ident[EI_MAG2] != ELFMAG2 || -- ehdr.e_ident[EI_MAG3] != ELFMAG3) { -+ ehdr.e_ident[EI_MAG3] != ELFMAG3) - error("Kernel is not a valid ELF file"); -- return; -- } - - debug_putstr("Parsing ELF... "); - -@@ -328,6 +326,35 @@ static void parse_elf(void *output) - } - - free(phdrs); -+ -+ return ehdr.e_entry - LOAD_PHYSICAL_ADDR; -+} -+ -+const unsigned long kernel_total_size = VO__end - VO__text; -+ -+static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4); -+ -+extern unsigned char input_data[]; -+extern unsigned int input_len, output_len; -+ -+unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr, -+ void (*error)(char *x)) -+{ -+ unsigned long entry; -+ -+ if (!free_mem_ptr) { -+ free_mem_ptr = (unsigned long)boot_heap; -+ free_mem_end_ptr = (unsigned long)boot_heap + sizeof(boot_heap); -+ } -+ -+ if (__decompress(input_data, input_len, NULL, NULL, outbuf, output_len, -+ NULL, error) < 0) -+ return ULONG_MAX; -+ -+ entry = parse_elf(outbuf); -+ handle_relocations(outbuf, output_len, virt_addr); -+ -+ return entry; - } - - /* -@@ -347,25 +374,22 @@ static void parse_elf(void *output) - * |-------uncompressed kernel image---------| - * - */ --asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, -- unsigned char *input_data, -- unsigned long input_len, -- unsigned char *output, -- unsigned long output_len) -+asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output) - { -- const unsigned long kernel_total_size = VO__end - VO__text; - unsigned long virt_addr = LOAD_PHYSICAL_ADDR; -+ memptr heap = (memptr)boot_heap; - unsigned long needed_size; -+ size_t entry_offset; - - /* Retain x86 boot parameters pointer passed from startup_32/64. */ -- boot_params = rmode; -+ boot_params_ptr = rmode; - - /* Clear flags intended for solely in-kernel use. */ -- boot_params->hdr.loadflags &= ~KASLR_FLAG; -+ boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG; - -- sanitize_boot_params(boot_params); -+ sanitize_boot_params(boot_params_ptr); - -- if (boot_params->screen_info.orig_video_mode == 7) { -+ if (boot_params_ptr->screen_info.orig_video_mode == 7) { - vidmem = (char *) 0xb0000; - vidport = 0x3b4; - } else { -@@ -373,8 +397,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - vidport = 0x3d4; - } - -- lines = boot_params->screen_info.orig_video_lines; -- cols = boot_params->screen_info.orig_video_cols; -+ lines = boot_params_ptr->screen_info.orig_video_lines; -+ cols = boot_params_ptr->screen_info.orig_video_cols; - - init_default_io_ops(); - -@@ -393,7 +417,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - * so that early debugging output from the RSDP parsing code can be - * collected. - */ -- boot_params->acpi_rsdp_addr = get_rsdp_addr(); -+ boot_params_ptr->acpi_rsdp_addr = get_rsdp_addr(); - - debug_putstr("early console in extract_kernel\n"); - -@@ -411,7 +435,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - * entries. This ensures the full mapped area is usable RAM - * and doesn't include any reserved areas. - */ -- needed_size = max(output_len, kernel_total_size); -+ needed_size = max_t(unsigned long, output_len, kernel_total_size); - #ifdef CONFIG_X86_64 - needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN); - #endif -@@ -442,7 +466,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - #ifdef CONFIG_X86_64 - if (heap > 0x3fffffffffffUL) - error("Destination address too large"); -- if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE) -+ if (virt_addr + needed_size > KERNEL_IMAGE_SIZE) - error("Destination virtual address is beyond the kernel mapping area"); - #else - if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) -@@ -454,16 +478,17 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, - #endif - - debug_putstr("\nDecompressing Linux... "); -- __decompress(input_data, input_len, NULL, NULL, output, output_len, -- NULL, error); -- parse_elf(output); -- handle_relocations(output, output_len, virt_addr); -- debug_putstr("done.\nBooting the kernel.\n"); -+ -+ entry_offset = decompress_kernel(output, virt_addr, error); -+ -+ debug_putstr("done.\nBooting the kernel (entry_offset: 0x"); -+ debug_puthex(entry_offset); -+ debug_putstr(").\n"); - - /* Disable exception handling before booting the kernel */ - cleanup_exception_handling(); - -- return output; -+ return output + entry_offset; - } - - void fortify_panic(const char *name) -diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h -index a49d9219c06e5..254acd76efde2 100644 ---- a/arch/x86/boot/compressed/misc.h -+++ b/arch/x86/boot/compressed/misc.h -@@ -52,7 +52,6 @@ extern memptr free_mem_ptr; - extern memptr free_mem_end_ptr; - void *malloc(int size); - void free(void *where); --extern struct boot_params *boot_params; - void __putstr(const char *s); - void __puthex(unsigned long value); - #define error_putstr(__x) __putstr(__x) -@@ -170,9 +169,7 @@ static inline int count_immovable_mem_regions(void) { return 0; } - #endif - - /* ident_map_64.c */ --#ifdef CONFIG_X86_5LEVEL - extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; --#endif - extern void kernel_add_identity_map(unsigned long start, unsigned long end); - - /* Used by PAGE_KERN* macros: */ -diff --git a/arch/x86/boot/compressed/pgtable.h b/arch/x86/boot/compressed/pgtable.h -index cc9b2529a0863..6d595abe06b34 100644 ---- a/arch/x86/boot/compressed/pgtable.h -+++ b/arch/x86/boot/compressed/pgtable.h -@@ -3,18 +3,16 @@ - - #define TRAMPOLINE_32BIT_SIZE (2 * PAGE_SIZE) - --#define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 -- - #define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE --#define TRAMPOLINE_32BIT_CODE_SIZE 0x80 -- --#define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE -+#define TRAMPOLINE_32BIT_CODE_SIZE 0xA0 - - #ifndef __ASSEMBLER__ - - extern unsigned long *trampoline_32bit; - --extern void trampoline_32bit_src(void *return_ptr); -+extern void trampoline_32bit_src(void *trampoline, bool enable_5lvl); -+ -+extern const u16 trampoline_ljmp_imm_offset; - - #endif /* __ASSEMBLER__ */ - #endif /* BOOT_COMPRESSED_PAGETABLE_H */ -diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c -index 2ac12ff4111bf..51f957b24ba7a 100644 ---- a/arch/x86/boot/compressed/pgtable_64.c -+++ b/arch/x86/boot/compressed/pgtable_64.c -@@ -16,11 +16,6 @@ unsigned int __section(".data") pgdir_shift = 39; - unsigned int __section(".data") ptrs_per_p4d = 1; - #endif - --struct paging_config { -- unsigned long trampoline_start; -- unsigned long l5_required; --}; -- - /* Buffer to preserve trampoline memory */ - static char trampoline_save[TRAMPOLINE_32BIT_SIZE]; - -@@ -29,11 +24,10 @@ static char trampoline_save[TRAMPOLINE_32BIT_SIZE]; - * purposes. - * - * Avoid putting the pointer into .bss as it will be cleared between -- * paging_prepare() and extract_kernel(). -+ * configure_5level_paging() and extract_kernel(). - */ - unsigned long *trampoline_32bit __section(".data"); - --extern struct boot_params *boot_params; - int cmdline_find_option_bool(const char *option); - - static unsigned long find_trampoline_placement(void) -@@ -54,7 +48,7 @@ static unsigned long find_trampoline_placement(void) - * - * Only look for values in the legacy ROM for non-EFI system. - */ -- signature = (char *)&boot_params->efi_info.efi_loader_signature; -+ signature = (char *)&boot_params_ptr->efi_info.efi_loader_signature; - if (strncmp(signature, EFI32_LOADER_SIGNATURE, 4) && - strncmp(signature, EFI64_LOADER_SIGNATURE, 4)) { - ebda_start = *(unsigned short *)0x40e << 4; -@@ -70,10 +64,10 @@ static unsigned long find_trampoline_placement(void) - bios_start = round_down(bios_start, PAGE_SIZE); - - /* Find the first usable memory region under bios_start. */ -- for (i = boot_params->e820_entries - 1; i >= 0; i--) { -+ for (i = boot_params_ptr->e820_entries - 1; i >= 0; i--) { - unsigned long new = bios_start; - -- entry = &boot_params->e820_table[i]; -+ entry = &boot_params_ptr->e820_table[i]; - - /* Skip all entries above bios_start. */ - if (bios_start <= entry->addr) -@@ -106,12 +100,13 @@ static unsigned long find_trampoline_placement(void) - return bios_start - TRAMPOLINE_32BIT_SIZE; - } - --struct paging_config paging_prepare(void *rmode) -+asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) - { -- struct paging_config paging_config = {}; -+ void (*toggle_la57)(void *cr3); -+ bool l5_required = false; - - /* Initialize boot_params. Required for cmdline_find_option_bool(). */ -- boot_params = rmode; -+ boot_params_ptr = bp; - - /* - * Check if LA57 is desired and supported. -@@ -129,12 +124,22 @@ struct paging_config paging_prepare(void *rmode) - !cmdline_find_option_bool("no5lvl") && - native_cpuid_eax(0) >= 7 && - (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) { -- paging_config.l5_required = 1; -+ l5_required = true; -+ -+ /* Initialize variables for 5-level paging */ -+ __pgtable_l5_enabled = 1; -+ pgdir_shift = 48; -+ ptrs_per_p4d = 512; - } - -- paging_config.trampoline_start = find_trampoline_placement(); -+ /* -+ * The trampoline will not be used if the paging mode is already set to -+ * the desired one. -+ */ -+ if (l5_required == !!(native_read_cr4() & X86_CR4_LA57)) -+ return; - -- trampoline_32bit = (unsigned long *)paging_config.trampoline_start; -+ trampoline_32bit = (unsigned long *)find_trampoline_placement(); - - /* Preserve trampoline memory */ - memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); -@@ -143,32 +148,32 @@ struct paging_config paging_prepare(void *rmode) - memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); - - /* Copy trampoline code in place */ -- memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), -+ toggle_la57 = memcpy(trampoline_32bit + -+ TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), - &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); - -+ /* -+ * Avoid the need for a stack in the 32-bit trampoline code, by using -+ * LJMP rather than LRET to return back to long mode. LJMP takes an -+ * immediate absolute address, which needs to be adjusted based on the -+ * placement of the trampoline. -+ */ -+ *(u32 *)((u8 *)toggle_la57 + trampoline_ljmp_imm_offset) += -+ (unsigned long)toggle_la57; -+ - /* - * The code below prepares page table in trampoline memory. - * - * The new page table will be used by trampoline code for switching - * from 4- to 5-level paging or vice versa. -- * -- * If switching is not required, the page table is unused: trampoline -- * code wouldn't touch CR3. -- */ -- -- /* -- * We are not going to use the page table in trampoline memory if we -- * are already in the desired paging mode. - */ -- if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57)) -- goto out; - -- if (paging_config.l5_required) { -+ if (l5_required) { - /* - * For 4- to 5-level paging transition, set up current CR3 as - * the first and the only entry in a new top-level page table. - */ -- trampoline_32bit[TRAMPOLINE_32BIT_PGTABLE_OFFSET] = __native_read_cr3() | _PAGE_TABLE_NOENC; -+ *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; - } else { - unsigned long src; - -@@ -181,38 +186,17 @@ struct paging_config paging_prepare(void *rmode) - * may be above 4G. - */ - src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; -- memcpy(trampoline_32bit + TRAMPOLINE_32BIT_PGTABLE_OFFSET / sizeof(unsigned long), -- (void *)src, PAGE_SIZE); -+ memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); - } - --out: -- return paging_config; --} -- --void cleanup_trampoline(void *pgtable) --{ -- void *trampoline_pgtable; -- -- trampoline_pgtable = trampoline_32bit + TRAMPOLINE_32BIT_PGTABLE_OFFSET / sizeof(unsigned long); -+ toggle_la57(trampoline_32bit); - - /* -- * Move the top level page table out of trampoline memory, -- * if it's there. -+ * Move the top level page table out of trampoline memory. - */ -- if ((void *)__native_read_cr3() == trampoline_pgtable) { -- memcpy(pgtable, trampoline_pgtable, PAGE_SIZE); -- native_write_cr3((unsigned long)pgtable); -- } -+ memcpy(pgtable, trampoline_32bit, PAGE_SIZE); -+ native_write_cr3((unsigned long)pgtable); - - /* Restore trampoline memory */ - memcpy(trampoline_32bit, trampoline_save, TRAMPOLINE_32BIT_SIZE); -- -- /* Initialize variables for 5-level paging */ --#ifdef CONFIG_X86_5LEVEL -- if (__read_cr4() & X86_CR4_LA57) { -- __pgtable_l5_enabled = 1; -- pgdir_shift = 48; -- ptrs_per_p4d = 512; -- } --#endif - } -diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c -index 9c91cc40f4565..d07e665bb265b 100644 ---- a/arch/x86/boot/compressed/sev.c -+++ b/arch/x86/boot/compressed/sev.c -@@ -327,20 +327,25 @@ static void enforce_vmpl0(void) - */ - #define SNP_FEATURES_PRESENT (0) - -+u64 snp_get_unsupported_features(u64 status) -+{ -+ if (!(status & MSR_AMD64_SEV_SNP_ENABLED)) -+ return 0; -+ -+ return status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT; -+} -+ - void snp_check_features(void) - { - u64 unsupported; - -- if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) -- return; -- - /* - * Terminate the boot if hypervisor has enabled any feature lacking - * guest side implementation. Pass on the unsupported features mask through - * EXIT_INFO_2 of the GHCB protocol so that those features can be reported - * as part of the guest boot failure. - */ -- unsupported = sev_status & SNP_FEATURES_IMPL_REQ & ~SNP_FEATURES_PRESENT; -+ unsupported = snp_get_unsupported_features(sev_status); - if (unsupported) { - if (ghcb_version < 2 || (!boot_ghcb && !early_setup_ghcb())) - sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); -@@ -350,35 +355,22 @@ void snp_check_features(void) - } - } - --void sev_enable(struct boot_params *bp) -+/* -+ * sev_check_cpu_support - Check for SEV support in the CPU capabilities -+ * -+ * Returns < 0 if SEV is not supported, otherwise the position of the -+ * encryption bit in the page table descriptors. -+ */ -+static int sev_check_cpu_support(void) - { - unsigned int eax, ebx, ecx, edx; -- struct msr m; -- bool snp; -- -- /* -- * bp->cc_blob_address should only be set by boot/compressed kernel. -- * Initialize it to 0 to ensure that uninitialized values from -- * buggy bootloaders aren't propagated. -- */ -- if (bp) -- bp->cc_blob_address = 0; -- -- /* -- * Do an initial SEV capability check before snp_init() which -- * loads the CPUID page and the same checks afterwards are done -- * without the hypervisor and are trustworthy. -- * -- * If the HV fakes SEV support, the guest will crash'n'burn -- * which is good enough. -- */ - - /* Check for the SME/SEV support leaf */ - eax = 0x80000000; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - if (eax < 0x8000001f) -- return; -+ return -ENODEV; - - /* - * Check for the SME/SEV feature: -@@ -393,6 +385,35 @@ void sev_enable(struct boot_params *bp) - native_cpuid(&eax, &ebx, &ecx, &edx); - /* Check whether SEV is supported */ - if (!(eax & BIT(1))) -+ return -ENODEV; -+ -+ return ebx & 0x3f; -+} -+ -+void sev_enable(struct boot_params *bp) -+{ -+ struct msr m; -+ int bitpos; -+ bool snp; -+ -+ /* -+ * bp->cc_blob_address should only be set by boot/compressed kernel. -+ * Initialize it to 0 to ensure that uninitialized values from -+ * buggy bootloaders aren't propagated. -+ */ -+ if (bp) -+ bp->cc_blob_address = 0; -+ -+ /* -+ * Do an initial SEV capability check before snp_init() which -+ * loads the CPUID page and the same checks afterwards are done -+ * without the hypervisor and are trustworthy. -+ * -+ * If the HV fakes SEV support, the guest will crash'n'burn -+ * which is good enough. -+ */ -+ -+ if (sev_check_cpu_support() < 0) - return; - - /* -@@ -403,26 +424,8 @@ void sev_enable(struct boot_params *bp) - - /* Now repeat the checks with the SNP CPUID table. */ - -- /* Recheck the SME/SEV support leaf */ -- eax = 0x80000000; -- ecx = 0; -- native_cpuid(&eax, &ebx, &ecx, &edx); -- if (eax < 0x8000001f) -- return; -- -- /* -- * Recheck for the SME/SEV feature: -- * CPUID Fn8000_001F[EAX] -- * - Bit 0 - Secure Memory Encryption support -- * - Bit 1 - Secure Encrypted Virtualization support -- * CPUID Fn8000_001F[EBX] -- * - Bits 5:0 - Pagetable bit position used to indicate encryption -- */ -- eax = 0x8000001f; -- ecx = 0; -- native_cpuid(&eax, &ebx, &ecx, &edx); -- /* Check whether SEV is supported */ -- if (!(eax & BIT(1))) { -+ bitpos = sev_check_cpu_support(); -+ if (bitpos < 0) { - if (snp) - error("SEV-SNP support indicated by CC blob, but not CPUID."); - return; -@@ -454,7 +457,24 @@ void sev_enable(struct boot_params *bp) - if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) - error("SEV-SNP supported indicated by CC blob, but not SEV status MSR."); - -- sme_me_mask = BIT_ULL(ebx & 0x3f); -+ sme_me_mask = BIT_ULL(bitpos); -+} -+ -+/* -+ * sev_get_status - Retrieve the SEV status mask -+ * -+ * Returns 0 if the CPU is not SEV capable, otherwise the value of the -+ * AMD64_SEV MSR. -+ */ -+u64 sev_get_status(void) -+{ -+ struct msr m; -+ -+ if (sev_check_cpu_support() < 0) -+ return 0; -+ -+ boot_rdmsr(MSR_AMD64_SEV, &m); -+ return m.q; - } - - /* Search for Confidential Computing blob in the EFI config table. */ -@@ -545,7 +565,7 @@ void sev_prep_identity_maps(unsigned long top_level_pgt) - * accessed after switchover. - */ - if (sev_snp_enabled()) { -- unsigned long cc_info_pa = boot_params->cc_blob_address; -+ unsigned long cc_info_pa = boot_params_ptr->cc_blob_address; - struct cc_blob_sev_info *cc_info; - - kernel_add_identity_map(cc_info_pa, cc_info_pa + sizeof(*cc_info)); -diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S -index f912d77701305..d31982509654d 100644 ---- a/arch/x86/boot/header.S -+++ b/arch/x86/boot/header.S -@@ -406,7 +406,7 @@ xloadflags: - # define XLF1 0 - #endif - --#ifdef CONFIG_EFI_STUB -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL - # ifdef CONFIG_EFI_MIXED - # define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64) - # else -diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c -index a3725ad46c5a0..bd247692b7017 100644 ---- a/arch/x86/boot/tools/build.c -+++ b/arch/x86/boot/tools/build.c -@@ -290,6 +290,7 @@ static void efi_stub_entry_update(void) - { - unsigned long addr = efi32_stub_entry; - -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL - #ifdef CONFIG_X86_64 - /* Yes, this is really how we defined it :( */ - addr = efi64_stub_entry - 0x200; -@@ -298,6 +299,7 @@ static void efi_stub_entry_update(void) - #ifdef CONFIG_EFI_MIXED - if (efi32_stub_entry != addr) - die("32-bit and 64-bit EFI entry points do not match\n"); -+#endif - #endif - put_unaligned_le32(addr, &buf[0x264]); - } -diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S -index bfb7bcb362bcf..09e99d13fc0b3 100644 ---- a/arch/x86/entry/entry.S -+++ b/arch/x86/entry/entry.S -@@ -6,6 +6,9 @@ - #include - #include - #include -+#include -+#include -+#include - - .pushsection .noinstr.text, "ax" - -@@ -20,3 +23,23 @@ SYM_FUNC_END(entry_ibpb) - EXPORT_SYMBOL_GPL(entry_ibpb); - - .popsection -+ -+/* -+ * Define the VERW operand that is disguised as entry code so that -+ * it can be referenced with KPTI enabled. This ensure VERW can be -+ * used late in exit-to-user path after page tables are switched. -+ */ -+.pushsection .entry.text, "ax" -+ -+.align L1_CACHE_BYTES, 0xcc -+SYM_CODE_START_NOALIGN(mds_verw_sel) -+ UNWIND_HINT_EMPTY -+ ANNOTATE_NOENDBR -+ .word __KERNEL_DS -+.align L1_CACHE_BYTES, 0xcc -+SYM_CODE_END(mds_verw_sel); -+/* For KVM */ -+EXPORT_SYMBOL_GPL(mds_verw_sel); -+ -+.popsection -+ -diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S -index e309e71560389..ee5def1060c86 100644 ---- a/arch/x86/entry/entry_32.S -+++ b/arch/x86/entry/entry_32.S -@@ -912,6 +912,7 @@ SYM_FUNC_START(entry_SYSENTER_32) - BUG_IF_WRONG_CR3 no_user_check=1 - popfl - popl %eax -+ CLEAR_CPU_BUFFERS - - /* - * Return back to the vDSO, which will pop ecx and edx. -@@ -981,6 +982,7 @@ restore_all_switch_stack: - - /* Restore user state */ - RESTORE_REGS pop=4 # skip orig_eax/error_code -+ CLEAR_CPU_BUFFERS - .Lirq_return: - /* - * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization -@@ -1173,6 +1175,7 @@ SYM_CODE_START(asm_exc_nmi) - - /* Not on SYSENTER stack. */ - call exc_nmi -+ CLEAR_CPU_BUFFERS - jmp .Lnmi_return - - .Lnmi_from_sysenter_stack: -diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S -index 9953d966d1244..c2383c2880ec6 100644 ---- a/arch/x86/entry/entry_64.S -+++ b/arch/x86/entry/entry_64.S -@@ -223,6 +223,7 @@ syscall_return_via_sysret: - SYM_INNER_LABEL(entry_SYSRETQ_unsafe_stack, SYM_L_GLOBAL) - ANNOTATE_NOENDBR - swapgs -+ CLEAR_CPU_BUFFERS - sysretq - SYM_INNER_LABEL(entry_SYSRETQ_end, SYM_L_GLOBAL) - ANNOTATE_NOENDBR -@@ -656,6 +657,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) - /* Restore RDI. */ - popq %rdi - swapgs -+ CLEAR_CPU_BUFFERS - jmp .Lnative_iret - - -@@ -767,6 +769,8 @@ native_irq_return_ldt: - */ - popq %rax /* Restore user RAX */ - -+ CLEAR_CPU_BUFFERS -+ - /* - * RSP now points to an ordinary IRET frame, except that the page - * is read-only and RSP[31:16] are preloaded with the userspace -@@ -1493,6 +1497,12 @@ nmi_restore: - std - movq $0, 5*8(%rsp) /* clear "NMI executing" */ - -+ /* -+ * Skip CLEAR_CPU_BUFFERS here, since it only helps in rare cases like -+ * NMI in kernel after user state is restored. For an unprivileged user -+ * these conditions are hard to meet. -+ */ -+ - /* - * iretq reads the "iret" frame and exits the NMI stack in a - * single instruction. We are returning to kernel mode, so this -@@ -1511,6 +1521,7 @@ SYM_CODE_START(ignore_sysret) - UNWIND_HINT_EMPTY - ENDBR - mov $-ENOSYS, %eax -+ CLEAR_CPU_BUFFERS - sysretl - SYM_CODE_END(ignore_sysret) - #endif -diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S -index d6c08d8986b17..4bcd009a232bf 100644 ---- a/arch/x86/entry/entry_64_compat.S -+++ b/arch/x86/entry/entry_64_compat.S -@@ -272,6 +272,7 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_stack, SYM_L_GLOBAL) - xorl %r9d, %r9d - xorl %r10d, %r10d - swapgs -+ CLEAR_CPU_BUFFERS - sysretl - SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) - ANNOTATE_NOENDBR -diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h -index 215d37f7dde8a..a38cc0afc90a0 100644 ---- a/arch/x86/include/asm/boot.h -+++ b/arch/x86/include/asm/boot.h -@@ -79,4 +79,14 @@ - # define BOOT_STACK_SIZE 0x1000 - #endif - -+#ifndef __ASSEMBLY__ -+extern unsigned int output_len; -+extern const unsigned long kernel_total_size; -+ -+unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr, -+ void (*error)(char *x)); -+ -+extern struct boot_params *boot_params_ptr; -+#endif -+ - #endif /* _ASM_X86_BOOT_H */ -diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index b122708792c4d..b60f24b30cb90 100644 ---- a/arch/x86/include/asm/cpufeatures.h -+++ b/arch/x86/include/asm/cpufeatures.h -@@ -304,7 +304,7 @@ - #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */ - #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ - #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */ -- -+#define X86_FEATURE_CLEAR_CPU_BUF (11*32+18) /* "" Clear CPU buffers using VERW */ - - #define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */ - -diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h -index 233ae6986d6f2..e601264b1a243 100644 ---- a/arch/x86/include/asm/efi.h -+++ b/arch/x86/include/asm/efi.h -@@ -88,6 +88,8 @@ static inline void efi_fpu_end(void) - } - - #ifdef CONFIG_X86_32 -+#define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) -+ - #define arch_efi_call_virt_setup() \ - ({ \ - efi_fpu_begin(); \ -@@ -101,8 +103,7 @@ static inline void efi_fpu_end(void) - }) - - #else /* !CONFIG_X86_32 */ -- --#define EFI_LOADER_SIGNATURE "EL64" -+#define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT - - extern asmlinkage u64 __efi_call(void *fp, ...); - -@@ -214,6 +215,8 @@ efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, - - #ifdef CONFIG_EFI_MIXED - -+#define EFI_ALLOC_LIMIT (efi_is_64bit() ? ULONG_MAX : U32_MAX) -+ - #define ARCH_HAS_EFISTUB_WRAPPERS - - static inline bool efi_is_64bit(void) -@@ -325,6 +328,13 @@ static inline u32 efi64_convert_status(efi_status_t status) - #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ - (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) - -+/* Memory Attribute Protocol */ -+#define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ -+ ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) -+ -+#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ -+ ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) -+ - /* - * The macros below handle the plumbing for the argument mapping. To add a - * mapping for a specific EFI method, simply define a macro -diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h -index 11203a9fe0a87..ffe72790ceafd 100644 ---- a/arch/x86/include/asm/entry-common.h -+++ b/arch/x86/include/asm/entry-common.h -@@ -91,7 +91,6 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, - - static __always_inline void arch_exit_to_user_mode(void) - { -- mds_user_clear_cpu_buffers(); - amd_clear_divider(); - } - #define arch_exit_to_user_mode arch_exit_to_user_mode -diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h -index d3706de91a934..8f6f17a8617b6 100644 ---- a/arch/x86/include/asm/nospec-branch.h -+++ b/arch/x86/include/asm/nospec-branch.h -@@ -194,6 +194,19 @@ - #endif - .endm - -+/* -+ * Macro to execute VERW instruction that mitigate transient data sampling -+ * attacks such as MDS. On affected systems a microcode update overloaded VERW -+ * instruction to also clear the CPU buffers. VERW clobbers CFLAGS.ZF. -+ * -+ * Note: Only the memory operand variant of VERW clears the CPU buffers. -+ */ -+.macro CLEAR_CPU_BUFFERS -+ ALTERNATIVE "jmp .Lskip_verw_\@", "", X86_FEATURE_CLEAR_CPU_BUF -+ verw _ASM_RIP(mds_verw_sel) -+.Lskip_verw_\@: -+.endm -+ - #else /* __ASSEMBLY__ */ - - #define ANNOTATE_RETPOLINE_SAFE \ -@@ -368,13 +381,14 @@ DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp); - DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); - DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb); - --DECLARE_STATIC_KEY_FALSE(mds_user_clear); - DECLARE_STATIC_KEY_FALSE(mds_idle_clear); - - DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); - - DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); - -+extern u16 mds_verw_sel; -+ - #include - - /** -@@ -400,17 +414,6 @@ static __always_inline void mds_clear_cpu_buffers(void) - asm volatile("verw %[ds]" : : [ds] "m" (ds) : "cc"); - } - --/** -- * mds_user_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability -- * -- * Clear CPU buffers if the corresponding static key is enabled -- */ --static __always_inline void mds_user_clear_cpu_buffers(void) --{ -- if (static_branch_likely(&mds_user_clear)) -- mds_clear_cpu_buffers(); --} -- - /** - * mds_idle_clear_cpu_buffers - Mitigation for MDS vulnerability - * -diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h -index 7ca5c9ec8b52e..cf98fc28601fb 100644 ---- a/arch/x86/include/asm/sev.h -+++ b/arch/x86/include/asm/sev.h -@@ -157,6 +157,7 @@ static __always_inline void sev_es_nmi_complete(void) - __sev_es_nmi_complete(); - } - extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd); -+extern void sev_enable(struct boot_params *bp); - - static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) - { -@@ -202,12 +203,15 @@ void snp_set_wakeup_secondary_cpu(void); - bool snp_init(struct boot_params *bp); - void __init __noreturn snp_abort(void); - int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio); -+u64 snp_get_unsupported_features(u64 status); -+u64 sev_get_status(void); - #else - static inline void sev_es_ist_enter(struct pt_regs *regs) { } - static inline void sev_es_ist_exit(void) { } - static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; } - static inline void sev_es_nmi_complete(void) { } - static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } -+static inline void sev_enable(struct boot_params *bp) { } - static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) { return 0; } - static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long attrs) { return 0; } - static inline void setup_ghcb(void) { } -@@ -225,6 +229,9 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in - { - return -ENOTTY; - } -+ -+static inline u64 snp_get_unsupported_features(u64 status) { return 0; } -+static inline u64 sev_get_status(void) { return 0; } - #endif - - #endif -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index 13dffc43ded02..d1895930e6eb8 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -110,9 +110,6 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); - /* Control unconditional IBPB in switch_mm() */ - DEFINE_STATIC_KEY_FALSE(switch_mm_always_ibpb); - --/* Control MDS CPU buffer clear before returning to user space */ --DEFINE_STATIC_KEY_FALSE(mds_user_clear); --EXPORT_SYMBOL_GPL(mds_user_clear); - /* Control MDS CPU buffer clear before idling (halt, mwait) */ - DEFINE_STATIC_KEY_FALSE(mds_idle_clear); - EXPORT_SYMBOL_GPL(mds_idle_clear); -@@ -251,7 +248,7 @@ static void __init mds_select_mitigation(void) - if (!boot_cpu_has(X86_FEATURE_MD_CLEAR)) - mds_mitigation = MDS_MITIGATION_VMWERV; - -- static_branch_enable(&mds_user_clear); -+ setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); - - if (!boot_cpu_has(X86_BUG_MSBDS_ONLY) && - (mds_nosmt || cpu_mitigations_auto_nosmt())) -@@ -355,7 +352,7 @@ static void __init taa_select_mitigation(void) - * For guests that can't determine whether the correct microcode is - * present on host, enable the mitigation for UCODE_NEEDED as well. - */ -- static_branch_enable(&mds_user_clear); -+ setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); - - if (taa_nosmt || cpu_mitigations_auto_nosmt()) - cpu_smt_disable(false); -@@ -423,7 +420,7 @@ static void __init mmio_select_mitigation(void) - */ - if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) && - boot_cpu_has(X86_FEATURE_RTM))) -- static_branch_enable(&mds_user_clear); -+ setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); - else - static_branch_enable(&mmio_stale_data_clear); - -@@ -483,12 +480,12 @@ static void __init md_clear_update_mitigation(void) - if (cpu_mitigations_off()) - return; - -- if (!static_key_enabled(&mds_user_clear)) -+ if (!boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF)) - goto out; - - /* -- * mds_user_clear is now enabled. Update MDS, TAA and MMIO Stale Data -- * mitigation, if necessary. -+ * X86_FEATURE_CLEAR_CPU_BUF is now enabled. Update MDS, TAA and MMIO -+ * Stale Data mitigation, if necessary. - */ - if (mds_mitigation == MDS_MITIGATION_OFF && - boot_cpu_has_bug(X86_BUG_MDS)) { -diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c -index 4278996504833..32bd640170475 100644 ---- a/arch/x86/kernel/cpu/intel.c -+++ b/arch/x86/kernel/cpu/intel.c -@@ -216,6 +216,90 @@ int intel_cpu_collect_info(struct ucode_cpu_info *uci) - } - EXPORT_SYMBOL_GPL(intel_cpu_collect_info); - -+#define MSR_IA32_TME_ACTIVATE 0x982 -+ -+/* Helpers to access TME_ACTIVATE MSR */ -+#define TME_ACTIVATE_LOCKED(x) (x & 0x1) -+#define TME_ACTIVATE_ENABLED(x) (x & 0x2) -+ -+#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ -+#define TME_ACTIVATE_POLICY_AES_XTS_128 0 -+ -+#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ -+ -+#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ -+#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 -+ -+/* Values for mktme_status (SW only construct) */ -+#define MKTME_ENABLED 0 -+#define MKTME_DISABLED 1 -+#define MKTME_UNINITIALIZED 2 -+static int mktme_status = MKTME_UNINITIALIZED; -+ -+static void detect_tme_early(struct cpuinfo_x86 *c) -+{ -+ u64 tme_activate, tme_policy, tme_crypto_algs; -+ int keyid_bits = 0, nr_keyids = 0; -+ static u64 tme_activate_cpu0 = 0; -+ -+ rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); -+ -+ if (mktme_status != MKTME_UNINITIALIZED) { -+ if (tme_activate != tme_activate_cpu0) { -+ /* Broken BIOS? */ -+ pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); -+ pr_err_once("x86/tme: MKTME is not usable\n"); -+ mktme_status = MKTME_DISABLED; -+ -+ /* Proceed. We may need to exclude bits from x86_phys_bits. */ -+ } -+ } else { -+ tme_activate_cpu0 = tme_activate; -+ } -+ -+ if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) { -+ pr_info_once("x86/tme: not enabled by BIOS\n"); -+ mktme_status = MKTME_DISABLED; -+ return; -+ } -+ -+ if (mktme_status != MKTME_UNINITIALIZED) -+ goto detect_keyid_bits; -+ -+ pr_info("x86/tme: enabled by BIOS\n"); -+ -+ tme_policy = TME_ACTIVATE_POLICY(tme_activate); -+ if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128) -+ pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); -+ -+ tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate); -+ if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { -+ pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", -+ tme_crypto_algs); -+ mktme_status = MKTME_DISABLED; -+ } -+detect_keyid_bits: -+ keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate); -+ nr_keyids = (1UL << keyid_bits) - 1; -+ if (nr_keyids) { -+ pr_info_once("x86/mktme: enabled by BIOS\n"); -+ pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); -+ } else { -+ pr_info_once("x86/mktme: disabled by BIOS\n"); -+ } -+ -+ if (mktme_status == MKTME_UNINITIALIZED) { -+ /* MKTME is usable */ -+ mktme_status = MKTME_ENABLED; -+ } -+ -+ /* -+ * KeyID bits effectively lower the number of physical address -+ * bits. Update cpuinfo_x86::x86_phys_bits accordingly. -+ */ -+ c->x86_phys_bits -= keyid_bits; -+} -+ - static void early_init_intel(struct cpuinfo_x86 *c) - { - u64 misc_enable; -@@ -367,6 +451,13 @@ static void early_init_intel(struct cpuinfo_x86 *c) - */ - if (detect_extended_topology_early(c) < 0) - detect_ht_early(c); -+ -+ /* -+ * Adjust the number of physical bits early because it affects the -+ * valid bits of the MTRR mask registers. -+ */ -+ if (cpu_has(c, X86_FEATURE_TME)) -+ detect_tme_early(c); - } - - static void bsp_init_intel(struct cpuinfo_x86 *c) -@@ -527,90 +618,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c) - #endif - } - --#define MSR_IA32_TME_ACTIVATE 0x982 -- --/* Helpers to access TME_ACTIVATE MSR */ --#define TME_ACTIVATE_LOCKED(x) (x & 0x1) --#define TME_ACTIVATE_ENABLED(x) (x & 0x2) -- --#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ --#define TME_ACTIVATE_POLICY_AES_XTS_128 0 -- --#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ -- --#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ --#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 -- --/* Values for mktme_status (SW only construct) */ --#define MKTME_ENABLED 0 --#define MKTME_DISABLED 1 --#define MKTME_UNINITIALIZED 2 --static int mktme_status = MKTME_UNINITIALIZED; -- --static void detect_tme(struct cpuinfo_x86 *c) --{ -- u64 tme_activate, tme_policy, tme_crypto_algs; -- int keyid_bits = 0, nr_keyids = 0; -- static u64 tme_activate_cpu0 = 0; -- -- rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); -- -- if (mktme_status != MKTME_UNINITIALIZED) { -- if (tme_activate != tme_activate_cpu0) { -- /* Broken BIOS? */ -- pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); -- pr_err_once("x86/tme: MKTME is not usable\n"); -- mktme_status = MKTME_DISABLED; -- -- /* Proceed. We may need to exclude bits from x86_phys_bits. */ -- } -- } else { -- tme_activate_cpu0 = tme_activate; -- } -- -- if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) { -- pr_info_once("x86/tme: not enabled by BIOS\n"); -- mktme_status = MKTME_DISABLED; -- return; -- } -- -- if (mktme_status != MKTME_UNINITIALIZED) -- goto detect_keyid_bits; -- -- pr_info("x86/tme: enabled by BIOS\n"); -- -- tme_policy = TME_ACTIVATE_POLICY(tme_activate); -- if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128) -- pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); -- -- tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate); -- if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { -- pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", -- tme_crypto_algs); -- mktme_status = MKTME_DISABLED; -- } --detect_keyid_bits: -- keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate); -- nr_keyids = (1UL << keyid_bits) - 1; -- if (nr_keyids) { -- pr_info_once("x86/mktme: enabled by BIOS\n"); -- pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); -- } else { -- pr_info_once("x86/mktme: disabled by BIOS\n"); -- } -- -- if (mktme_status == MKTME_UNINITIALIZED) { -- /* MKTME is usable */ -- mktme_status = MKTME_ENABLED; -- } -- -- /* -- * KeyID bits effectively lower the number of physical address -- * bits. Update cpuinfo_x86::x86_phys_bits accordingly. -- */ -- c->x86_phys_bits -= keyid_bits; --} -- - static void init_cpuid_fault(struct cpuinfo_x86 *c) - { - u64 msr; -@@ -747,9 +754,6 @@ static void init_intel(struct cpuinfo_x86 *c) - - init_ia32_feat_ctl(c); - -- if (cpu_has(c, X86_FEATURE_TME)) -- detect_tme(c); -- - init_intel_misc_features(c); - - split_lock_init(); -diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c -index 9dac24680ff8e..993734e96615a 100644 ---- a/arch/x86/kernel/e820.c -+++ b/arch/x86/kernel/e820.c -@@ -1017,10 +1017,12 @@ void __init e820__reserve_setup_data(void) - e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); - - /* -- * SETUP_EFI and SETUP_IMA are supplied by kexec and do not need -- * to be reserved. -+ * SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED are supplied by -+ * kexec and do not need to be reserved. - */ -- if (data->type != SETUP_EFI && data->type != SETUP_IMA) -+ if (data->type != SETUP_EFI && -+ data->type != SETUP_IMA && -+ data->type != SETUP_RNG_SEED) - e820__range_update_kexec(pa_data, - sizeof(*data) + data->len, - E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); -diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c -index cec0bfa3bc04f..ed6cce6c39504 100644 ---- a/arch/x86/kernel/nmi.c -+++ b/arch/x86/kernel/nmi.c -@@ -522,9 +522,6 @@ DEFINE_IDTENTRY_RAW(exc_nmi) - write_cr2(this_cpu_read(nmi_cr2)); - if (this_cpu_dec_return(nmi_state)) - goto nmi_restart; -- -- if (user_mode(regs)) -- mds_user_clear_cpu_buffers(); - } - - #if defined(CONFIG_X86_64) && IS_ENABLED(CONFIG_KVM_INTEL) -diff --git a/arch/x86/kvm/vmx/run_flags.h b/arch/x86/kvm/vmx/run_flags.h -index edc3f16cc1896..6a9bfdfbb6e59 100644 ---- a/arch/x86/kvm/vmx/run_flags.h -+++ b/arch/x86/kvm/vmx/run_flags.h -@@ -2,7 +2,10 @@ - #ifndef __KVM_X86_VMX_RUN_FLAGS_H - #define __KVM_X86_VMX_RUN_FLAGS_H - --#define VMX_RUN_VMRESUME (1 << 0) --#define VMX_RUN_SAVE_SPEC_CTRL (1 << 1) -+#define VMX_RUN_VMRESUME_SHIFT 0 -+#define VMX_RUN_SAVE_SPEC_CTRL_SHIFT 1 -+ -+#define VMX_RUN_VMRESUME BIT(VMX_RUN_VMRESUME_SHIFT) -+#define VMX_RUN_SAVE_SPEC_CTRL BIT(VMX_RUN_SAVE_SPEC_CTRL_SHIFT) - - #endif /* __KVM_X86_VMX_RUN_FLAGS_H */ -diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S -index 0b5db4de4d09e..0b2cad66dee12 100644 ---- a/arch/x86/kvm/vmx/vmenter.S -+++ b/arch/x86/kvm/vmx/vmenter.S -@@ -106,7 +106,7 @@ SYM_FUNC_START(__vmx_vcpu_run) - mov (%_ASM_SP), %_ASM_AX - - /* Check if vmlaunch or vmresume is needed */ -- testb $VMX_RUN_VMRESUME, %bl -+ bt $VMX_RUN_VMRESUME_SHIFT, %bx - - /* Load guest registers. Don't clobber flags. */ - mov VCPU_RCX(%_ASM_AX), %_ASM_CX -@@ -128,8 +128,11 @@ SYM_FUNC_START(__vmx_vcpu_run) - /* Load guest RAX. This kills the @regs pointer! */ - mov VCPU_RAX(%_ASM_AX), %_ASM_AX - -- /* Check EFLAGS.ZF from 'testb' above */ -- jz .Lvmlaunch -+ /* Clobbers EFLAGS.ZF */ -+ CLEAR_CPU_BUFFERS -+ -+ /* Check EFLAGS.CF from the VMX_RUN_VMRESUME bit test above. */ -+ jnc .Lvmlaunch - - /* - * After a successful VMRESUME/VMLAUNCH, control flow "magically" -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 57c1374fdfd49..5c1590855ffcd 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -407,7 +407,8 @@ static __always_inline void vmx_enable_fb_clear(struct vcpu_vmx *vmx) - - static void vmx_update_fb_clear_dis(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx) - { -- vmx->disable_fb_clear = vmx_fb_clear_ctrl_available; -+ vmx->disable_fb_clear = !cpu_feature_enabled(X86_FEATURE_CLEAR_CPU_BUF) && -+ vmx_fb_clear_ctrl_available; - - /* - * If guest will not execute VERW, there is no need to set FB_CLEAR_DIS -@@ -7120,11 +7121,14 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, - { - guest_state_enter_irqoff(); - -- /* L1D Flush includes CPU buffer clear to mitigate MDS */ -+ /* -+ * L1D Flush includes CPU buffer clear to mitigate MDS, but VERW -+ * mitigation for MDS is done late in VMentry and is still -+ * executed in spite of L1D Flush. This is because an extra VERW -+ * should not matter much after the big hammer L1D Flush. -+ */ - if (static_branch_unlikely(&vmx_l1d_should_flush)) - vmx_l1d_flush(vcpu); -- else if (static_branch_unlikely(&mds_user_clear)) -- mds_clear_cpu_buffers(); - else if (static_branch_unlikely(&mmio_stale_data_clear) && - kvm_arch_has_assigned_device(vcpu->kvm)) - mds_clear_cpu_buffers(); -diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c -index c9064d34d8308..0211f704a358b 100644 ---- a/drivers/bluetooth/btqca.c -+++ b/drivers/bluetooth/btqca.c -@@ -152,7 +152,7 @@ static int qca_send_patch_config_cmd(struct hci_dev *hdev) - bt_dev_dbg(hdev, "QCA Patch config"); - - skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, sizeof(cmd), -- cmd, HCI_EV_VENDOR, HCI_INIT_TIMEOUT); -+ cmd, 0, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - bt_dev_err(hdev, "Sending QCA Patch config failed (%d)", err); -@@ -594,27 +594,48 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, - /* Firmware files to download are based on ROM version. - * ROM version is derived from last two bytes of soc_ver. - */ -- rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); -+ if (soc_type == QCA_WCN3988) -+ rom_ver = ((soc_ver & 0x00000f00) >> 0x05) | (soc_ver & 0x0000000f); -+ else -+ rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); - - if (soc_type == QCA_WCN6750) - qca_send_patch_config_cmd(hdev); - - /* Download rampatch file */ - config.type = TLV_TYPE_PATCH; -- if (qca_is_wcn399x(soc_type)) { -+ switch (soc_type) { -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: - snprintf(config.fwname, sizeof(config.fwname), - "qca/crbtfw%02x.tlv", rom_ver); -- } else if (soc_type == QCA_QCA6390) { -+ break; -+ case QCA_WCN3988: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/apbtfw%02x.tlv", rom_ver); -+ break; -+ case QCA_QCA6390: - snprintf(config.fwname, sizeof(config.fwname), - "qca/htbtfw%02x.tlv", rom_ver); -- } else if (soc_type == QCA_WCN6750) { -+ break; -+ case QCA_WCN6750: - /* Choose mbn file by default.If mbn file is not found - * then choose tlv file - */ - config.type = ELF_TYPE_PATCH; - snprintf(config.fwname, sizeof(config.fwname), - "qca/msbtfw%02x.mbn", rom_ver); -- } else { -+ break; -+ case QCA_WCN6855: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/hpbtfw%02x.tlv", rom_ver); -+ break; -+ case QCA_WCN7850: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/hmtbtfw%02x.tlv", rom_ver); -+ break; -+ default: - snprintf(config.fwname, sizeof(config.fwname), - "qca/rampatch_%08x.bin", soc_ver); - } -@@ -630,27 +651,48 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, - - /* Download NVM configuration */ - config.type = TLV_TYPE_NVM; -- if (firmware_name) -+ if (firmware_name) { - snprintf(config.fwname, sizeof(config.fwname), - "qca/%s", firmware_name); -- else if (qca_is_wcn399x(soc_type)) { -- if (ver.soc_id == QCA_WCN3991_SOC_ID) { -+ } else { -+ switch (soc_type) { -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) { -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/crnv%02xu.bin", rom_ver); -+ } else { -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/crnv%02x.bin", rom_ver); -+ } -+ break; -+ case QCA_WCN3988: - snprintf(config.fwname, sizeof(config.fwname), -- "qca/crnv%02xu.bin", rom_ver); -- } else { -+ "qca/apnv%02x.bin", rom_ver); -+ break; -+ case QCA_QCA6390: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/htnv%02x.bin", rom_ver); -+ break; -+ case QCA_WCN6750: - snprintf(config.fwname, sizeof(config.fwname), -- "qca/crnv%02x.bin", rom_ver); -+ "qca/msnv%02x.bin", rom_ver); -+ break; -+ case QCA_WCN6855: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/hpnv%02x.bin", rom_ver); -+ break; -+ case QCA_WCN7850: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/hmtnv%02x.bin", rom_ver); -+ break; -+ -+ default: -+ snprintf(config.fwname, sizeof(config.fwname), -+ "qca/nvm_%08x.bin", soc_ver); - } - } -- else if (soc_type == QCA_QCA6390) -- snprintf(config.fwname, sizeof(config.fwname), -- "qca/htnv%02x.bin", rom_ver); -- else if (soc_type == QCA_WCN6750) -- snprintf(config.fwname, sizeof(config.fwname), -- "qca/msnv%02x.bin", rom_ver); -- else -- snprintf(config.fwname, sizeof(config.fwname), -- "qca/nvm_%08x.bin", soc_ver); - - err = qca_download_firmware(hdev, &config, soc_type, rom_ver); - if (err < 0) { -@@ -658,16 +700,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, - return err; - } - -- if (soc_type >= QCA_WCN3991) { -+ switch (soc_type) { -+ case QCA_WCN3991: -+ case QCA_QCA6390: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - err = qca_disable_soc_logging(hdev); - if (err < 0) - return err; -+ break; -+ default: -+ break; - } - - /* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the - * VsMsftOpCode. - */ - switch (soc_type) { -+ case QCA_WCN3988: - case QCA_WCN3990: - case QCA_WCN3991: - case QCA_WCN3998: -@@ -685,11 +736,18 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, - return err; - } - -- if (soc_type == QCA_WCN3991 || soc_type == QCA_WCN6750) { -+ switch (soc_type) { -+ case QCA_WCN3991: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - /* get fw build info */ - err = qca_read_fw_build_info(hdev); - if (err < 0) - return err; -+ break; -+ default: -+ break; - } - - bt_dev_info(hdev, "QCA setup on UART is completed"); -diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h -index 61e9a50e66ae1..03bff5c0059de 100644 ---- a/drivers/bluetooth/btqca.h -+++ b/drivers/bluetooth/btqca.h -@@ -142,11 +142,14 @@ enum qca_btsoc_type { - QCA_INVALID = -1, - QCA_AR3002, - QCA_ROME, -+ QCA_WCN3988, - QCA_WCN3990, - QCA_WCN3998, - QCA_WCN3991, - QCA_QCA6390, - QCA_WCN6750, -+ QCA_WCN6855, -+ QCA_WCN7850, - }; - - #if IS_ENABLED(CONFIG_BT_QCA) -@@ -159,16 +162,6 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver, - enum qca_btsoc_type); - int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); - int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); --static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) --{ -- return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 || -- soc_type == QCA_WCN3998; --} --static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) --{ -- return soc_type == QCA_WCN6750; --} -- - #else - - static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) -@@ -196,16 +189,6 @@ static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) - return -EOPNOTSUPP; - } - --static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) --{ -- return false; --} -- --static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) --{ -- return false; --} -- - static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) - { - return -EOPNOTSUPP; -diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c -index 76ceb8a0183d1..8bfef7f81b417 100644 ---- a/drivers/bluetooth/hci_qca.c -+++ b/drivers/bluetooth/hci_qca.c -@@ -7,6 +7,7 @@ - * - * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. - * - * Acknowledgements: - * This file is based on hci_ll.c, which was... -@@ -606,9 +607,18 @@ static int qca_open(struct hci_uart *hu) - if (hu->serdev) { - qcadev = serdev_device_get_drvdata(hu->serdev); - -- if (qca_is_wcn399x(qcadev->btsoc_type) || -- qca_is_wcn6750(qcadev->btsoc_type)) -+ switch (qcadev->btsoc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: - hu->init_speed = qcadev->init_speed; -+ break; -+ -+ default: -+ break; -+ } - - if (qcadev->oper_speed) - hu->oper_speed = qcadev->oper_speed; -@@ -1314,11 +1324,20 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) - msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS)); - - /* Give the controller time to process the request */ -- if (qca_is_wcn399x(qca_soc_type(hu)) || -- qca_is_wcn6750(qca_soc_type(hu))) -+ switch (qca_soc_type(hu)) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - usleep_range(1000, 10000); -- else -+ break; -+ -+ default: - msleep(300); -+ } - - return 0; - } -@@ -1391,12 +1410,20 @@ static unsigned int qca_get_speed(struct hci_uart *hu, - - static int qca_check_speeds(struct hci_uart *hu) - { -- if (qca_is_wcn399x(qca_soc_type(hu)) || -- qca_is_wcn6750(qca_soc_type(hu))) { -+ switch (qca_soc_type(hu)) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - if (!qca_get_speed(hu, QCA_INIT_SPEED) && - !qca_get_speed(hu, QCA_OPER_SPEED)) - return -EINVAL; -- } else { -+ break; -+ -+ default: - if (!qca_get_speed(hu, QCA_INIT_SPEED) || - !qca_get_speed(hu, QCA_OPER_SPEED)) - return -EINVAL; -@@ -1425,13 +1452,29 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) - /* Disable flow control for wcn3990 to deassert RTS while - * changing the baudrate of chip and host. - */ -- if (qca_is_wcn399x(soc_type) || -- qca_is_wcn6750(soc_type)) -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - hci_uart_set_flow_control(hu, true); -+ break; - -- if (soc_type == QCA_WCN3990) { -+ default: -+ break; -+ } -+ -+ switch (soc_type) { -+ case QCA_WCN3990: - reinit_completion(&qca->drop_ev_comp); - set_bit(QCA_DROP_VENDOR_EVENT, &qca->flags); -+ break; -+ -+ default: -+ break; - } - - qca_baudrate = qca_get_baudrate_value(speed); -@@ -1443,11 +1486,23 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) - host_set_baudrate(hu, speed); - - error: -- if (qca_is_wcn399x(soc_type) || -- qca_is_wcn6750(soc_type)) -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - hci_uart_set_flow_control(hu, false); -+ break; - -- if (soc_type == QCA_WCN3990) { -+ default: -+ break; -+ } -+ -+ switch (soc_type) { -+ case QCA_WCN3990: - /* Wait for the controller to send the vendor event - * for the baudrate change command. - */ -@@ -1459,6 +1514,10 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) - } - - clear_bit(QCA_DROP_VENDOR_EVENT, &qca->flags); -+ break; -+ -+ default: -+ break; - } - } - -@@ -1620,12 +1679,20 @@ static int qca_regulator_init(struct hci_uart *hu) - } - } - -- if (qca_is_wcn399x(soc_type)) { -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: - /* Forcefully enable wcn399x to enter in to boot mode. */ - host_set_baudrate(hu, 2400); - ret = qca_send_power_pulse(hu, false); - if (ret) - return ret; -+ break; -+ -+ default: -+ break; - } - - /* For wcn6750 need to enable gpio bt_en */ -@@ -1642,10 +1709,18 @@ static int qca_regulator_init(struct hci_uart *hu) - - qca_set_speed(hu, QCA_INIT_SPEED); - -- if (qca_is_wcn399x(soc_type)) { -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: - ret = qca_send_power_pulse(hu, true); - if (ret) - return ret; -+ break; -+ -+ default: -+ break; - } - - /* Now the device is in ready state to communicate with host. -@@ -1679,10 +1754,18 @@ static int qca_power_on(struct hci_dev *hdev) - if (!hu->serdev) - return 0; - -- if (qca_is_wcn399x(soc_type) || -- qca_is_wcn6750(soc_type)) { -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - ret = qca_regulator_init(hu); -- } else { -+ break; -+ -+ default: - qcadev = serdev_device_get_drvdata(hu->serdev); - if (qcadev->bt_en) { - gpiod_set_value_cansleep(qcadev->bt_en, 1); -@@ -1705,6 +1788,7 @@ static int qca_setup(struct hci_uart *hu) - const char *firmware_name = qca_get_firmware_name(hu); - int ret; - struct qca_btsoc_version ver; -+ const char *soc_name; - - ret = qca_check_speeds(hu); - if (ret) -@@ -1719,9 +1803,30 @@ static int qca_setup(struct hci_uart *hu) - */ - set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); - -- bt_dev_info(hdev, "setting up %s", -- qca_is_wcn399x(soc_type) ? "wcn399x" : -- (soc_type == QCA_WCN6750) ? "wcn6750" : "ROME/QCA6390"); -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ soc_name = "wcn399x"; -+ break; -+ -+ case QCA_WCN6750: -+ soc_name = "wcn6750"; -+ break; -+ -+ case QCA_WCN6855: -+ soc_name = "wcn6855"; -+ break; -+ -+ case QCA_WCN7850: -+ soc_name = "wcn7850"; -+ break; -+ -+ default: -+ soc_name = "ROME/QCA6390"; -+ } -+ bt_dev_info(hdev, "setting up %s", soc_name); - - qca->memdump_state = QCA_MEMDUMP_IDLE; - -@@ -1732,15 +1837,33 @@ static int qca_setup(struct hci_uart *hu) - - clear_bit(QCA_SSR_TRIGGERED, &qca->flags); - -- if (qca_is_wcn399x(soc_type) || -- qca_is_wcn6750(soc_type)) { -- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: -+ -+ /* Set BDA quirk bit for reading BDA value from fwnode property -+ * only if that property exist in DT. -+ */ -+ if (fwnode_property_present(dev_fwnode(hdev->dev.parent), "local-bd-address")) { -+ set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); -+ bt_dev_info(hdev, "setting quirk bit to read BDA from fwnode later"); -+ } else { -+ bt_dev_dbg(hdev, "local-bd-address` is not present in the devicetree so not setting quirk bit for BDA"); -+ } -+ - hci_set_aosp_capable(hdev); - - ret = qca_read_soc_version(hdev, &ver, soc_type); - if (ret) - goto out; -- } else { -+ break; -+ -+ default: - qca_set_speed(hu, QCA_INIT_SPEED); - } - -@@ -1754,8 +1877,17 @@ static int qca_setup(struct hci_uart *hu) - qca_baudrate = qca_get_baudrate_value(speed); - } - -- if (!(qca_is_wcn399x(soc_type) || -- qca_is_wcn6750(soc_type))) { -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: -+ break; -+ -+ default: - /* Get QCA version information */ - ret = qca_read_soc_version(hdev, &ver, soc_type); - if (ret) -@@ -1824,7 +1956,18 @@ static const struct hci_uart_proto qca_proto = { - .dequeue = qca_dequeue, - }; - --static const struct qca_device_data qca_soc_data_wcn3990 = { -+static const struct qca_device_data qca_soc_data_wcn3988 __maybe_unused = { -+ .soc_type = QCA_WCN3988, -+ .vregs = (struct qca_vreg []) { -+ { "vddio", 15000 }, -+ { "vddxo", 80000 }, -+ { "vddrf", 300000 }, -+ { "vddch0", 450000 }, -+ }, -+ .num_vregs = 4, -+}; -+ -+static const struct qca_device_data qca_soc_data_wcn3990 __maybe_unused = { - .soc_type = QCA_WCN3990, - .vregs = (struct qca_vreg []) { - { "vddio", 15000 }, -@@ -1835,7 +1978,7 @@ static const struct qca_device_data qca_soc_data_wcn3990 = { - .num_vregs = 4, - }; - --static const struct qca_device_data qca_soc_data_wcn3991 = { -+static const struct qca_device_data qca_soc_data_wcn3991 __maybe_unused = { - .soc_type = QCA_WCN3991, - .vregs = (struct qca_vreg []) { - { "vddio", 15000 }, -@@ -1847,7 +1990,7 @@ static const struct qca_device_data qca_soc_data_wcn3991 = { - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, - }; - --static const struct qca_device_data qca_soc_data_wcn3998 = { -+static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = { - .soc_type = QCA_WCN3998, - .vregs = (struct qca_vreg []) { - { "vddio", 10000 }, -@@ -1858,13 +2001,13 @@ static const struct qca_device_data qca_soc_data_wcn3998 = { - .num_vregs = 4, - }; - --static const struct qca_device_data qca_soc_data_qca6390 = { -+static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { - .soc_type = QCA_QCA6390, - .num_vregs = 0, - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, - }; - --static const struct qca_device_data qca_soc_data_wcn6750 = { -+static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { - .soc_type = QCA_WCN6750, - .vregs = (struct qca_vreg []) { - { "vddio", 5000 }, -@@ -1881,6 +2024,34 @@ static const struct qca_device_data qca_soc_data_wcn6750 = { - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, - }; - -+static const struct qca_device_data qca_soc_data_wcn6855 = { -+ .soc_type = QCA_WCN6855, -+ .vregs = (struct qca_vreg []) { -+ { "vddio", 5000 }, -+ { "vddbtcxmx", 126000 }, -+ { "vddrfacmn", 12500 }, -+ { "vddrfa0p8", 102000 }, -+ { "vddrfa1p7", 302000 }, -+ { "vddrfa1p2", 257000 }, -+ }, -+ .num_vregs = 6, -+ .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, -+}; -+ -+static const struct qca_device_data qca_soc_data_wcn7850 __maybe_unused = { -+ .soc_type = QCA_WCN7850, -+ .vregs = (struct qca_vreg []) { -+ { "vddio", 5000 }, -+ { "vddaon", 26000 }, -+ { "vdddig", 126000 }, -+ { "vddrfa0p8", 102000 }, -+ { "vddrfa1p2", 257000 }, -+ { "vddrfa1p9", 302000 }, -+ }, -+ .num_vregs = 6, -+ .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, -+}; -+ - static void qca_power_shutdown(struct hci_uart *hu) - { - struct qca_serdev *qcadev; -@@ -1906,11 +2077,18 @@ static void qca_power_shutdown(struct hci_uart *hu) - - qcadev = serdev_device_get_drvdata(hu->serdev); - -- if (qca_is_wcn399x(soc_type)) { -+ switch (soc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: - host_set_baudrate(hu, 2400); - qca_send_power_pulse(hu, false); - qca_regulator_disable(qcadev); -- } else if (soc_type == QCA_WCN6750) { -+ break; -+ -+ case QCA_WCN6750: -+ case QCA_WCN6855: - gpiod_set_value_cansleep(qcadev->bt_en, 0); - msleep(100); - qca_regulator_disable(qcadev); -@@ -1918,7 +2096,9 @@ static void qca_power_shutdown(struct hci_uart *hu) - sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); - bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); - } -- } else if (qcadev->bt_en) { -+ break; -+ -+ default: - gpiod_set_value_cansleep(qcadev->bt_en, 0); - } - -@@ -2043,10 +2223,19 @@ static int qca_serdev_probe(struct serdev_device *serdev) - if (!qcadev->oper_speed) - BT_DBG("UART will pick default operating speed"); - -- if (data && -- (qca_is_wcn399x(data->soc_type) || -- qca_is_wcn6750(data->soc_type))) { -+ if (data) - qcadev->btsoc_type = data->soc_type; -+ else -+ qcadev->btsoc_type = QCA_ROME; -+ -+ switch (qcadev->btsoc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: - qcadev->bt_power = devm_kzalloc(&serdev->dev, - sizeof(struct qca_power), - GFP_KERNEL); -@@ -2065,14 +2254,19 @@ static int qca_serdev_probe(struct serdev_device *serdev) - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); -- if (IS_ERR_OR_NULL(qcadev->bt_en) && data->soc_type == QCA_WCN6750) { -+ if (IS_ERR_OR_NULL(qcadev->bt_en) && -+ (data->soc_type == QCA_WCN6750 || -+ data->soc_type == QCA_WCN6855)) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - power_ctrl_enabled = false; - } - - qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", - GPIOD_IN); -- if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && data->soc_type == QCA_WCN6750) -+ if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && -+ (data->soc_type == QCA_WCN6750 || -+ data->soc_type == QCA_WCN6855 || -+ data->soc_type == QCA_WCN7850)) - dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); - - qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); -@@ -2086,12 +2280,9 @@ static int qca_serdev_probe(struct serdev_device *serdev) - BT_ERR("wcn3990 serdev registration failed"); - return err; - } -- } else { -- if (data) -- qcadev->btsoc_type = data->soc_type; -- else -- qcadev->btsoc_type = QCA_ROME; -+ break; - -+ default: - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (IS_ERR_OR_NULL(qcadev->bt_en)) { -@@ -2147,12 +2338,24 @@ static void qca_serdev_remove(struct serdev_device *serdev) - struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); - struct qca_power *power = qcadev->bt_power; - -- if ((qca_is_wcn399x(qcadev->btsoc_type) || -- qca_is_wcn6750(qcadev->btsoc_type)) && -- power->vregs_on) -- qca_power_shutdown(&qcadev->serdev_hu); -- else if (qcadev->susclk) -- clk_disable_unprepare(qcadev->susclk); -+ switch (qcadev->btsoc_type) { -+ case QCA_WCN3988: -+ case QCA_WCN3990: -+ case QCA_WCN3991: -+ case QCA_WCN3998: -+ case QCA_WCN6750: -+ case QCA_WCN6855: -+ case QCA_WCN7850: -+ if (power->vregs_on) { -+ qca_power_shutdown(&qcadev->serdev_hu); -+ break; -+ } -+ fallthrough; -+ -+ default: -+ if (qcadev->susclk) -+ clk_disable_unprepare(qcadev->susclk); -+ } - - hci_uart_unregister_device(&qcadev->serdev_hu); - } -@@ -2329,10 +2532,13 @@ static const struct of_device_id qca_bluetooth_of_match[] = { - { .compatible = "qcom,qca6174-bt" }, - { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390}, - { .compatible = "qcom,qca9377-bt" }, -+ { .compatible = "qcom,wcn3988-bt", .data = &qca_soc_data_wcn3988}, - { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, - { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, - { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, - { .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750}, -+ { .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855}, -+ { .compatible = "qcom,wcn7850-bt", .data = &qca_soc_data_wcn7850}, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); -diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c -index 422d782475532..dcacc5064d339 100644 ---- a/drivers/clk/tegra/clk-tegra20.c -+++ b/drivers/clk/tegra/clk-tegra20.c -@@ -21,24 +21,24 @@ - #define MISC_CLK_ENB 0x48 - - #define OSC_CTRL 0x50 --#define OSC_CTRL_OSC_FREQ_MASK (3<<30) --#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) --#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) --#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) --#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) --#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) -- --#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28) --#define OSC_CTRL_PLL_REF_DIV_1 (0<<28) --#define OSC_CTRL_PLL_REF_DIV_2 (1<<28) --#define OSC_CTRL_PLL_REF_DIV_4 (2<<28) -+#define OSC_CTRL_OSC_FREQ_MASK (3u<<30) -+#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30) -+#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30) -+#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30) -+#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30) -+#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK) -+ -+#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28) -+#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28) -+#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28) -+#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28) - - #define OSC_FREQ_DET 0x58 --#define OSC_FREQ_DET_TRIG (1<<31) -+#define OSC_FREQ_DET_TRIG (1u<<31) - - #define OSC_FREQ_DET_STATUS 0x5c --#define OSC_FREQ_DET_BUSY (1<<31) --#define OSC_FREQ_DET_CNT_MASK 0xFFFF -+#define OSC_FREQ_DET_BUSYu (1<<31) -+#define OSC_FREQ_DET_CNT_MASK 0xFFFFu - - #define TEGRA20_CLK_PERIPH_BANKS 3 - -diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c -index abdd26f7d04c9..5771f3fc6115d 100644 ---- a/drivers/cpufreq/intel_pstate.c -+++ b/drivers/cpufreq/intel_pstate.c -@@ -2952,6 +2952,9 @@ static void intel_cpufreq_adjust_perf(unsigned int cpunum, - if (min_pstate < cpu->min_perf_ratio) - min_pstate = cpu->min_perf_ratio; - -+ if (min_pstate > cpu->max_perf_ratio) -+ min_pstate = cpu->max_perf_ratio; -+ - max_pstate = min(cap_pstate, cpu->max_perf_ratio); - if (max_pstate < min_pstate) - max_pstate = min_pstate; -diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c -index f383f219ed008..7082a5a6814a4 100644 ---- a/drivers/dma/fsl-qdma.c -+++ b/drivers/dma/fsl-qdma.c -@@ -109,6 +109,7 @@ - #define FSL_QDMA_CMD_WTHROTL_OFFSET 20 - #define FSL_QDMA_CMD_DSEN_OFFSET 19 - #define FSL_QDMA_CMD_LWC_OFFSET 16 -+#define FSL_QDMA_CMD_PF BIT(17) - - /* Field definition for Descriptor status */ - #define QDMA_CCDF_STATUS_RTE BIT(5) -@@ -384,7 +385,8 @@ static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp, - qdma_csgf_set_f(csgf_dest, len); - /* Descriptor Buffer */ - cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE << -- FSL_QDMA_CMD_RWTTYPE_OFFSET); -+ FSL_QDMA_CMD_RWTTYPE_OFFSET) | -+ FSL_QDMA_CMD_PF; - sdf->data = QDMA_SDDF_CMD(cmd); - - cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE << -@@ -1201,10 +1203,6 @@ static int fsl_qdma_probe(struct platform_device *pdev) - if (!fsl_qdma->queue) - return -ENOMEM; - -- ret = fsl_qdma_irq_init(pdev, fsl_qdma); -- if (ret) -- return ret; -- - fsl_qdma->irq_base = platform_get_irq_byname(pdev, "qdma-queue0"); - if (fsl_qdma->irq_base < 0) - return fsl_qdma->irq_base; -@@ -1243,16 +1241,19 @@ static int fsl_qdma_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, fsl_qdma); - -- ret = dma_async_device_register(&fsl_qdma->dma_dev); -+ ret = fsl_qdma_reg_init(fsl_qdma); - if (ret) { -- dev_err(&pdev->dev, -- "Can't register NXP Layerscape qDMA engine.\n"); -+ dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n"); - return ret; - } - -- ret = fsl_qdma_reg_init(fsl_qdma); -+ ret = fsl_qdma_irq_init(pdev, fsl_qdma); -+ if (ret) -+ return ret; -+ -+ ret = dma_async_device_register(&fsl_qdma->dma_dev); - if (ret) { -- dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n"); -+ dev_err(&pdev->dev, "Can't register NXP Layerscape qDMA engine.\n"); - return ret; - } - -diff --git a/drivers/dma/ptdma/ptdma-dmaengine.c b/drivers/dma/ptdma/ptdma-dmaengine.c -index 1aa65e5de0f3a..f792407348077 100644 ---- a/drivers/dma/ptdma/ptdma-dmaengine.c -+++ b/drivers/dma/ptdma/ptdma-dmaengine.c -@@ -385,8 +385,6 @@ int pt_dmaengine_register(struct pt_device *pt) - chan->vc.desc_free = pt_do_cleanup; - vchan_init(&chan->vc, dma_dev); - -- dma_set_mask_and_coherent(pt->dev, DMA_BIT_MASK(64)); -- - ret = dma_async_device_register(dma_dev); - if (ret) - goto err_reg; -diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c -index 3e8d4b51a8140..97bafb5f70389 100644 ---- a/drivers/firmware/efi/capsule-loader.c -+++ b/drivers/firmware/efi/capsule-loader.c -@@ -292,7 +292,7 @@ static int efi_capsule_open(struct inode *inode, struct file *file) - return -ENOMEM; - } - -- cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL); -+ cap_info->phys = kzalloc(sizeof(phys_addr_t), GFP_KERNEL); - if (!cap_info->phys) { - kfree(cap_info->pages); - kfree(cap_info); -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index b7c0e8cc0764f..9077353d1c98d 100644 ---- a/drivers/firmware/efi/efi.c -+++ b/drivers/firmware/efi/efi.c -@@ -185,8 +185,27 @@ static const struct attribute_group efi_subsys_attr_group = { - static struct efivars generic_efivars; - static struct efivar_operations generic_ops; - -+static bool generic_ops_supported(void) -+{ -+ unsigned long name_size; -+ efi_status_t status; -+ efi_char16_t name; -+ efi_guid_t guid; -+ -+ name_size = sizeof(name); -+ -+ status = efi.get_next_variable(&name_size, &name, &guid); -+ if (status == EFI_UNSUPPORTED) -+ return false; -+ -+ return true; -+} -+ - static int generic_ops_register(void) - { -+ if (!generic_ops_supported()) -+ return 0; -+ - generic_ops.get_variable = efi.get_variable; - generic_ops.get_next_variable = efi.get_next_variable; - generic_ops.query_variable_store = efi_query_variable_store; -@@ -200,6 +219,9 @@ static int generic_ops_register(void) - - static void generic_ops_unregister(void) - { -+ if (!generic_ops.get_variable) -+ return; -+ - efivars_unregister(&generic_efivars); - } - -diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile -index b6e1dcb98a64c..473ef18421db0 100644 ---- a/drivers/firmware/efi/libstub/Makefile -+++ b/drivers/firmware/efi/libstub/Makefile -@@ -84,6 +84,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o - lib-$(CONFIG_ARM) += arm32-stub.o - lib-$(CONFIG_ARM64) += arm64-stub.o smbios.o - lib-$(CONFIG_X86) += x86-stub.o -+lib-$(CONFIG_X86_64) += x86-5lvl.o - lib-$(CONFIG_RISCV) += riscv-stub.o - lib-$(CONFIG_LOONGARCH) += loongarch-stub.o - -diff --git a/drivers/firmware/efi/libstub/alignedmem.c b/drivers/firmware/efi/libstub/alignedmem.c -index 1de9878ddd3a2..6b83c492c3b82 100644 ---- a/drivers/firmware/efi/libstub/alignedmem.c -+++ b/drivers/firmware/efi/libstub/alignedmem.c -@@ -22,12 +22,15 @@ - * Return: status code - */ - efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, -- unsigned long max, unsigned long align) -+ unsigned long max, unsigned long align, -+ int memory_type) - { - efi_physical_addr_t alloc_addr; - efi_status_t status; - int slack; - -+ max = min(max, EFI_ALLOC_LIMIT); -+ - if (align < EFI_ALLOC_ALIGN) - align = EFI_ALLOC_ALIGN; - -@@ -36,7 +39,7 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, - slack = align / EFI_PAGE_SIZE - 1; - - status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS, -- EFI_LOADER_DATA, size / EFI_PAGE_SIZE + slack, -+ memory_type, size / EFI_PAGE_SIZE + slack, - &alloc_addr); - if (status != EFI_SUCCESS) - return status; -diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c -index e2f90566b291a..16f15e36f9a7d 100644 ---- a/drivers/firmware/efi/libstub/arm64-stub.c -+++ b/drivers/firmware/efi/libstub/arm64-stub.c -@@ -180,7 +180,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, - * locate the kernel at a randomized offset in physical memory. - */ - status = efi_random_alloc(*reserve_size, min_kimg_align, -- reserve_addr, phys_seed); -+ reserve_addr, phys_seed, -+ EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT); - if (status != EFI_SUCCESS) - efi_warn("efi_random_alloc() failed: 0x%lx\n", status); - } else { -@@ -190,10 +191,11 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, - if (status != EFI_SUCCESS) { - if (!check_image_region((u64)_text, kernel_memsize)) { - efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); -- } else if (IS_ALIGNED((u64)_text, min_kimg_align)) { -+ } else if (IS_ALIGNED((u64)_text, min_kimg_align) && -+ (u64)_end < EFI_ALLOC_LIMIT) { - /* - * Just execute from wherever we were loaded by the -- * UEFI PE/COFF loader if the alignment is suitable. -+ * UEFI PE/COFF loader if the placement is suitable. - */ - *image_addr = (u64)_text; - *reserve_size = 0; -@@ -201,7 +203,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, - } - - status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, -- ULONG_MAX, min_kimg_align); -+ ULONG_MAX, min_kimg_align, -+ EFI_LOADER_CODE); - - if (status != EFI_SUCCESS) { - efi_err("Failed to relocate kernel\n"); -diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c -index 3d9b2469a0dfd..97744822dd951 100644 ---- a/drivers/firmware/efi/libstub/efi-stub-helper.c -+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c -@@ -216,6 +216,8 @@ efi_status_t efi_parse_options(char const *cmdline) - efi_loglevel = CONSOLE_LOGLEVEL_QUIET; - } else if (!strcmp(param, "noinitrd")) { - efi_noinitrd = true; -+ } else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) { -+ efi_no5lvl = true; - } else if (!strcmp(param, "efi") && val) { - efi_nochunk = parse_option_str(val, "nochunk"); - efi_novamap |= parse_option_str(val, "novamap"); -diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h -index 970e86e3aab05..6741f3d900c5a 100644 ---- a/drivers/firmware/efi/libstub/efistub.h -+++ b/drivers/firmware/efi/libstub/efistub.h -@@ -29,6 +29,11 @@ - #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE - #endif - -+#ifndef EFI_ALLOC_LIMIT -+#define EFI_ALLOC_LIMIT ULONG_MAX -+#endif -+ -+extern bool efi_no5lvl; - extern bool efi_nochunk; - extern bool efi_nokaslr; - extern int efi_loglevel; -@@ -415,6 +420,26 @@ union efi_dxe_services_table { - } mixed_mode; - }; - -+typedef union efi_memory_attribute_protocol efi_memory_attribute_protocol_t; -+ -+union efi_memory_attribute_protocol { -+ struct { -+ efi_status_t (__efiapi *get_memory_attributes)( -+ efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64 *); -+ -+ efi_status_t (__efiapi *set_memory_attributes)( -+ efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64); -+ -+ efi_status_t (__efiapi *clear_memory_attributes)( -+ efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64); -+ }; -+ struct { -+ u32 get_memory_attributes; -+ u32 set_memory_attributes; -+ u32 clear_memory_attributes; -+ } mixed_mode; -+}; -+ - typedef union efi_uga_draw_protocol efi_uga_draw_protocol_t; - - union efi_uga_draw_protocol { -@@ -880,7 +905,9 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, - efi_status_t efi_get_random_bytes(unsigned long size, u8 *out); - - efi_status_t efi_random_alloc(unsigned long size, unsigned long align, -- unsigned long *addr, unsigned long random_seed); -+ unsigned long *addr, unsigned long random_seed, -+ int memory_type, unsigned long alloc_min, -+ unsigned long alloc_max); - - efi_status_t efi_random_get_seed(void); - -@@ -907,7 +934,8 @@ efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, - unsigned long max); - - efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, -- unsigned long max, unsigned long align); -+ unsigned long max, unsigned long align, -+ int memory_type); - - efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, - unsigned long *addr, unsigned long min); -diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c -index 45841ef55a9f6..4f1fa302234d8 100644 ---- a/drivers/firmware/efi/libstub/mem.c -+++ b/drivers/firmware/efi/libstub/mem.c -@@ -89,9 +89,12 @@ efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, - efi_physical_addr_t alloc_addr; - efi_status_t status; - -+ max = min(max, EFI_ALLOC_LIMIT); -+ - if (EFI_ALLOC_ALIGN > EFI_PAGE_SIZE) - return efi_allocate_pages_aligned(size, addr, max, -- EFI_ALLOC_ALIGN); -+ EFI_ALLOC_ALIGN, -+ EFI_LOADER_DATA); - - alloc_addr = ALIGN_DOWN(max + 1, EFI_ALLOC_ALIGN) - 1; - status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS, -diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c -index 9fb5869896be7..7ba05719a53ba 100644 ---- a/drivers/firmware/efi/libstub/randomalloc.c -+++ b/drivers/firmware/efi/libstub/randomalloc.c -@@ -16,7 +16,8 @@ - */ - static unsigned long get_entry_num_slots(efi_memory_desc_t *md, - unsigned long size, -- unsigned long align_shift) -+ unsigned long align_shift, -+ u64 alloc_min, u64 alloc_max) - { - unsigned long align = 1UL << align_shift; - u64 first_slot, last_slot, region_end; -@@ -29,11 +30,11 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, - return 0; - - region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, -- (u64)ULONG_MAX); -+ alloc_max); - if (region_end < size) - return 0; - -- first_slot = round_up(md->phys_addr, align); -+ first_slot = round_up(max(md->phys_addr, alloc_min), align); - last_slot = round_down(region_end - size + 1, align); - - if (first_slot > last_slot) -@@ -53,7 +54,10 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, - efi_status_t efi_random_alloc(unsigned long size, - unsigned long align, - unsigned long *addr, -- unsigned long random_seed) -+ unsigned long random_seed, -+ int memory_type, -+ unsigned long alloc_min, -+ unsigned long alloc_max) - { - unsigned long total_slots = 0, target_slot; - unsigned long total_mirrored_slots = 0; -@@ -75,7 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size, - efi_memory_desc_t *md = (void *)map->map + map_offset; - unsigned long slots; - -- slots = get_entry_num_slots(md, size, ilog2(align)); -+ slots = get_entry_num_slots(md, size, ilog2(align), alloc_min, -+ alloc_max); - MD_NUM_SLOTS(md) = slots; - total_slots += slots; - if (md->attribute & EFI_MEMORY_MORE_RELIABLE) -@@ -118,7 +123,7 @@ efi_status_t efi_random_alloc(unsigned long size, - pages = size / EFI_PAGE_SIZE; - - status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, -- EFI_LOADER_DATA, pages, &target); -+ memory_type, pages, &target); - if (status == EFI_SUCCESS) - *addr = target; - break; -diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c -new file mode 100644 -index 0000000000000..479dd445acdcf ---- /dev/null -+++ b/drivers/firmware/efi/libstub/x86-5lvl.c -@@ -0,0 +1,95 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+ -+#include -+#include -+#include -+ -+#include "efistub.h" -+#include "x86-stub.h" -+ -+bool efi_no5lvl; -+ -+static void (*la57_toggle)(void *cr3); -+ -+static const struct desc_struct gdt[] = { -+ [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), -+ [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), -+}; -+ -+/* -+ * Enabling (or disabling) 5 level paging is tricky, because it can only be -+ * done from 32-bit mode with paging disabled. This means not only that the -+ * code itself must be running from 32-bit addressable physical memory, but -+ * also that the root page table must be 32-bit addressable, as programming -+ * a 64-bit value into CR3 when running in 32-bit mode is not supported. -+ */ -+efi_status_t efi_setup_5level_paging(void) -+{ -+ u8 tmpl_size = (u8 *)&trampoline_ljmp_imm_offset - (u8 *)&trampoline_32bit_src; -+ efi_status_t status; -+ u8 *la57_code; -+ -+ if (!efi_is_64bit()) -+ return EFI_SUCCESS; -+ -+ /* check for 5 level paging support */ -+ if (native_cpuid_eax(0) < 7 || -+ !(native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) -+ return EFI_SUCCESS; -+ -+ /* allocate some 32-bit addressable memory for code and a page table */ -+ status = efi_allocate_pages(2 * PAGE_SIZE, (unsigned long *)&la57_code, -+ U32_MAX); -+ if (status != EFI_SUCCESS) -+ return status; -+ -+ la57_toggle = memcpy(la57_code, trampoline_32bit_src, tmpl_size); -+ memset(la57_code + tmpl_size, 0x90, PAGE_SIZE - tmpl_size); -+ -+ /* -+ * To avoid the need to allocate a 32-bit addressable stack, the -+ * trampoline uses a LJMP instruction to switch back to long mode. -+ * LJMP takes an absolute destination address, which needs to be -+ * fixed up at runtime. -+ */ -+ *(u32 *)&la57_code[trampoline_ljmp_imm_offset] += (unsigned long)la57_code; -+ -+ efi_adjust_memory_range_protection((unsigned long)la57_toggle, PAGE_SIZE); -+ -+ return EFI_SUCCESS; -+} -+ -+void efi_5level_switch(void) -+{ -+ bool want_la57 = IS_ENABLED(CONFIG_X86_5LEVEL) && !efi_no5lvl; -+ bool have_la57 = native_read_cr4() & X86_CR4_LA57; -+ bool need_toggle = want_la57 ^ have_la57; -+ u64 *pgt = (void *)la57_toggle + PAGE_SIZE; -+ u64 *cr3 = (u64 *)__native_read_cr3(); -+ u64 *new_cr3; -+ -+ if (!la57_toggle || !need_toggle) -+ return; -+ -+ if (!have_la57) { -+ /* -+ * 5 level paging will be enabled, so a root level page needs -+ * to be allocated from the 32-bit addressable physical region, -+ * with its first entry referring to the existing hierarchy. -+ */ -+ new_cr3 = memset(pgt, 0, PAGE_SIZE); -+ new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; -+ } else { -+ /* take the new root table pointer from the current entry #0 */ -+ new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); -+ -+ /* copy the new root table if it is not 32-bit addressable */ -+ if ((u64)new_cr3 > U32_MAX) -+ new_cr3 = memcpy(pgt, new_cr3, PAGE_SIZE); -+ } -+ -+ native_load_gdt(&(struct desc_ptr){ sizeof(gdt) - 1, (u64)gdt }); -+ -+ la57_toggle(new_cr3); -+} -diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c -index 4f0152b11a890..784e1b2ae5ccd 100644 ---- a/drivers/firmware/efi/libstub/x86-stub.c -+++ b/drivers/firmware/efi/libstub/x86-stub.c -@@ -15,16 +15,16 @@ - #include - #include - #include -+#include -+#include - - #include "efistub.h" -- --/* Maximum physical address for 64-bit kernel with 4-level paging */ --#define MAXMEM_X86_64_4LEVEL (1ull << 46) -+#include "x86-stub.h" - - const efi_system_table_t *efi_system_table; - const efi_dxe_services_table_t *efi_dxe_table; --extern u32 image_offset; - static efi_loaded_image_t *image = NULL; -+static efi_memory_attribute_protocol_t *memattr; - - static efi_status_t - preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) -@@ -212,8 +212,8 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params) - } - } - --static void --adjust_memory_range_protection(unsigned long start, unsigned long size) -+efi_status_t efi_adjust_memory_range_protection(unsigned long start, -+ unsigned long size) - { - efi_status_t status; - efi_gcd_memory_space_desc_t desc; -@@ -221,12 +221,22 @@ adjust_memory_range_protection(unsigned long start, unsigned long size) - unsigned long rounded_start, rounded_end; - unsigned long unprotect_start, unprotect_size; - -- if (efi_dxe_table == NULL) -- return; -- - rounded_start = rounddown(start, EFI_PAGE_SIZE); - rounded_end = roundup(start + size, EFI_PAGE_SIZE); - -+ if (memattr != NULL) { -+ status = efi_call_proto(memattr, clear_memory_attributes, -+ rounded_start, -+ rounded_end - rounded_start, -+ EFI_MEMORY_XP); -+ if (status != EFI_SUCCESS) -+ efi_warn("Failed to clear EFI_MEMORY_XP attribute\n"); -+ return status; -+ } -+ -+ if (efi_dxe_table == NULL) -+ return EFI_SUCCESS; -+ - /* - * Don't modify memory region attributes, they are - * already suitable, to lower the possibility to -@@ -238,7 +248,7 @@ adjust_memory_range_protection(unsigned long start, unsigned long size) - status = efi_dxe_call(get_memory_space_descriptor, start, &desc); - - if (status != EFI_SUCCESS) -- return; -+ break; - - next = desc.base_address + desc.length; - -@@ -263,69 +273,26 @@ adjust_memory_range_protection(unsigned long start, unsigned long size) - unprotect_start, - unprotect_start + unprotect_size, - status); -+ break; - } - } -+ return EFI_SUCCESS; - } - --/* -- * Trampoline takes 2 pages and can be loaded in first megabyte of memory -- * with its end placed between 128k and 640k where BIOS might start. -- * (see arch/x86/boot/compressed/pgtable_64.c) -- * -- * We cannot find exact trampoline placement since memory map -- * can be modified by UEFI, and it can alter the computed address. -- */ -- --#define TRAMPOLINE_PLACEMENT_BASE ((128 - 8)*1024) --#define TRAMPOLINE_PLACEMENT_SIZE (640*1024 - (128 - 8)*1024) -- --void startup_32(struct boot_params *boot_params); -- --static void --setup_memory_protection(unsigned long image_base, unsigned long image_size) -+static efi_char16_t *efistub_fw_vendor(void) - { -- /* -- * Allow execution of possible trampoline used -- * for switching between 4- and 5-level page tables -- * and relocated kernel image. -- */ -- -- adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE, -- TRAMPOLINE_PLACEMENT_SIZE); -+ unsigned long vendor = efi_table_attr(efi_system_table, fw_vendor); - --#ifdef CONFIG_64BIT -- if (image_base != (unsigned long)startup_32) -- adjust_memory_range_protection(image_base, image_size); --#else -- /* -- * Clear protection flags on a whole range of possible -- * addresses used for KASLR. We don't need to do that -- * on x86_64, since KASLR/extraction is performed after -- * dedicated identity page tables are built and we only -- * need to remove possible protection on relocated image -- * itself disregarding further relocations. -- */ -- adjust_memory_range_protection(LOAD_PHYSICAL_ADDR, -- KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR); --#endif -+ return (efi_char16_t *)vendor; - } - - static const efi_char16_t apple[] = L"Apple"; - --static void setup_quirks(struct boot_params *boot_params, -- unsigned long image_base, -- unsigned long image_size) -+static void setup_quirks(struct boot_params *boot_params) - { -- efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long) -- efi_table_attr(efi_system_table, fw_vendor); -- -- if (!memcmp(fw_vendor, apple, sizeof(apple))) { -- if (IS_ENABLED(CONFIG_APPLE_PROPERTIES)) -- retrieve_apple_device_properties(boot_params); -- } -- -- if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) -- setup_memory_protection(image_base, image_size); -+ if (IS_ENABLED(CONFIG_APPLE_PROPERTIES) && -+ !memcmp(efistub_fw_vendor(), apple, sizeof(apple))) -+ retrieve_apple_device_properties(boot_params); - } - - /* -@@ -478,7 +445,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, - } - - image_base = efi_table_attr(image, image_base); -- image_offset = (void *)startup_32 - image_base; - - status = efi_allocate_pages(sizeof(struct boot_params), - (unsigned long *)&boot_params, ULONG_MAX); -@@ -760,85 +726,139 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) - return EFI_SUCCESS; - } - -+static bool have_unsupported_snp_features(void) -+{ -+ u64 unsupported; -+ -+ unsupported = snp_get_unsupported_features(sev_get_status()); -+ if (unsupported) { -+ efi_err("Unsupported SEV-SNP features detected: 0x%llx\n", -+ unsupported); -+ return true; -+ } -+ return false; -+} -+ -+static void efi_get_seed(void *seed, int size) -+{ -+ efi_get_random_bytes(size, seed); -+ -+ /* -+ * This only updates seed[0] when running on 32-bit, but in that case, -+ * seed[1] is not used anyway, as there is no virtual KASLR on 32-bit. -+ */ -+ *(unsigned long *)seed ^= kaslr_get_random_long("EFI"); -+} -+ -+static void error(char *str) -+{ -+ efi_warn("Decompression failed: %s\n", str); -+} -+ -+static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) -+{ -+ unsigned long virt_addr = LOAD_PHYSICAL_ADDR; -+ unsigned long addr, alloc_size, entry; -+ efi_status_t status; -+ u32 seed[2] = {}; -+ -+ /* determine the required size of the allocation */ -+ alloc_size = ALIGN(max_t(unsigned long, output_len, kernel_total_size), -+ MIN_KERNEL_ALIGN); -+ -+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) { -+ u64 range = KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR - kernel_total_size; -+ static const efi_char16_t ami[] = L"American Megatrends"; -+ -+ efi_get_seed(seed, sizeof(seed)); -+ -+ virt_addr += (range * seed[1]) >> 32; -+ virt_addr &= ~(CONFIG_PHYSICAL_ALIGN - 1); -+ -+ /* -+ * Older Dell systems with AMI UEFI firmware v2.0 may hang -+ * while decompressing the kernel if physical address -+ * randomization is enabled. -+ * -+ * https://bugzilla.kernel.org/show_bug.cgi?id=218173 -+ */ -+ if (efi_system_table->hdr.revision <= EFI_2_00_SYSTEM_TABLE_REVISION && -+ !memcmp(efistub_fw_vendor(), ami, sizeof(ami))) { -+ efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n"); -+ seed[0] = 0; -+ } -+ -+ boot_params_ptr->hdr.loadflags |= KASLR_FLAG; -+ } -+ -+ status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr, -+ seed[0], EFI_LOADER_CODE, -+ LOAD_PHYSICAL_ADDR, -+ EFI_X86_KERNEL_ALLOC_LIMIT); -+ if (status != EFI_SUCCESS) -+ return status; -+ -+ entry = decompress_kernel((void *)addr, virt_addr, error); -+ if (entry == ULONG_MAX) { -+ efi_free(alloc_size, addr); -+ return EFI_LOAD_ERROR; -+ } -+ -+ *kernel_entry = addr + entry; -+ -+ return efi_adjust_memory_range_protection(addr, kernel_total_size); -+} -+ -+static void __noreturn enter_kernel(unsigned long kernel_addr, -+ struct boot_params *boot_params) -+{ -+ /* enter decompressed kernel with boot_params pointer in RSI/ESI */ -+ asm("jmp *%0"::"r"(kernel_addr), "S"(boot_params)); -+ -+ unreachable(); -+} -+ - /* -- * On success, we return the address of startup_32, which has potentially been -- * relocated by efi_relocate_kernel. -- * On failure, we exit to the firmware via efi_exit instead of returning. -+ * On success, this routine will jump to the relocated image directly and never -+ * return. On failure, it will exit to the firmware via efi_exit() instead of -+ * returning. - */ --asmlinkage unsigned long efi_main(efi_handle_t handle, -- efi_system_table_t *sys_table_arg, -- struct boot_params *boot_params) -+void __noreturn efi_stub_entry(efi_handle_t handle, -+ efi_system_table_t *sys_table_arg, -+ struct boot_params *boot_params) - { -- unsigned long bzimage_addr = (unsigned long)startup_32; -- unsigned long buffer_start, buffer_end; -+ efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; - struct setup_header *hdr = &boot_params->hdr; - const struct linux_efi_initrd *initrd = NULL; -+ unsigned long kernel_entry; - efi_status_t status; - -+ boot_params_ptr = boot_params; -+ - efi_system_table = sys_table_arg; - /* Check if we were booted by the EFI firmware */ - if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) - efi_exit(handle, EFI_INVALID_PARAMETER); - -- efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); -- if (efi_dxe_table && -- efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { -- efi_warn("Ignoring DXE services table: invalid signature\n"); -- efi_dxe_table = NULL; -+ if (have_unsupported_snp_features()) -+ efi_exit(handle, EFI_UNSUPPORTED); -+ -+ if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) { -+ efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); -+ if (efi_dxe_table && -+ efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { -+ efi_warn("Ignoring DXE services table: invalid signature\n"); -+ efi_dxe_table = NULL; -+ } - } - -- /* -- * If the kernel isn't already loaded at a suitable address, -- * relocate it. -- * -- * It must be loaded above LOAD_PHYSICAL_ADDR. -- * -- * The maximum address for 64-bit is 1 << 46 for 4-level paging. This -- * is defined as the macro MAXMEM, but unfortunately that is not a -- * compile-time constant if 5-level paging is configured, so we instead -- * define our own macro for use here. -- * -- * For 32-bit, the maximum address is complicated to figure out, for -- * now use KERNEL_IMAGE_SIZE, which will be 512MiB, the same as what -- * KASLR uses. -- * -- * Also relocate it if image_offset is zero, i.e. the kernel wasn't -- * loaded by LoadImage, but rather by a bootloader that called the -- * handover entry. The reason we must always relocate in this case is -- * to handle the case of systemd-boot booting a unified kernel image, -- * which is a PE executable that contains the bzImage and an initrd as -- * COFF sections. The initrd section is placed after the bzImage -- * without ensuring that there are at least init_size bytes available -- * for the bzImage, and thus the compressed kernel's startup code may -- * overwrite the initrd unless it is moved out of the way. -- */ -+ /* grab the memory attributes protocol if it exists */ -+ efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr); - -- buffer_start = ALIGN(bzimage_addr - image_offset, -- hdr->kernel_alignment); -- buffer_end = buffer_start + hdr->init_size; -- -- if ((buffer_start < LOAD_PHYSICAL_ADDR) || -- (IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) || -- (IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) || -- (image_offset == 0)) { -- extern char _bss[]; -- -- status = efi_relocate_kernel(&bzimage_addr, -- (unsigned long)_bss - bzimage_addr, -- hdr->init_size, -- hdr->pref_address, -- hdr->kernel_alignment, -- LOAD_PHYSICAL_ADDR); -- if (status != EFI_SUCCESS) { -- efi_err("efi_relocate_kernel() failed!\n"); -- goto fail; -- } -- /* -- * Now that we've copied the kernel elsewhere, we no longer -- * have a set up block before startup_32(), so reset image_offset -- * to zero in case it was set earlier. -- */ -- image_offset = 0; -+ status = efi_setup_5level_paging(); -+ if (status != EFI_SUCCESS) { -+ efi_err("efi_setup_5level_paging() failed!\n"); -+ goto fail; - } - - #ifdef CONFIG_CMDLINE_BOOL -@@ -858,6 +878,12 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, - } - } - -+ status = efi_decompress_kernel(&kernel_entry); -+ if (status != EFI_SUCCESS) { -+ efi_err("Failed to decompress kernel\n"); -+ goto fail; -+ } -+ - /* - * At this point, an initrd may already have been loaded by the - * bootloader and passed via bootparams. We permit an initrd loaded -@@ -897,7 +923,7 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, - - setup_efi_pci(boot_params); - -- setup_quirks(boot_params, bzimage_addr, buffer_end - buffer_start); -+ setup_quirks(boot_params); - - status = exit_boot(boot_params, handle); - if (status != EFI_SUCCESS) { -@@ -905,9 +931,38 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, - goto fail; - } - -- return bzimage_addr; -+ /* -+ * Call the SEV init code while still running with the firmware's -+ * GDT/IDT, so #VC exceptions will be handled by EFI. -+ */ -+ sev_enable(boot_params); -+ -+ efi_5level_switch(); -+ -+ enter_kernel(kernel_entry, boot_params); - fail: -- efi_err("efi_main() failed!\n"); -+ efi_err("efi_stub_entry() failed!\n"); - - efi_exit(handle, status); - } -+ -+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL -+void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, -+ struct boot_params *boot_params) -+{ -+ extern char _bss[], _ebss[]; -+ -+ memset(_bss, 0, _ebss - _bss); -+ efi_stub_entry(handle, sys_table_arg, boot_params); -+} -+ -+#ifndef CONFIG_EFI_MIXED -+extern __alias(efi_handover_entry) -+void efi32_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, -+ struct boot_params *boot_params); -+ -+extern __alias(efi_handover_entry) -+void efi64_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, -+ struct boot_params *boot_params); -+#endif -+#endif -diff --git a/drivers/firmware/efi/libstub/x86-stub.h b/drivers/firmware/efi/libstub/x86-stub.h -new file mode 100644 -index 0000000000000..1c20e99a64944 ---- /dev/null -+++ b/drivers/firmware/efi/libstub/x86-stub.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#include -+ -+extern void trampoline_32bit_src(void *, bool); -+extern const u16 trampoline_ljmp_imm_offset; -+ -+efi_status_t efi_adjust_memory_range_protection(unsigned long start, -+ unsigned long size); -+ -+#ifdef CONFIG_X86_64 -+efi_status_t efi_setup_5level_paging(void); -+void efi_5level_switch(void); -+#else -+static inline efi_status_t efi_setup_5level_paging(void) { return EFI_SUCCESS; } -+static inline void efi_5level_switch(void) {} -+#endif -diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c -index 0ba9f18312f5b..4ca256bcd6971 100644 ---- a/drivers/firmware/efi/vars.c -+++ b/drivers/firmware/efi/vars.c -@@ -66,19 +66,28 @@ int efivars_register(struct efivars *efivars, - const struct efivar_operations *ops, - struct kobject *kobject) - { -+ int rv; -+ - if (down_interruptible(&efivars_lock)) - return -EINTR; - -+ if (__efivars) { -+ pr_warn("efivars already registered\n"); -+ rv = -EBUSY; -+ goto out; -+ } -+ - efivars->ops = ops; - efivars->kobject = kobject; - - __efivars = efivars; - - pr_info("Registered efivars operations\n"); -- -+ rv = 0; -+out: - up(&efivars_lock); - -- return 0; -+ return rv; - } - EXPORT_SYMBOL_GPL(efivars_register); - -diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c -index e00c333105170..753e7be039e4d 100644 ---- a/drivers/gpio/gpio-74x164.c -+++ b/drivers/gpio/gpio-74x164.c -@@ -127,8 +127,6 @@ static int gen_74x164_probe(struct spi_device *spi) - if (IS_ERR(chip->gpiod_oe)) - return PTR_ERR(chip->gpiod_oe); - -- gpiod_set_value_cansleep(chip->gpiod_oe, 1); -- - spi_set_drvdata(spi, chip); - - chip->gpio_chip.label = spi->modalias; -@@ -153,6 +151,8 @@ static int gen_74x164_probe(struct spi_device *spi) - goto exit_destroy; - } - -+ gpiod_set_value_cansleep(chip->gpiod_oe, 1); -+ - ret = gpiochip_add_data(&chip->gpio_chip, chip); - if (!ret) - return 0; -diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c -index 6d3e3454a6ed6..9d8c783124033 100644 ---- a/drivers/gpio/gpiolib.c -+++ b/drivers/gpio/gpiolib.c -@@ -784,11 +784,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - - ret = gpiochip_irqchip_init_valid_mask(gc); - if (ret) -- goto err_remove_acpi_chip; -+ goto err_free_hogs; - - ret = gpiochip_irqchip_init_hw(gc); - if (ret) -- goto err_remove_acpi_chip; -+ goto err_remove_irqchip_mask; - - ret = gpiochip_add_irqchip(gc, lock_key, request_key); - if (ret) -@@ -813,13 +813,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - gpiochip_irqchip_remove(gc); - err_remove_irqchip_mask: - gpiochip_irqchip_free_valid_mask(gc); --err_remove_acpi_chip: -+err_free_hogs: -+ gpiochip_free_hogs(gc); - acpi_gpiochip_remove(gc); -+ gpiochip_remove_pin_ranges(gc); - err_remove_of_chip: -- gpiochip_free_hogs(gc); - of_gpiochip_remove(gc); - err_free_gpiochip_mask: -- gpiochip_remove_pin_ranges(gc); - gpiochip_free_valid_mask(gc); - if (gdev->dev.release) { - /* release() has been registered by gpiochip_setup_dev() */ -diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile -index 6fdf87a6e240f..6c7b286e1123d 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile -@@ -51,8 +51,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) - -diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -index dc0a6fba7050f..ff1032de4f76d 100644 ---- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -@@ -6925,6 +6925,23 @@ static int si_dpm_enable(struct amdgpu_device *adev) - return 0; - } - -+static int si_set_temperature_range(struct amdgpu_device *adev) -+{ -+ int ret; -+ -+ ret = si_thermal_enable_alert(adev, false); -+ if (ret) -+ return ret; -+ ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); -+ if (ret) -+ return ret; -+ ret = si_thermal_enable_alert(adev, true); -+ if (ret) -+ return ret; -+ -+ return ret; -+} -+ - static void si_dpm_disable(struct amdgpu_device *adev) - { - struct rv7xx_power_info *pi = rv770_get_pi(adev); -@@ -7608,6 +7625,18 @@ static int si_dpm_process_interrupt(struct amdgpu_device *adev, - - static int si_dpm_late_init(void *handle) - { -+ int ret; -+ struct amdgpu_device *adev = (struct amdgpu_device *)handle; -+ -+ if (!adev->pm.dpm_enabled) -+ return 0; -+ -+ ret = si_set_temperature_range(adev); -+ if (ret) -+ return ret; -+#if 0 //TODO ? -+ si_dpm_powergate_uvd(adev, true); -+#endif - return 0; - } - -diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c -index 7098f125b54a9..fd32041f82263 100644 ---- a/drivers/gpu/drm/drm_buddy.c -+++ b/drivers/gpu/drm/drm_buddy.c -@@ -332,6 +332,7 @@ alloc_range_bias(struct drm_buddy *mm, - u64 start, u64 end, - unsigned int order) - { -+ u64 req_size = mm->chunk_size << order; - struct drm_buddy_block *block; - struct drm_buddy_block *buddy; - LIST_HEAD(dfs); -@@ -367,6 +368,15 @@ alloc_range_bias(struct drm_buddy *mm, - if (drm_buddy_block_is_allocated(block)) - continue; - -+ if (block_start < start || block_end > end) { -+ u64 adjusted_start = max(block_start, start); -+ u64 adjusted_end = min(block_end, end); -+ -+ if (round_down(adjusted_end + 1, req_size) <= -+ round_up(adjusted_start, req_size)) -+ continue; -+ } -+ - if (contains(start, end, block_start, block_end) && - order == drm_buddy_block_order(block)) { - /* -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 119544d88b586..fbac39aa38cc4 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -316,32 +316,34 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - goto exit_afbcd; - - if (has_components) { -- ret = component_bind_all(drm->dev, drm); -+ ret = component_bind_all(dev, drm); - if (ret) { - dev_err(drm->dev, "Couldn't bind all components\n"); -+ /* Do not try to unbind */ -+ has_components = false; - goto exit_afbcd; - } - } - - ret = meson_encoder_hdmi_init(priv); - if (ret) -- goto unbind_all; -+ goto exit_afbcd; - - ret = meson_plane_create(priv); - if (ret) -- goto unbind_all; -+ goto exit_afbcd; - - ret = meson_overlay_create(priv); - if (ret) -- goto unbind_all; -+ goto exit_afbcd; - - ret = meson_crtc_create(priv); - if (ret) -- goto unbind_all; -+ goto exit_afbcd; - - ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm); - if (ret) -- goto unbind_all; -+ goto exit_afbcd; - - drm_mode_config_reset(drm); - -@@ -359,15 +361,18 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - - uninstall_irq: - free_irq(priv->vsync_irq, drm); --unbind_all: -- if (has_components) -- component_unbind_all(drm->dev, drm); - exit_afbcd: - if (priv->afbcd.ops) - priv->afbcd.ops->exit(priv); - free_drm: - drm_dev_put(drm); - -+ meson_encoder_hdmi_remove(priv); -+ meson_encoder_cvbs_remove(priv); -+ -+ if (has_components) -+ component_unbind_all(dev, drm); -+ - return ret; - } - -diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -index 3f73b211fa8e3..3407450435e20 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -@@ -294,6 +294,5 @@ void meson_encoder_cvbs_remove(struct meson_drm *priv) - if (priv->encoders[MESON_ENC_CVBS]) { - meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS]; - drm_bridge_remove(&meson_encoder_cvbs->bridge); -- drm_bridge_remove(meson_encoder_cvbs->next_bridge); - } - } -diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -index b14e6e507c61b..03062e7a02b64 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -@@ -472,6 +472,5 @@ void meson_encoder_hdmi_remove(struct meson_drm *priv) - if (priv->encoders[MESON_ENC_HDMI]) { - meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI]; - drm_bridge_remove(&meson_encoder_hdmi->bridge); -- drm_bridge_remove(meson_encoder_hdmi->next_bridge); - } - } -diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c -index 5fc55b9777cbf..6806779f8ecce 100644 ---- a/drivers/gpu/drm/tegra/drm.c -+++ b/drivers/gpu/drm/tegra/drm.c -@@ -1252,9 +1252,26 @@ static int host1x_drm_probe(struct host1x_device *dev) - - drm_mode_config_reset(drm); - -- err = drm_aperture_remove_framebuffers(&tegra_drm_driver); -- if (err < 0) -- goto hub; -+ /* -+ * Only take over from a potential firmware framebuffer if any CRTCs -+ * have been registered. This must not be a fatal error because there -+ * are other accelerators that are exposed via this driver. -+ * -+ * Another case where this happens is on Tegra234 where the display -+ * hardware is no longer part of the host1x complex, so this driver -+ * will not expose any modesetting features. -+ */ -+ if (drm->mode_config.num_crtc > 0) { -+ err = drm_aperture_remove_framebuffers(&tegra_drm_driver); -+ if (err < 0) -+ goto hub; -+ } else { -+ /* -+ * Indicate to userspace that this doesn't expose any display -+ * capabilities. -+ */ -+ drm->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC); -+ } - - err = tegra_drm_fb_init(drm); - if (err < 0) -diff --git a/drivers/infiniband/core/cm_trace.h b/drivers/infiniband/core/cm_trace.h -index e9d282679ef15..944d9071245d2 100644 ---- a/drivers/infiniband/core/cm_trace.h -+++ b/drivers/infiniband/core/cm_trace.h -@@ -16,7 +16,7 @@ - - #include - #include --#include -+#include - - /* - * enum ib_cm_state, from include/rdma/ib_cm.h -diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c -index 0773ca7ace247..067d7f42871ff 100644 ---- a/drivers/infiniband/core/cma.c -+++ b/drivers/infiniband/core/cma.c -@@ -3547,121 +3547,6 @@ static int cma_resolve_ib_addr(struct rdma_id_private *id_priv) - return ret; - } - --static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, -- const struct sockaddr *dst_addr) --{ -- struct sockaddr_storage zero_sock = {}; -- -- if (src_addr && src_addr->sa_family) -- return rdma_bind_addr(id, src_addr); -- -- /* -- * When the src_addr is not specified, automatically supply an any addr -- */ -- zero_sock.ss_family = dst_addr->sa_family; -- if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) { -- struct sockaddr_in6 *src_addr6 = -- (struct sockaddr_in6 *)&zero_sock; -- struct sockaddr_in6 *dst_addr6 = -- (struct sockaddr_in6 *)dst_addr; -- -- src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; -- if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) -- id->route.addr.dev_addr.bound_dev_if = -- dst_addr6->sin6_scope_id; -- } else if (dst_addr->sa_family == AF_IB) { -- ((struct sockaddr_ib *)&zero_sock)->sib_pkey = -- ((struct sockaddr_ib *)dst_addr)->sib_pkey; -- } -- return rdma_bind_addr(id, (struct sockaddr *)&zero_sock); --} -- --/* -- * If required, resolve the source address for bind and leave the id_priv in -- * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior -- * calls made by ULP, a previously bound ID will not be re-bound and src_addr is -- * ignored. -- */ --static int resolve_prepare_src(struct rdma_id_private *id_priv, -- struct sockaddr *src_addr, -- const struct sockaddr *dst_addr) --{ -- int ret; -- -- memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); -- if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { -- /* For a well behaved ULP state will be RDMA_CM_IDLE */ -- ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr); -- if (ret) -- goto err_dst; -- if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, -- RDMA_CM_ADDR_QUERY))) { -- ret = -EINVAL; -- goto err_dst; -- } -- } -- -- if (cma_family(id_priv) != dst_addr->sa_family) { -- ret = -EINVAL; -- goto err_state; -- } -- return 0; -- --err_state: -- cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); --err_dst: -- memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); -- return ret; --} -- --int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, -- const struct sockaddr *dst_addr, unsigned long timeout_ms) --{ -- struct rdma_id_private *id_priv = -- container_of(id, struct rdma_id_private, id); -- int ret; -- -- ret = resolve_prepare_src(id_priv, src_addr, dst_addr); -- if (ret) -- return ret; -- -- if (cma_any_addr(dst_addr)) { -- ret = cma_resolve_loopback(id_priv); -- } else { -- if (dst_addr->sa_family == AF_IB) { -- ret = cma_resolve_ib_addr(id_priv); -- } else { -- /* -- * The FSM can return back to RDMA_CM_ADDR_BOUND after -- * rdma_resolve_ip() is called, eg through the error -- * path in addr_handler(). If this happens the existing -- * request must be canceled before issuing a new one. -- * Since canceling a request is a bit slow and this -- * oddball path is rare, keep track once a request has -- * been issued. The track turns out to be a permanent -- * state since this is the only cancel as it is -- * immediately before rdma_resolve_ip(). -- */ -- if (id_priv->used_resolve_ip) -- rdma_addr_cancel(&id->route.addr.dev_addr); -- else -- id_priv->used_resolve_ip = 1; -- ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, -- &id->route.addr.dev_addr, -- timeout_ms, addr_handler, -- false, id_priv); -- } -- } -- if (ret) -- goto err; -- -- return 0; --err: -- cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); -- return ret; --} --EXPORT_SYMBOL(rdma_resolve_addr); -- - int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse) - { - struct rdma_id_private *id_priv; -@@ -4064,27 +3949,26 @@ int rdma_listen(struct rdma_cm_id *id, int backlog) - } - EXPORT_SYMBOL(rdma_listen); - --int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) -+static int rdma_bind_addr_dst(struct rdma_id_private *id_priv, -+ struct sockaddr *addr, const struct sockaddr *daddr) - { -- struct rdma_id_private *id_priv; -+ struct sockaddr *id_daddr; - int ret; -- struct sockaddr *daddr; - - if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 && - addr->sa_family != AF_IB) - return -EAFNOSUPPORT; - -- id_priv = container_of(id, struct rdma_id_private, id); - if (!cma_comp_exch(id_priv, RDMA_CM_IDLE, RDMA_CM_ADDR_BOUND)) - return -EINVAL; - -- ret = cma_check_linklocal(&id->route.addr.dev_addr, addr); -+ ret = cma_check_linklocal(&id_priv->id.route.addr.dev_addr, addr); - if (ret) - goto err1; - - memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr)); - if (!cma_any_addr(addr)) { -- ret = cma_translate_addr(addr, &id->route.addr.dev_addr); -+ ret = cma_translate_addr(addr, &id_priv->id.route.addr.dev_addr); - if (ret) - goto err1; - -@@ -4104,8 +3988,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) - } - #endif - } -- daddr = cma_dst_addr(id_priv); -- daddr->sa_family = addr->sa_family; -+ id_daddr = cma_dst_addr(id_priv); -+ if (daddr != id_daddr) -+ memcpy(id_daddr, daddr, rdma_addr_size(addr)); -+ id_daddr->sa_family = addr->sa_family; - - ret = cma_get_port(id_priv); - if (ret) -@@ -4121,6 +4007,129 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) - cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE); - return ret; - } -+ -+static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, -+ const struct sockaddr *dst_addr) -+{ -+ struct rdma_id_private *id_priv = -+ container_of(id, struct rdma_id_private, id); -+ struct sockaddr_storage zero_sock = {}; -+ -+ if (src_addr && src_addr->sa_family) -+ return rdma_bind_addr_dst(id_priv, src_addr, dst_addr); -+ -+ /* -+ * When the src_addr is not specified, automatically supply an any addr -+ */ -+ zero_sock.ss_family = dst_addr->sa_family; -+ if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) { -+ struct sockaddr_in6 *src_addr6 = -+ (struct sockaddr_in6 *)&zero_sock; -+ struct sockaddr_in6 *dst_addr6 = -+ (struct sockaddr_in6 *)dst_addr; -+ -+ src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; -+ if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) -+ id->route.addr.dev_addr.bound_dev_if = -+ dst_addr6->sin6_scope_id; -+ } else if (dst_addr->sa_family == AF_IB) { -+ ((struct sockaddr_ib *)&zero_sock)->sib_pkey = -+ ((struct sockaddr_ib *)dst_addr)->sib_pkey; -+ } -+ return rdma_bind_addr_dst(id_priv, (struct sockaddr *)&zero_sock, dst_addr); -+} -+ -+/* -+ * If required, resolve the source address for bind and leave the id_priv in -+ * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior -+ * calls made by ULP, a previously bound ID will not be re-bound and src_addr is -+ * ignored. -+ */ -+static int resolve_prepare_src(struct rdma_id_private *id_priv, -+ struct sockaddr *src_addr, -+ const struct sockaddr *dst_addr) -+{ -+ int ret; -+ -+ if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { -+ /* For a well behaved ULP state will be RDMA_CM_IDLE */ -+ ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr); -+ if (ret) -+ return ret; -+ if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, -+ RDMA_CM_ADDR_QUERY))) -+ return -EINVAL; -+ -+ } else { -+ memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); -+ } -+ -+ if (cma_family(id_priv) != dst_addr->sa_family) { -+ ret = -EINVAL; -+ goto err_state; -+ } -+ return 0; -+ -+err_state: -+ cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); -+ return ret; -+} -+ -+int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, -+ const struct sockaddr *dst_addr, unsigned long timeout_ms) -+{ -+ struct rdma_id_private *id_priv = -+ container_of(id, struct rdma_id_private, id); -+ int ret; -+ -+ ret = resolve_prepare_src(id_priv, src_addr, dst_addr); -+ if (ret) -+ return ret; -+ -+ if (cma_any_addr(dst_addr)) { -+ ret = cma_resolve_loopback(id_priv); -+ } else { -+ if (dst_addr->sa_family == AF_IB) { -+ ret = cma_resolve_ib_addr(id_priv); -+ } else { -+ /* -+ * The FSM can return back to RDMA_CM_ADDR_BOUND after -+ * rdma_resolve_ip() is called, eg through the error -+ * path in addr_handler(). If this happens the existing -+ * request must be canceled before issuing a new one. -+ * Since canceling a request is a bit slow and this -+ * oddball path is rare, keep track once a request has -+ * been issued. The track turns out to be a permanent -+ * state since this is the only cancel as it is -+ * immediately before rdma_resolve_ip(). -+ */ -+ if (id_priv->used_resolve_ip) -+ rdma_addr_cancel(&id->route.addr.dev_addr); -+ else -+ id_priv->used_resolve_ip = 1; -+ ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, -+ &id->route.addr.dev_addr, -+ timeout_ms, addr_handler, -+ false, id_priv); -+ } -+ } -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); -+ return ret; -+} -+EXPORT_SYMBOL(rdma_resolve_addr); -+ -+int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) -+{ -+ struct rdma_id_private *id_priv = -+ container_of(id, struct rdma_id_private, id); -+ -+ return rdma_bind_addr_dst(id_priv, addr, cma_dst_addr(id_priv)); -+} - EXPORT_SYMBOL(rdma_bind_addr); - - static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv) -diff --git a/drivers/infiniband/core/cma_trace.h b/drivers/infiniband/core/cma_trace.h -index e45264267bcc9..47f3c6e4be893 100644 ---- a/drivers/infiniband/core/cma_trace.h -+++ b/drivers/infiniband/core/cma_trace.h -@@ -15,7 +15,7 @@ - #define _TRACE_RDMA_CMA_H - - #include --#include -+#include - - - DECLARE_EVENT_CLASS(cma_fsm_class, -diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c -index d96c78e436f98..5c284dfbe6923 100644 ---- a/drivers/infiniband/core/user_mad.c -+++ b/drivers/infiniband/core/user_mad.c -@@ -131,6 +131,11 @@ struct ib_umad_packet { - struct ib_user_mad mad; - }; - -+struct ib_rmpp_mad_hdr { -+ struct ib_mad_hdr mad_hdr; -+ struct ib_rmpp_hdr rmpp_hdr; -+} __packed; -+ - #define CREATE_TRACE_POINTS - #include - -@@ -494,11 +499,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, - size_t count, loff_t *pos) - { - struct ib_umad_file *file = filp->private_data; -+ struct ib_rmpp_mad_hdr *rmpp_mad_hdr; - struct ib_umad_packet *packet; - struct ib_mad_agent *agent; - struct rdma_ah_attr ah_attr; - struct ib_ah *ah; -- struct ib_rmpp_mad *rmpp_mad; - __be64 *tid; - int ret, data_len, hdr_len, copy_offset, rmpp_active; - u8 base_version; -@@ -506,7 +511,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, - if (count < hdr_size(file) + IB_MGMT_RMPP_HDR) - return -EINVAL; - -- packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); -+ packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL); - if (!packet) - return -ENOMEM; - -@@ -560,13 +565,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, - goto err_up; - } - -- rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; -- hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); -+ rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data; -+ hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class); - -- if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) -+ if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class) - && ib_mad_kernel_rmpp_agent(agent)) { - copy_offset = IB_MGMT_RMPP_HDR; -- rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & -+ rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & - IB_MGMT_RMPP_FLAG_ACTIVE; - } else { - copy_offset = IB_MGMT_MAD_HDR; -@@ -615,12 +620,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, - tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; - *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | - (be64_to_cpup(tid) & 0xffffffff)); -- rmpp_mad->mad_hdr.tid = *tid; -+ rmpp_mad_hdr->mad_hdr.tid = *tid; - } - - if (!ib_mad_kernel_rmpp_agent(agent) -- && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) -- && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { -+ && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class) -+ && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { - spin_lock_irq(&file->send_lock); - list_add_tail(&packet->list, &file->send_list); - spin_unlock_irq(&file->send_lock); -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index 02f3bc4e4895e..13c36f51b9353 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -564,6 +564,9 @@ struct xboxone_init_packet { - #define GIP_MOTOR_LT BIT(3) - #define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT) - -+#define GIP_WIRED_INTF_DATA 0 -+#define GIP_WIRED_INTF_AUDIO 1 -+ - /* - * This packet is required for all Xbox One pads with 2015 - * or later firmware installed (or present from the factory). -@@ -2008,7 +2011,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id - } - - if (xpad->xtype == XTYPE_XBOXONE && -- intf->cur_altsetting->desc.bInterfaceNumber != 0) { -+ intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) { - /* - * The Xbox One controller lists three interfaces all with the - * same interface class, subclass and protocol. Differentiate by -diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c -index 1d9494f64a215..4526ff2e1bd5f 100644 ---- a/drivers/interconnect/core.c -+++ b/drivers/interconnect/core.c -@@ -29,7 +29,6 @@ static LIST_HEAD(icc_providers); - static int providers_count; - static bool synced_state; - static DEFINE_MUTEX(icc_lock); --static DEFINE_MUTEX(icc_bw_lock); - static struct dentry *icc_debugfs_dir; - - static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) -@@ -636,7 +635,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) - if (WARN_ON(IS_ERR(path) || !path->num_nodes)) - return -EINVAL; - -- mutex_lock(&icc_bw_lock); -+ mutex_lock(&icc_lock); - - old_avg = path->reqs[0].avg_bw; - old_peak = path->reqs[0].peak_bw; -@@ -668,7 +667,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) - apply_constraints(path); - } - -- mutex_unlock(&icc_bw_lock); -+ mutex_unlock(&icc_lock); - - trace_icc_set_bw_end(path, ret); - -@@ -971,7 +970,6 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) - return; - - mutex_lock(&icc_lock); -- mutex_lock(&icc_bw_lock); - - node->provider = provider; - list_add_tail(&node->node_list, &provider->nodes); -@@ -997,7 +995,6 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) - node->avg_bw = 0; - node->peak_bw = 0; - -- mutex_unlock(&icc_bw_lock); - mutex_unlock(&icc_lock); - } - EXPORT_SYMBOL_GPL(icc_node_add); -@@ -1137,7 +1134,6 @@ void icc_sync_state(struct device *dev) - return; - - mutex_lock(&icc_lock); -- mutex_lock(&icc_bw_lock); - synced_state = true; - list_for_each_entry(p, &icc_providers, provider_list) { - dev_dbg(p->dev, "interconnect provider is in synced state\n"); -@@ -1150,21 +1146,13 @@ void icc_sync_state(struct device *dev) - } - } - } -- mutex_unlock(&icc_bw_lock); - mutex_unlock(&icc_lock); - } - EXPORT_SYMBOL_GPL(icc_sync_state); - - static int __init icc_init(void) - { -- struct device_node *root; -- -- /* Teach lockdep about lock ordering wrt. shrinker: */ -- fs_reclaim_acquire(GFP_KERNEL); -- might_lock(&icc_bw_lock); -- fs_reclaim_release(GFP_KERNEL); -- -- root = of_find_node_by_path("/"); -+ struct device_node *root = of_find_node_by_path("/"); - - providers_count = of_count_icc_providers(root); - of_node_put(root); -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -index 8966f7d5aab61..82f100e591b5a 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -@@ -152,6 +152,18 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q) - q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons); - } - -+static void queue_sync_cons_ovf(struct arm_smmu_queue *q) -+{ -+ struct arm_smmu_ll_queue *llq = &q->llq; -+ -+ if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons))) -+ return; -+ -+ llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | -+ Q_IDX(llq, llq->cons); -+ queue_sync_cons_out(q); -+} -+ - static int queue_sync_prod_in(struct arm_smmu_queue *q) - { - u32 prod; -@@ -1583,8 +1595,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev) - } while (!queue_empty(llq)); - - /* Sync our overflow flag, as we believe we're up to speed */ -- llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | -- Q_IDX(llq, llq->cons); -+ queue_sync_cons_ovf(q); - return IRQ_HANDLED; - } - -@@ -1642,9 +1653,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev) - } while (!queue_empty(llq)); - - /* Sync our overflow flag, as we believe we're up to speed */ -- llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | -- Q_IDX(llq, llq->cons); -- queue_sync_cons_out(q); -+ queue_sync_cons_ovf(q); - return IRQ_HANDLED; - } - -diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -index d80065c8105af..f15dcb9e4175c 100644 ---- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -@@ -267,12 +267,26 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain, - - static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) - { -- unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); - struct qcom_smmu *qsmmu = to_qcom_smmu(smmu); -+ unsigned int last_s2cr; - u32 reg; - u32 smr; - int i; - -+ /* -+ * Some platforms support more than the Arm SMMU architected maximum of -+ * 128 stream matching groups. For unknown reasons, the additional -+ * groups don't exhibit the same behavior as the architected registers, -+ * so limit the groups to 128 until the behavior is fixed for the other -+ * groups. -+ */ -+ if (smmu->num_mapping_groups > 128) { -+ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); -+ smmu->num_mapping_groups = 128; -+ } -+ -+ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); -+ - /* - * With some firmware versions writes to S2CR of type FAULT are - * ignored, and writing BYPASS will end up written as FAULT in the -diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c -index 8261066de07d7..e4358393fe378 100644 ---- a/drivers/iommu/sprd-iommu.c -+++ b/drivers/iommu/sprd-iommu.c -@@ -152,13 +152,6 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type) - return &dom->domain; - } - --static void sprd_iommu_domain_free(struct iommu_domain *domain) --{ -- struct sprd_iommu_domain *dom = to_sprd_domain(domain); -- -- kfree(dom); --} -- - static void sprd_iommu_first_vpn(struct sprd_iommu_domain *dom) - { - struct sprd_iommu_device *sdev = dom->sdev; -@@ -231,6 +224,28 @@ static void sprd_iommu_hw_en(struct sprd_iommu_device *sdev, bool en) - sprd_iommu_update_bits(sdev, reg_cfg, mask, 0, val); - } - -+static void sprd_iommu_cleanup(struct sprd_iommu_domain *dom) -+{ -+ size_t pgt_size; -+ -+ /* Nothing need to do if the domain hasn't been attached */ -+ if (!dom->sdev) -+ return; -+ -+ pgt_size = sprd_iommu_pgt_size(&dom->domain); -+ dma_free_coherent(dom->sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa); -+ dom->sdev = NULL; -+ sprd_iommu_hw_en(dom->sdev, false); -+} -+ -+static void sprd_iommu_domain_free(struct iommu_domain *domain) -+{ -+ struct sprd_iommu_domain *dom = to_sprd_domain(domain); -+ -+ sprd_iommu_cleanup(dom); -+ kfree(dom); -+} -+ - static int sprd_iommu_attach_device(struct iommu_domain *domain, - struct device *dev) - { -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index a46ce0868fe1f..3a927452a6501 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1007,10 +1007,12 @@ static int mmc_select_bus_width(struct mmc_card *card) - static unsigned ext_csd_bits[] = { - EXT_CSD_BUS_WIDTH_8, - EXT_CSD_BUS_WIDTH_4, -+ EXT_CSD_BUS_WIDTH_1, - }; - static unsigned bus_widths[] = { - MMC_BUS_WIDTH_8, - MMC_BUS_WIDTH_4, -+ MMC_BUS_WIDTH_1, - }; - struct mmc_host *host = card->host; - unsigned idx, bus_width = 0; -diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c -index 60bca78a72b19..0511583ffa764 100644 ---- a/drivers/mmc/host/mmci_stm32_sdmmc.c -+++ b/drivers/mmc/host/mmci_stm32_sdmmc.c -@@ -200,6 +200,8 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl) - struct scatterlist *sg; - int i; - -+ host->dma_in_progress = true; -+ - if (!host->variant->dma_lli || data->sg_len == 1 || - idma->use_bounce_buffer) { - u32 dma_addr; -@@ -238,9 +240,30 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl) - return 0; - } - -+static void sdmmc_idma_error(struct mmci_host *host) -+{ -+ struct mmc_data *data = host->data; -+ struct sdmmc_idma *idma = host->dma_priv; -+ -+ if (!dma_inprogress(host)) -+ return; -+ -+ writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR); -+ host->dma_in_progress = false; -+ data->host_cookie = 0; -+ -+ if (!idma->use_bounce_buffer) -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ mmc_get_dma_dir(data)); -+} -+ - static void sdmmc_idma_finalize(struct mmci_host *host, struct mmc_data *data) - { -+ if (!dma_inprogress(host)) -+ return; -+ - writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR); -+ host->dma_in_progress = false; - - if (!data->host_cookie) - sdmmc_idma_unprep_data(host, data, 0); -@@ -567,6 +590,7 @@ static struct mmci_host_ops sdmmc_variant_ops = { - .dma_setup = sdmmc_idma_setup, - .dma_start = sdmmc_idma_start, - .dma_finalize = sdmmc_idma_finalize, -+ .dma_error = sdmmc_idma_error, - .set_clkreg = mmci_sdmmc_set_clkreg, - .set_pwrreg = mmci_sdmmc_set_pwrreg, - .busy_complete = sdmmc_busy_complete, -diff --git a/drivers/mmc/host/sdhci-xenon-phy.c b/drivers/mmc/host/sdhci-xenon-phy.c -index 8cf3a375de659..cc9d28b75eb91 100644 ---- a/drivers/mmc/host/sdhci-xenon-phy.c -+++ b/drivers/mmc/host/sdhci-xenon-phy.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - - #include "sdhci-pltfm.h" -@@ -109,6 +110,8 @@ - #define XENON_EMMC_PHY_LOGIC_TIMING_ADJUST (XENON_EMMC_PHY_REG_BASE + 0x18) - #define XENON_LOGIC_TIMING_VALUE 0x00AA8977 - -+#define XENON_MAX_PHY_TIMEOUT_LOOPS 100 -+ - /* - * List offset of PHY registers and some special register values - * in eMMC PHY 5.0 or eMMC PHY 5.1 -@@ -216,6 +219,19 @@ static int xenon_alloc_emmc_phy(struct sdhci_host *host) - return 0; - } - -+static int xenon_check_stability_internal_clk(struct sdhci_host *host) -+{ -+ u32 reg; -+ int err; -+ -+ err = read_poll_timeout(sdhci_readw, reg, reg & SDHCI_CLOCK_INT_STABLE, -+ 1100, 20000, false, host, SDHCI_CLOCK_CONTROL); -+ if (err) -+ dev_err(mmc_dev(host->mmc), "phy_init: Internal clock never stabilized.\n"); -+ -+ return err; -+} -+ - /* - * eMMC 5.0/5.1 PHY init/re-init. - * eMMC PHY init should be executed after: -@@ -232,6 +248,11 @@ static int xenon_emmc_phy_init(struct sdhci_host *host) - struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); - struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; - -+ int ret = xenon_check_stability_internal_clk(host); -+ -+ if (ret) -+ return ret; -+ - reg = sdhci_readl(host, phy_regs->timing_adj); - reg |= XENON_PHY_INITIALIZAION; - sdhci_writel(host, reg, phy_regs->timing_adj); -@@ -259,18 +280,27 @@ static int xenon_emmc_phy_init(struct sdhci_host *host) - /* get the wait time */ - wait /= clock; - wait++; -- /* wait for host eMMC PHY init completes */ -- udelay(wait); - -- reg = sdhci_readl(host, phy_regs->timing_adj); -- reg &= XENON_PHY_INITIALIZAION; -- if (reg) { -+ /* -+ * AC5X spec says bit must be polled until zero. -+ * We see cases in which timeout can take longer -+ * than the standard calculation on AC5X, which is -+ * expected following the spec comment above. -+ * According to the spec, we must wait as long as -+ * it takes for that bit to toggle on AC5X. -+ * Cap that with 100 delay loops so we won't get -+ * stuck here forever: -+ */ -+ -+ ret = read_poll_timeout(sdhci_readl, reg, -+ !(reg & XENON_PHY_INITIALIZAION), -+ wait, XENON_MAX_PHY_TIMEOUT_LOOPS * wait, -+ false, host, phy_regs->timing_adj); -+ if (ret) - dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n", -- wait); -- return -ETIMEDOUT; -- } -+ wait * XENON_MAX_PHY_TIMEOUT_LOOPS); - -- return 0; -+ return ret; - } - - #define ARMADA_3700_SOC_PAD_1_8V 0x1 -diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c -index 6b043e24855fb..9116ee7f023ed 100644 ---- a/drivers/mtd/nand/spi/gigadevice.c -+++ b/drivers/mtd/nand/spi/gigadevice.c -@@ -186,7 +186,7 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, - { - u8 status2; - struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, -- &status2); -+ spinand->scratchbuf); - int ret; - - switch (status & STATUS_ECC_MASK) { -@@ -207,6 +207,7 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, - * report the maximum of 4 in this case - */ - /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ -+ status2 = *(spinand->scratchbuf); - return ((status & STATUS_ECC_MASK) >> 2) | - ((status2 & STATUS_ECC_MASK) >> 4); - -@@ -228,7 +229,7 @@ static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, - { - u8 status2; - struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, -- &status2); -+ spinand->scratchbuf); - int ret; - - switch (status & STATUS_ECC_MASK) { -@@ -248,6 +249,7 @@ static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, - * 1 ... 4 bits are flipped (and corrected) - */ - /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ -+ status2 = *(spinand->scratchbuf); - return ((status2 & STATUS_ECC_MASK) >> 4) + 1; - - case STATUS_ECC_UNCOR_ERROR: -diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig -index 1917da7841919..5a274b99f2992 100644 ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -84,7 +84,6 @@ source "drivers/net/ethernet/huawei/Kconfig" - source "drivers/net/ethernet/i825xx/Kconfig" - source "drivers/net/ethernet/ibm/Kconfig" - source "drivers/net/ethernet/intel/Kconfig" --source "drivers/net/ethernet/wangxun/Kconfig" - source "drivers/net/ethernet/xscale/Kconfig" - - config JME -@@ -189,6 +188,7 @@ source "drivers/net/ethernet/toshiba/Kconfig" - source "drivers/net/ethernet/tundra/Kconfig" - source "drivers/net/ethernet/vertexcom/Kconfig" - source "drivers/net/ethernet/via/Kconfig" -+source "drivers/net/ethernet/wangxun/Kconfig" - source "drivers/net/ethernet/wiznet/Kconfig" - source "drivers/net/ethernet/xilinx/Kconfig" - source "drivers/net/ethernet/xircom/Kconfig" -diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c -index 07171e574e7d7..36e62197fba0b 100644 ---- a/drivers/net/ethernet/intel/igb/igb_ptp.c -+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c -@@ -976,7 +976,7 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) - - igb_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval); - /* adjust timestamp for the TX latency based on link speed */ -- if (adapter->hw.mac.type == e1000_i210) { -+ if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) { - switch (adapter->link_speed) { - case SPEED_10: - adjust = IGB_I210_TX_LATENCY_10; -@@ -1022,6 +1022,7 @@ int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, - ktime_t *timestamp) - { - struct igb_adapter *adapter = q_vector->adapter; -+ struct e1000_hw *hw = &adapter->hw; - struct skb_shared_hwtstamps ts; - __le64 *regval = (__le64 *)va; - int adjust = 0; -@@ -1041,7 +1042,7 @@ int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, - igb_ptp_systim_to_hwtstamp(adapter, &ts, le64_to_cpu(regval[1])); - - /* adjust timestamp for the RX latency based on link speed */ -- if (adapter->hw.mac.type == e1000_i210) { -+ if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) { - switch (adapter->link_speed) { - case SPEED_10: - adjust = IGB_I210_RX_LATENCY_10; -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -index dc2e204bcd727..41eac7dfb67e7 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c -@@ -52,8 +52,10 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, - max_regions = max_tcam_regions; - - tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL); -- if (!tcam->used_regions) -- return -ENOMEM; -+ if (!tcam->used_regions) { -+ err = -ENOMEM; -+ goto err_alloc_used_regions; -+ } - tcam->max_regions = max_regions; - - max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS); -@@ -78,6 +80,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, - bitmap_free(tcam->used_groups); - err_alloc_used_groups: - bitmap_free(tcam->used_regions); -+err_alloc_used_regions: -+ mutex_destroy(&tcam->lock); - return err; - } - -@@ -86,10 +90,10 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, - { - const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops; - -- mutex_destroy(&tcam->lock); - ops->fini(mlxsw_sp, tcam->priv); - bitmap_free(tcam->used_groups); - bitmap_free(tcam->used_regions); -+ mutex_destroy(&tcam->lock); - } - - int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp, -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 91b2aa81914ba..e2d51014ab4bc 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3900,8 +3900,10 @@ static void stmmac_fpe_stop_wq(struct stmmac_priv *priv) - { - set_bit(__FPE_REMOVING, &priv->fpe_task_state); - -- if (priv->fpe_wq) -+ if (priv->fpe_wq) { - destroy_workqueue(priv->fpe_wq); -+ priv->fpe_wq = NULL; -+ } - - netdev_info(priv->dev, "FPE workqueue stop"); - } -diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c -index 937dd9cf4fbaf..7086acfed5b90 100644 ---- a/drivers/net/gtp.c -+++ b/drivers/net/gtp.c -@@ -1902,26 +1902,26 @@ static int __init gtp_init(void) - - get_random_bytes(>p_h_initval, sizeof(gtp_h_initval)); - -- err = rtnl_link_register(>p_link_ops); -+ err = register_pernet_subsys(>p_net_ops); - if (err < 0) - goto error_out; - -- err = register_pernet_subsys(>p_net_ops); -+ err = rtnl_link_register(>p_link_ops); - if (err < 0) -- goto unreg_rtnl_link; -+ goto unreg_pernet_subsys; - - err = genl_register_family(>p_genl_family); - if (err < 0) -- goto unreg_pernet_subsys; -+ goto unreg_rtnl_link; - - pr_info("GTP module loaded (pdp ctx size %zd bytes)\n", - sizeof(struct pdp_ctx)); - return 0; - --unreg_pernet_subsys: -- unregister_pernet_subsys(>p_net_ops); - unreg_rtnl_link: - rtnl_link_unregister(>p_link_ops); -+unreg_pernet_subsys: -+ unregister_pernet_subsys(>p_net_ops); - error_out: - pr_err("error loading GTP module loaded\n"); - return err; -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 367255bb44cdc..922d6f16d99d1 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -653,6 +653,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean) - tun->tfiles[tun->numqueues - 1]); - ntfile = rtnl_dereference(tun->tfiles[index]); - ntfile->queue_index = index; -+ ntfile->xdp_rxq.queue_index = index; - rcu_assign_pointer(tun->tfiles[tun->numqueues - 1], - NULL); - -diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c -index 99ec1d4a972db..8b6d6a1b3c2ec 100644 ---- a/drivers/net/usb/dm9601.c -+++ b/drivers/net/usb/dm9601.c -@@ -232,7 +232,7 @@ static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc) - err = dm_read_shared_word(dev, 1, loc, &res); - if (err < 0) { - netdev_err(dev->net, "MDIO read error: %d\n", err); -- return err; -+ return 0; - } - - netdev_dbg(dev->net, -diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c -index c458c030fadf6..4fd4563811299 100644 ---- a/drivers/net/usb/lan78xx.c -+++ b/drivers/net/usb/lan78xx.c -@@ -1501,7 +1501,9 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) - - lan78xx_rx_urb_submit_all(dev); - -+ local_bh_disable(); - napi_schedule(&dev->napi); -+ local_bh_enable(); - } - - return 0; -@@ -3035,7 +3037,8 @@ static int lan78xx_reset(struct lan78xx_net *dev) - if (dev->chipid == ID_REV_CHIP_ID_7801_) - buf &= ~MAC_CR_GMII_EN_; - -- if (dev->chipid == ID_REV_CHIP_ID_7800_) { -+ if (dev->chipid == ID_REV_CHIP_ID_7800_ || -+ dev->chipid == ID_REV_CHIP_ID_7850_) { - ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig); - if (!ret && sig != EEPROM_INDICATOR) { - /* Implies there is no external eeprom. Set mac speed */ -diff --git a/drivers/net/veth.c b/drivers/net/veth.c -index 36c5a41f84e44..dd9f5f1461921 100644 ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -1135,14 +1135,6 @@ static int veth_enable_xdp(struct net_device *dev) - veth_disable_xdp_range(dev, 0, dev->real_num_rx_queues, true); - return err; - } -- -- if (!veth_gro_requested(dev)) { -- /* user-space did not require GRO, but adding XDP -- * is supposed to get GRO working -- */ -- dev->features |= NETIF_F_GRO; -- netdev_features_change(dev); -- } - } - } - -@@ -1162,18 +1154,9 @@ static void veth_disable_xdp(struct net_device *dev) - for (i = 0; i < dev->real_num_rx_queues; i++) - rcu_assign_pointer(priv->rq[i].xdp_prog, NULL); - -- if (!netif_running(dev) || !veth_gro_requested(dev)) { -+ if (!netif_running(dev) || !veth_gro_requested(dev)) - veth_napi_del(dev); - -- /* if user-space did not require GRO, since adding XDP -- * enabled it, clear it now -- */ -- if (!veth_gro_requested(dev) && netif_running(dev)) { -- dev->features &= ~NETIF_F_GRO; -- netdev_features_change(dev); -- } -- } -- - veth_disable_xdp_range(dev, 0, dev->real_num_rx_queues, false); - } - -@@ -1376,7 +1359,8 @@ static int veth_alloc_queues(struct net_device *dev) - struct veth_priv *priv = netdev_priv(dev); - int i; - -- priv->rq = kcalloc(dev->num_rx_queues, sizeof(*priv->rq), GFP_KERNEL_ACCOUNT); -+ priv->rq = kvcalloc(dev->num_rx_queues, sizeof(*priv->rq), -+ GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); - if (!priv->rq) - return -ENOMEM; - -@@ -1392,7 +1376,7 @@ static void veth_free_queues(struct net_device *dev) - { - struct veth_priv *priv = netdev_priv(dev); - -- kfree(priv->rq); -+ kvfree(priv->rq); - } - - static int veth_dev_init(struct net_device *dev) -@@ -1558,6 +1542,14 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, - } - - if (!old_prog) { -+ if (!veth_gro_requested(dev)) { -+ /* user-space did not require GRO, but adding -+ * XDP is supposed to get GRO working -+ */ -+ dev->features |= NETIF_F_GRO; -+ netdev_features_change(dev); -+ } -+ - peer->hw_features &= ~NETIF_F_GSO_SOFTWARE; - peer->max_mtu = max_mtu; - } -@@ -1568,6 +1560,14 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, - if (dev->flags & IFF_UP) - veth_disable_xdp(dev); - -+ /* if user-space did not require GRO, since adding XDP -+ * enabled it, clear it now -+ */ -+ if (!veth_gro_requested(dev)) { -+ dev->features &= ~NETIF_F_GRO; -+ netdev_features_change(dev); -+ } -+ - if (peer) { - peer->hw_features |= NETIF_F_GSO_SOFTWARE; - peer->max_mtu = ETH_MAX_MTU; -diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index 4402871b5c0c0..e663d5585a057 100644 ---- a/drivers/of/overlay.c -+++ b/drivers/of/overlay.c -@@ -45,8 +45,8 @@ struct target { - - /** - * struct fragment - info about fragment nodes in overlay expanded device tree -- * @target: target of the overlay operation - * @overlay: pointer to the __overlay__ node -+ * @target: target of the overlay operation - */ - struct fragment { - struct device_node *overlay; -diff --git a/drivers/of/property.c b/drivers/of/property.c -index 33d5f16c81204..da5d712197704 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1332,7 +1332,7 @@ static struct device_node *parse_remote_endpoint(struct device_node *np, - int index) - { - /* Return NULL for index > 0 to signify end of remote-endpoints. */ -- if (!index || strcmp(prop_name, "remote-endpoint")) -+ if (index > 0 || strcmp(prop_name, "remote-endpoint")) - return NULL; - - return of_graph_get_remote_port_parent(np); -diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c -index ad99707b3b994..dd7d74fecc48e 100644 ---- a/drivers/pci/controller/dwc/pci-layerscape-ep.c -+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c -@@ -18,6 +18,20 @@ - - #include "pcie-designware.h" - -+#define PEX_PF0_CONFIG 0xC0014 -+#define PEX_PF0_CFG_READY BIT(0) -+ -+/* PEX PFa PCIE PME and message interrupt registers*/ -+#define PEX_PF0_PME_MES_DR 0xC0020 -+#define PEX_PF0_PME_MES_DR_LUD BIT(7) -+#define PEX_PF0_PME_MES_DR_LDD BIT(9) -+#define PEX_PF0_PME_MES_DR_HRD BIT(10) -+ -+#define PEX_PF0_PME_MES_IER 0xC0028 -+#define PEX_PF0_PME_MES_IER_LUDIE BIT(7) -+#define PEX_PF0_PME_MES_IER_LDDIE BIT(9) -+#define PEX_PF0_PME_MES_IER_HRDIE BIT(10) -+ - #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev) - - struct ls_pcie_ep_drvdata { -@@ -30,8 +44,99 @@ struct ls_pcie_ep { - struct dw_pcie *pci; - struct pci_epc_features *ls_epc; - const struct ls_pcie_ep_drvdata *drvdata; -+ int irq; -+ u32 lnkcap; -+ bool big_endian; - }; - -+static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset) -+{ -+ struct dw_pcie *pci = pcie->pci; -+ -+ if (pcie->big_endian) -+ return ioread32be(pci->dbi_base + offset); -+ else -+ return ioread32(pci->dbi_base + offset); -+} -+ -+static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset, u32 value) -+{ -+ struct dw_pcie *pci = pcie->pci; -+ -+ if (pcie->big_endian) -+ iowrite32be(value, pci->dbi_base + offset); -+ else -+ iowrite32(value, pci->dbi_base + offset); -+} -+ -+static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id) -+{ -+ struct ls_pcie_ep *pcie = dev_id; -+ struct dw_pcie *pci = pcie->pci; -+ u32 val, cfg; -+ u8 offset; -+ -+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR); -+ ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val); -+ -+ if (!val) -+ return IRQ_NONE; -+ -+ if (val & PEX_PF0_PME_MES_DR_LUD) { -+ -+ offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); -+ -+ /* -+ * The values of the Maximum Link Width and Supported Link -+ * Speed from the Link Capabilities Register will be lost -+ * during link down or hot reset. Restore initial value -+ * that configured by the Reset Configuration Word (RCW). -+ */ -+ dw_pcie_dbi_ro_wr_en(pci); -+ dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, pcie->lnkcap); -+ dw_pcie_dbi_ro_wr_dis(pci); -+ -+ cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG); -+ cfg |= PEX_PF0_CFG_READY; -+ ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg); -+ dw_pcie_ep_linkup(&pci->ep); -+ -+ dev_dbg(pci->dev, "Link up\n"); -+ } else if (val & PEX_PF0_PME_MES_DR_LDD) { -+ dev_dbg(pci->dev, "Link down\n"); -+ } else if (val & PEX_PF0_PME_MES_DR_HRD) { -+ dev_dbg(pci->dev, "Hot reset\n"); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie, -+ struct platform_device *pdev) -+{ -+ u32 val; -+ int ret; -+ -+ pcie->irq = platform_get_irq_byname(pdev, "pme"); -+ if (pcie->irq < 0) -+ return pcie->irq; -+ -+ ret = devm_request_irq(&pdev->dev, pcie->irq, ls_pcie_ep_event_handler, -+ IRQF_SHARED, pdev->name, pcie); -+ if (ret) { -+ dev_err(&pdev->dev, "Can't register PCIe IRQ\n"); -+ return ret; -+ } -+ -+ /* Enable interrupts */ -+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER); -+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE | -+ PEX_PF0_PME_MES_IER_LUDIE; -+ ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val); -+ -+ return 0; -+} -+ - static const struct pci_epc_features* - ls_pcie_ep_get_features(struct dw_pcie_ep *ep) - { -@@ -124,6 +229,8 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) - struct ls_pcie_ep *pcie; - struct pci_epc_features *ls_epc; - struct resource *dbi_base; -+ u8 offset; -+ int ret; - - pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); - if (!pcie) -@@ -143,6 +250,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) - pci->ops = pcie->drvdata->dw_pcie_ops; - - ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4); -+ ls_epc->linkup_notifier = true; - - pcie->pci = pci; - pcie->ls_epc = ls_epc; -@@ -154,9 +262,18 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) - - pci->ep.ops = &ls_pcie_ep_ops; - -+ pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian"); -+ - platform_set_drvdata(pdev, pcie); - -- return dw_pcie_ep_init(&pci->ep); -+ offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); -+ pcie->lnkcap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); -+ -+ ret = dw_pcie_ep_init(&pci->ep); -+ if (ret) -+ return ret; -+ -+ return ls_pcie_ep_interrupt_init(pcie, pdev); - } - - static struct platform_driver ls_pcie_ep_driver = { -diff --git a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c -index e625b32889bfc..0928a526e2ab3 100644 ---- a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c -+++ b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c -@@ -706,7 +706,7 @@ static int mixel_dphy_probe(struct platform_device *pdev) - return ret; - } - -- priv->id = of_alias_get_id(np, "mipi_dphy"); -+ priv->id = of_alias_get_id(np, "mipi-dphy"); - if (priv->id < 0) { - dev_err(dev, "Failed to get phy node alias id: %d\n", - priv->id); -diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c -index 0713a52a25107..17b37354e32c0 100644 ---- a/drivers/power/supply/bq27xxx_battery_i2c.c -+++ b/drivers/power/supply/bq27xxx_battery_i2c.c -@@ -209,7 +209,9 @@ static void bq27xxx_battery_i2c_remove(struct i2c_client *client) - { - struct bq27xxx_device_info *di = i2c_get_clientdata(client); - -- free_irq(client->irq, di); -+ if (client->irq) -+ free_irq(client->irq, di); -+ - bq27xxx_battery_teardown(di); - - mutex_lock(&battery_mutex); -diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index 5c5954b78585e..edd296f950a33 100644 ---- a/drivers/scsi/scsi_lib.c -+++ b/drivers/scsi/scsi_lib.c -@@ -185,39 +185,37 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) - __scsi_queue_insert(cmd, reason, true); - } - -- - /** -- * __scsi_execute - insert request and wait for the result -- * @sdev: scsi device -+ * scsi_execute_cmd - insert request and wait for the result -+ * @sdev: scsi_device - * @cmd: scsi command -- * @data_direction: data direction -+ * @opf: block layer request cmd_flags - * @buffer: data buffer - * @bufflen: len of buffer -- * @sense: optional sense buffer -- * @sshdr: optional decoded sense header - * @timeout: request timeout in HZ - * @retries: number of times to retry request -- * @flags: flags for ->cmd_flags -- * @rq_flags: flags for ->rq_flags -- * @resid: optional residual length -+ * @args: Optional args. See struct definition for field descriptions - * - * Returns the scsi_cmnd result field if a command was executed, or a negative - * Linux error code if we didn't get that far. - */ --int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, -- int data_direction, void *buffer, unsigned bufflen, -- unsigned char *sense, struct scsi_sense_hdr *sshdr, -- int timeout, int retries, blk_opf_t flags, -- req_flags_t rq_flags, int *resid) -+int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, -+ blk_opf_t opf, void *buffer, unsigned int bufflen, -+ int timeout, int retries, -+ const struct scsi_exec_args *args) - { -+ static const struct scsi_exec_args default_args; - struct request *req; - struct scsi_cmnd *scmd; - int ret; - -- req = scsi_alloc_request(sdev->request_queue, -- data_direction == DMA_TO_DEVICE ? -- REQ_OP_DRV_OUT : REQ_OP_DRV_IN, -- rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); -+ if (!args) -+ args = &default_args; -+ else if (WARN_ON_ONCE(args->sense && -+ args->sense_len != SCSI_SENSE_BUFFERSIZE)) -+ return -EINVAL; -+ -+ req = scsi_alloc_request(sdev->request_queue, opf, args->req_flags); - if (IS_ERR(req)) - return PTR_ERR(req); - -@@ -232,8 +230,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, - memcpy(scmd->cmnd, cmd, scmd->cmd_len); - scmd->allowed = retries; - req->timeout = timeout; -- req->cmd_flags |= flags; -- req->rq_flags |= rq_flags | RQF_QUIET; -+ req->rq_flags |= RQF_QUIET; - - /* - * head injection *required* here otherwise quiesce won't work -@@ -249,20 +246,21 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, - if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) - memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); - -- if (resid) -- *resid = scmd->resid_len; -- if (sense && scmd->sense_len) -- memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -- if (sshdr) -+ if (args->resid) -+ *args->resid = scmd->resid_len; -+ if (args->sense) -+ memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -+ if (args->sshdr) - scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, -- sshdr); -+ args->sshdr); -+ - ret = scmd->result; - out: - blk_mq_free_request(req); - - return ret; - } --EXPORT_SYMBOL(__scsi_execute); -+EXPORT_SYMBOL(scsi_execute_cmd); - - /* - * Wake up the error handler if necessary. Avoid as follows that the error -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index 31b5273f43a71..4433b02c8935f 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -3284,6 +3284,24 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, - return true; - } - -+static void sd_read_block_zero(struct scsi_disk *sdkp) -+{ -+ unsigned int buf_len = sdkp->device->sector_size; -+ char *buffer, cmd[10] = { }; -+ -+ buffer = kmalloc(buf_len, GFP_KERNEL); -+ if (!buffer) -+ return; -+ -+ cmd[0] = READ_10; -+ put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */ -+ put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */ -+ -+ scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len, -+ SD_TIMEOUT, sdkp->max_retries, NULL); -+ kfree(buffer); -+} -+ - /** - * sd_revalidate_disk - called the first time a new disk is seen, - * performs disk spin up, read_capacity, etc. -@@ -3323,7 +3341,13 @@ static int sd_revalidate_disk(struct gendisk *disk) - */ - if (sdkp->media_present) { - sd_read_capacity(sdkp, buffer); -- -+ /* -+ * Some USB/UAS devices return generic values for mode pages -+ * until the media has been accessed. Trigger a READ operation -+ * to force the device to populate mode pages. -+ */ -+ if (sdp->read_before_ms) -+ sd_read_block_zero(sdkp); - /* - * set the default to rotational. All non-rotational devices - * support the block characteristics VPD page, which will -diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c -index 092f6ab09acf3..9a90f241bb97f 100644 ---- a/drivers/soc/qcom/rpmhpd.c -+++ b/drivers/soc/qcom/rpmhpd.c -@@ -492,12 +492,15 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner) - unsigned int active_corner, sleep_corner; - unsigned int this_active_corner = 0, this_sleep_corner = 0; - unsigned int peer_active_corner = 0, peer_sleep_corner = 0; -+ unsigned int peer_enabled_corner; - - to_active_sleep(pd, corner, &this_active_corner, &this_sleep_corner); - -- if (peer && peer->enabled) -- to_active_sleep(peer, peer->corner, &peer_active_corner, -+ if (peer && peer->enabled) { -+ peer_enabled_corner = max(peer->corner, peer->enable_corner); -+ to_active_sleep(peer, peer_enabled_corner, &peer_active_corner, - &peer_sleep_corner); -+ } - - active_corner = max(this_active_corner, peer_active_corner); - -diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c -index cb0a4e2cdbb73..247cca46cdfae 100644 ---- a/drivers/usb/gadget/composite.c -+++ b/drivers/usb/gadget/composite.c -@@ -511,6 +511,19 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, - return min(val, 900U) / 8; - } - -+void check_remote_wakeup_config(struct usb_gadget *g, -+ struct usb_configuration *c) -+{ -+ if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes) { -+ /* Reset the rw bit if gadget is not capable of it */ -+ if (!g->wakeup_capable && g->ops->set_remote_wakeup) { -+ WARN(c->cdev, "Clearing wakeup bit for config c.%d\n", -+ c->bConfigurationValue); -+ c->bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; -+ } -+ } -+} -+ - static int config_buf(struct usb_configuration *config, - enum usb_device_speed speed, void *buf, u8 type) - { -@@ -959,6 +972,11 @@ static int set_config(struct usb_composite_dev *cdev, - power = min(power, 500U); - else - power = min(power, 900U); -+ -+ if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes) -+ usb_gadget_set_remote_wakeup(gadget, 1); -+ else -+ usb_gadget_set_remote_wakeup(gadget, 0); - done: - if (power <= USB_SELF_POWER_VBUS_MAX_DRAW) - usb_gadget_set_selfpowered(gadget); -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index 4dcf29577f8f1..b94aec6227c51 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -1376,6 +1376,9 @@ static int configfs_composite_bind(struct usb_gadget *gadget, - if (gadget_is_otg(gadget)) - c->descriptors = otg_desc; - -+ /* Properly configure the bmAttributes wakeup bit */ -+ check_remote_wakeup_config(gadget, c); -+ - cfg = container_of(c, struct config_usb_cfg, c); - if (!list_empty(&cfg->string_list)) { - i = 0; -diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c -index c40f2ecbe1b8c..0edd9e53fc5a1 100644 ---- a/drivers/usb/gadget/udc/core.c -+++ b/drivers/usb/gadget/udc/core.c -@@ -525,6 +525,33 @@ int usb_gadget_wakeup(struct usb_gadget *gadget) - } - EXPORT_SYMBOL_GPL(usb_gadget_wakeup); - -+/** -+ * usb_gadget_set_remote_wakeup - configures the device remote wakeup feature. -+ * @gadget:the device being configured for remote wakeup -+ * @set:value to be configured. -+ * -+ * set to one to enable remote wakeup feature and zero to disable it. -+ * -+ * returns zero on success, else negative errno. -+ */ -+int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set) -+{ -+ int ret = 0; -+ -+ if (!gadget->ops->set_remote_wakeup) { -+ ret = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ ret = gadget->ops->set_remote_wakeup(gadget, set); -+ -+out: -+ trace_usb_gadget_set_remote_wakeup(gadget, ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(usb_gadget_set_remote_wakeup); -+ - /** - * usb_gadget_set_selfpowered - sets the device selfpowered feature. - * @gadget:the device being declared as self-powered -diff --git a/drivers/usb/gadget/udc/trace.h b/drivers/usb/gadget/udc/trace.h -index abdbcb1bacb0b..a5ed26fbc2dad 100644 ---- a/drivers/usb/gadget/udc/trace.h -+++ b/drivers/usb/gadget/udc/trace.h -@@ -91,6 +91,11 @@ DEFINE_EVENT(udc_log_gadget, usb_gadget_wakeup, - TP_ARGS(g, ret) - ); - -+DEFINE_EVENT(udc_log_gadget, usb_gadget_set_remote_wakeup, -+ TP_PROTO(struct usb_gadget *g, int ret), -+ TP_ARGS(g, ret) -+); -+ - DEFINE_EVENT(udc_log_gadget, usb_gadget_set_selfpowered, - TP_PROTO(struct usb_gadget *g, int ret), - TP_ARGS(g, ret) -diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c -index c54e9805da536..12cf9940e5b67 100644 ---- a/drivers/usb/storage/scsiglue.c -+++ b/drivers/usb/storage/scsiglue.c -@@ -179,6 +179,13 @@ static int slave_configure(struct scsi_device *sdev) - */ - sdev->use_192_bytes_for_3f = 1; - -+ /* -+ * Some devices report generic values until the media has been -+ * accessed. Force a READ(10) prior to querying device -+ * characteristics. -+ */ -+ sdev->read_before_ms = 1; -+ - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c -index de3836412bf32..ed22053b3252f 100644 ---- a/drivers/usb/storage/uas.c -+++ b/drivers/usb/storage/uas.c -@@ -878,6 +878,13 @@ static int uas_slave_configure(struct scsi_device *sdev) - if (devinfo->flags & US_FL_CAPACITY_HEURISTICS) - sdev->guess_capacity = 1; - -+ /* -+ * Some devices report generic values until the media has been -+ * accessed. Force a READ(10) prior to querying device -+ * characteristics. -+ */ -+ sdev->read_before_ms = 1; -+ - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c -index fa205be94a4b8..14498a0d13e0b 100644 ---- a/drivers/video/fbdev/core/fbcon.c -+++ b/drivers/video/fbdev/core/fbcon.c -@@ -2397,11 +2397,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, - struct fbcon_ops *ops = info->fbcon_par; - struct fbcon_display *p = &fb_display[vc->vc_num]; - int resize, ret, old_userfont, old_width, old_height, old_charcount; -- char *old_data = NULL; -+ u8 *old_data = vc->vc_font.data; - - resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); -- if (p->userfont) -- old_data = vc->vc_font.data; - vc->vc_font.data = (void *)(p->fontdata = data); - old_userfont = p->userfont; - if ((p->userfont = userfont)) -@@ -2435,13 +2433,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, - update_screen(vc); - } - -- if (old_data && (--REFCOUNT(old_data) == 0)) -+ if (old_userfont && (--REFCOUNT(old_data) == 0)) - kfree(old_data - FONT_EXTRA_WORDS * sizeof(int)); - return 0; - - err_out: - p->fontdata = old_data; -- vc->vc_font.data = (void *)old_data; -+ vc->vc_font.data = old_data; - - if (userfont) { - p->userfont = old_userfont; -diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c -index 00f8e349921d4..96b96516c9806 100644 ---- a/drivers/xen/events/events_base.c -+++ b/drivers/xen/events/events_base.c -@@ -937,8 +937,8 @@ static void shutdown_pirq(struct irq_data *data) - return; - - do_mask(info, EVT_MASK_REASON_EXPLICIT); -- xen_evtchn_close(evtchn); - xen_irq_info_cleanup(info); -+ xen_evtchn_close(evtchn); - } - - static void enable_pirq(struct irq_data *data) -@@ -982,8 +982,6 @@ static void __unbind_from_irq(unsigned int irq) - unsigned int cpu = cpu_from_irq(irq); - struct xenbus_device *dev; - -- xen_evtchn_close(evtchn); -- - switch (type_from_irq(irq)) { - case IRQT_VIRQ: - per_cpu(virq_to_irq, cpu)[virq_from_irq(irq)] = -1; -@@ -1001,6 +999,7 @@ static void __unbind_from_irq(unsigned int irq) - } - - xen_irq_info_cleanup(info); -+ xen_evtchn_close(evtchn); - } - - xen_free_irq(irq); -diff --git a/fs/afs/dir.c b/fs/afs/dir.c -index cf811b77ee671..6e2c967fae6fc 100644 ---- a/fs/afs/dir.c -+++ b/fs/afs/dir.c -@@ -478,8 +478,10 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode, - dire->u.name[0] == '.' && - ctx->actor != afs_lookup_filldir && - ctx->actor != afs_lookup_one_filldir && -- memcmp(dire->u.name, ".__afs", 6) == 0) -+ memcmp(dire->u.name, ".__afs", 6) == 0) { -+ ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent); - continue; -+ } - - /* found the next entry */ - if (!dir_emit(ctx, dire->u.name, nlen, -diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c -index 61e58066b5fd2..9c856a73d5333 100644 ---- a/fs/btrfs/dev-replace.c -+++ b/fs/btrfs/dev-replace.c -@@ -740,6 +740,23 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, - return ret; - } - -+static int btrfs_check_replace_dev_names(struct btrfs_ioctl_dev_replace_args *args) -+{ -+ if (args->start.srcdevid == 0) { -+ if (memchr(args->start.srcdev_name, 0, -+ sizeof(args->start.srcdev_name)) == NULL) -+ return -ENAMETOOLONG; -+ } else { -+ args->start.srcdev_name[0] = 0; -+ } -+ -+ if (memchr(args->start.tgtdev_name, 0, -+ sizeof(args->start.tgtdev_name)) == NULL) -+ return -ENAMETOOLONG; -+ -+ return 0; -+} -+ - int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, - struct btrfs_ioctl_dev_replace_args *args) - { -@@ -752,10 +769,9 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info, - default: - return -EINVAL; - } -- -- if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') || -- args->start.tgtdev_name[0] == '\0') -- return -EINVAL; -+ ret = btrfs_check_replace_dev_names(args); -+ if (ret < 0) -+ return ret; - - ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name, - args->start.srcdevid, -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 0d1b05ded1e35..5756edb37c61e 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -1643,12 +1643,12 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) - * - * @objectid: root id - * @anon_dev: preallocated anonymous block device number for new roots, -- * pass 0 for new allocation. -+ * pass NULL for a new allocation. - * @check_ref: whether to check root item references, If true, return -ENOENT - * for orphan roots - */ - static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, -- u64 objectid, dev_t anon_dev, -+ u64 objectid, dev_t *anon_dev, - bool check_ref) - { - struct btrfs_root *root; -@@ -1668,9 +1668,9 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, - * that common but still possible. In that case, we just need - * to free the anon_dev. - */ -- if (unlikely(anon_dev)) { -- free_anon_bdev(anon_dev); -- anon_dev = 0; -+ if (unlikely(anon_dev && *anon_dev)) { -+ free_anon_bdev(*anon_dev); -+ *anon_dev = 0; - } - - if (check_ref && btrfs_root_refs(&root->root_item) == 0) { -@@ -1692,7 +1692,7 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, - goto fail; - } - -- ret = btrfs_init_fs_root(root, anon_dev); -+ ret = btrfs_init_fs_root(root, anon_dev ? *anon_dev : 0); - if (ret) - goto fail; - -@@ -1728,7 +1728,7 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, - * root's anon_dev to 0 to avoid a double free, once by btrfs_put_root() - * and once again by our caller. - */ -- if (anon_dev) -+ if (anon_dev && *anon_dev) - root->anon_dev = 0; - btrfs_put_root(root); - return ERR_PTR(ret); -@@ -1744,7 +1744,7 @@ static struct btrfs_root *btrfs_get_root_ref(struct btrfs_fs_info *fs_info, - struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, - u64 objectid, bool check_ref) - { -- return btrfs_get_root_ref(fs_info, objectid, 0, check_ref); -+ return btrfs_get_root_ref(fs_info, objectid, NULL, check_ref); - } - - /* -@@ -1752,11 +1752,11 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, - * the anonymous block device id - * - * @objectid: tree objectid -- * @anon_dev: if zero, allocate a new anonymous block device or use the -- * parameter value -+ * @anon_dev: if NULL, allocate a new anonymous block device or use the -+ * parameter value if not NULL - */ - struct btrfs_root *btrfs_get_new_fs_root(struct btrfs_fs_info *fs_info, -- u64 objectid, dev_t anon_dev) -+ u64 objectid, dev_t *anon_dev) - { - return btrfs_get_root_ref(fs_info, objectid, anon_dev, true); - } -diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h -index 7322af63c0cc7..24bddca86e9c9 100644 ---- a/fs/btrfs/disk-io.h -+++ b/fs/btrfs/disk-io.h -@@ -65,7 +65,7 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info); - struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, - u64 objectid, bool check_ref); - struct btrfs_root *btrfs_get_new_fs_root(struct btrfs_fs_info *fs_info, -- u64 objectid, dev_t anon_dev); -+ u64 objectid, dev_t *anon_dev); - struct btrfs_root *btrfs_get_fs_root_commit_root(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, - u64 objectid); -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 196e222749ccd..64b37afb7c87f 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -708,7 +708,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, - free_extent_buffer(leaf); - leaf = NULL; - -- new_root = btrfs_get_new_fs_root(fs_info, objectid, anon_dev); -+ new_root = btrfs_get_new_fs_root(fs_info, objectid, &anon_dev); - if (IS_ERR(new_root)) { - ret = PTR_ERR(new_root); - btrfs_abort_transaction(trans, ret); -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index a75669972dc73..9f7ffd9ef6fd7 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -6462,11 +6462,20 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) - if (ret) - goto out; - } -- if (sctx->cur_inode_last_extent < -- sctx->cur_inode_size) { -- ret = send_hole(sctx, sctx->cur_inode_size); -- if (ret) -+ if (sctx->cur_inode_last_extent < sctx->cur_inode_size) { -+ ret = range_is_hole_in_parent(sctx, -+ sctx->cur_inode_last_extent, -+ sctx->cur_inode_size); -+ if (ret < 0) { - goto out; -+ } else if (ret == 0) { -+ ret = send_hole(sctx, sctx->cur_inode_size); -+ if (ret < 0) -+ goto out; -+ } else { -+ /* Range is already a hole, skip. */ -+ ret = 0; -+ } - } - } - if (need_truncate) { -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index 60db4c3b82fa1..b172091f42612 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -1809,7 +1809,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - } - - key.offset = (u64)-1; -- pending->snap = btrfs_get_new_fs_root(fs_info, objectid, pending->anon_dev); -+ pending->snap = btrfs_get_new_fs_root(fs_info, objectid, &pending->anon_dev); - if (IS_ERR(pending->snap)) { - ret = PTR_ERR(pending->snap); - pending->snap = NULL; -diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c -index 9e4f47808bd5a..13bc606989557 100644 ---- a/fs/efivarfs/vars.c -+++ b/fs/efivarfs/vars.c -@@ -372,7 +372,7 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid, - int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), - void *data, bool duplicates, struct list_head *head) - { -- unsigned long variable_name_size = 1024; -+ unsigned long variable_name_size = 512; - efi_char16_t *variable_name; - efi_status_t status; - efi_guid_t vendor_guid; -@@ -389,12 +389,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), - goto free; - - /* -- * Per EFI spec, the maximum storage allocated for both -- * the variable name and variable data is 1024 bytes. -+ * A small set of old UEFI implementations reject sizes -+ * above a certain threshold, the lowest seen in the wild -+ * is 512. - */ - - do { -- variable_name_size = 1024; -+ variable_name_size = 512; - - status = efivar_get_next_variable(&variable_name_size, - variable_name, -@@ -431,9 +432,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), - break; - case EFI_NOT_FOUND: - break; -+ case EFI_BUFFER_TOO_SMALL: -+ pr_warn("efivars: Variable name size exceeds maximum (%lu > 512)\n", -+ variable_name_size); -+ status = EFI_NOT_FOUND; -+ break; - default: -- printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n", -- status); -+ pr_warn("efivars: get_next_variable: status=%lx\n", status); - status = EFI_NOT_FOUND; - break; - } -diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c -index c648a493faf23..3204bd33e4e8a 100644 ---- a/fs/exportfs/expfs.c -+++ b/fs/exportfs/expfs.c -@@ -18,7 +18,7 @@ - #include - #include - --#define dprintk(fmt, args...) do{}while(0) -+#define dprintk(fmt, args...) pr_debug(fmt, ##args) - - - static int get_name(const struct path *path, char *name, struct dentry *child); -@@ -132,8 +132,8 @@ static struct dentry *reconnect_one(struct vfsmount *mnt, - inode_unlock(dentry->d_inode); - - if (IS_ERR(parent)) { -- dprintk("%s: get_parent of %ld failed, err %d\n", -- __func__, dentry->d_inode->i_ino, PTR_ERR(parent)); -+ dprintk("get_parent of %lu failed, err %ld\n", -+ dentry->d_inode->i_ino, PTR_ERR(parent)); - return parent; - } - -@@ -147,7 +147,7 @@ static struct dentry *reconnect_one(struct vfsmount *mnt, - dprintk("%s: found name: %s\n", __func__, nbuf); - tmp = lookup_one_unlocked(mnt_user_ns(mnt), nbuf, parent, strlen(nbuf)); - if (IS_ERR(tmp)) { -- dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp)); -+ dprintk("lookup failed: %ld\n", PTR_ERR(tmp)); - err = PTR_ERR(tmp); - goto out_err; - } -diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c -index 284b019cb6529..b72023a6b4c16 100644 ---- a/fs/lockd/svc4proc.c -+++ b/fs/lockd/svc4proc.c -@@ -52,6 +52,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, - *filp = file; - - /* Set up the missing parts of the file_lock structure */ -+ lock->fl.fl_flags = FL_POSIX; - lock->fl.fl_file = file->f_file[mode]; - lock->fl.fl_pid = current->tgid; - lock->fl.fl_start = (loff_t)lock->lock_start; -diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c -index 9c1aa75441e1c..4e30f3c509701 100644 ---- a/fs/lockd/svclock.c -+++ b/fs/lockd/svclock.c -@@ -659,11 +659,13 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock) - nlmsvc_cancel_blocked(net, file, lock); - - lock->fl.fl_type = F_UNLCK; -- if (file->f_file[O_RDONLY]) -- error = vfs_lock_file(file->f_file[O_RDONLY], F_SETLK, -+ lock->fl.fl_file = file->f_file[O_RDONLY]; -+ if (lock->fl.fl_file) -+ error = vfs_lock_file(lock->fl.fl_file, F_SETLK, - &lock->fl, NULL); -- if (file->f_file[O_WRONLY]) -- error = vfs_lock_file(file->f_file[O_WRONLY], F_SETLK, -+ lock->fl.fl_file = file->f_file[O_WRONLY]; -+ if (lock->fl.fl_file) -+ error |= vfs_lock_file(lock->fl.fl_file, F_SETLK, - &lock->fl, NULL); - - return (error < 0)? nlm_lck_denied_nolocks : nlm_granted; -@@ -697,9 +699,10 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l - block = nlmsvc_lookup_block(file, lock); - mutex_unlock(&file->f_mutex); - if (block != NULL) { -- mode = lock_to_openmode(&lock->fl); -- vfs_cancel_lock(block->b_file->f_file[mode], -- &block->b_call->a_args.lock.fl); -+ struct file_lock *fl = &block->b_call->a_args.lock.fl; -+ -+ mode = lock_to_openmode(fl); -+ vfs_cancel_lock(block->b_file->f_file[mode], fl); - status = nlmsvc_unlink_block(block); - nlmsvc_release_block(block); - } -diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c -index e35c05e278061..32784f508c810 100644 ---- a/fs/lockd/svcproc.c -+++ b/fs/lockd/svcproc.c -@@ -77,6 +77,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, - - /* Set up the missing parts of the file_lock structure */ - mode = lock_to_openmode(&lock->fl); -+ lock->fl.fl_flags = FL_POSIX; - lock->fl.fl_file = file->f_file[mode]; - lock->fl.fl_pid = current->tgid; - lock->fl.fl_lmops = &nlmsvc_lock_operations; -diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c -index 3515f17eaf3fb..e3b6229e7ae5c 100644 ---- a/fs/lockd/svcsubs.c -+++ b/fs/lockd/svcsubs.c -@@ -210,7 +210,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, - { - struct inode *inode = nlmsvc_file_inode(file); - struct file_lock *fl; -- struct file_lock_context *flctx = inode->i_flctx; -+ struct file_lock_context *flctx = locks_inode_context(inode); - struct nlm_host *lockhost; - - if (!flctx || list_empty_careful(&flctx->flc_posix)) -@@ -265,7 +265,7 @@ nlm_file_inuse(struct nlm_file *file) - { - struct inode *inode = nlmsvc_file_inode(file); - struct file_lock *fl; -- struct file_lock_context *flctx = inode->i_flctx; -+ struct file_lock_context *flctx = locks_inode_context(inode); - - if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) - return 1; -diff --git a/fs/locks.c b/fs/locks.c -index 1047ab2b15e96..7d0918b8fe5d6 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -175,7 +175,7 @@ locks_get_lock_context(struct inode *inode, int type) - struct file_lock_context *ctx; - - /* paired with cmpxchg() below */ -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (likely(ctx) || type == F_UNLCK) - goto out; - -@@ -194,7 +194,7 @@ locks_get_lock_context(struct inode *inode, int type) - */ - if (cmpxchg(&inode->i_flctx, NULL, ctx)) { - kmem_cache_free(flctx_cache, ctx); -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - } - out: - trace_locks_get_lock_context(inode, type, ctx); -@@ -247,7 +247,7 @@ locks_check_ctx_file_list(struct file *filp, struct list_head *list, - void - locks_free_lock_context(struct inode *inode) - { -- struct file_lock_context *ctx = inode->i_flctx; -+ struct file_lock_context *ctx = locks_inode_context(inode); - - if (unlikely(ctx)) { - locks_check_ctx_lists(inode); -@@ -891,7 +891,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl) - void *owner; - void (*func)(void); - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx || list_empty_careful(&ctx->flc_posix)) { - fl->fl_type = F_UNLCK; - return; -@@ -1483,7 +1483,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) - new_fl->fl_flags = type; - - /* typically we will check that ctx is non-NULL before calling */ -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx) { - WARN_ON_ONCE(1); - goto free_lock; -@@ -1588,7 +1588,7 @@ void lease_get_mtime(struct inode *inode, struct timespec64 *time) - struct file_lock_context *ctx; - struct file_lock *fl; - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (ctx && !list_empty_careful(&ctx->flc_lease)) { - spin_lock(&ctx->flc_lock); - fl = list_first_entry_or_null(&ctx->flc_lease, -@@ -1634,7 +1634,7 @@ int fcntl_getlease(struct file *filp) - int type = F_UNLCK; - LIST_HEAD(dispose); - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (ctx && !list_empty_careful(&ctx->flc_lease)) { - percpu_down_read(&file_rwsem); - spin_lock(&ctx->flc_lock); -@@ -1823,7 +1823,7 @@ static int generic_delete_lease(struct file *filp, void *owner) - struct file_lock_context *ctx; - LIST_HEAD(dispose); - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx) { - trace_generic_delete_lease(inode, NULL); - return error; -@@ -2562,7 +2562,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) - * posix_lock_file(). Another process could be setting a lock on this - * file at the same time, but we wouldn't remove that lock anyway. - */ -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx || list_empty(&ctx->flc_posix)) - return; - -@@ -2635,7 +2635,7 @@ void locks_remove_file(struct file *filp) - { - struct file_lock_context *ctx; - -- ctx = smp_load_acquire(&locks_inode(filp)->i_flctx); -+ ctx = locks_inode_context(locks_inode(filp)); - if (!ctx) - return; - -@@ -2682,7 +2682,7 @@ bool vfs_inode_has_locks(struct inode *inode) - struct file_lock_context *ctx; - bool ret; - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx) - return false; - -@@ -2863,7 +2863,7 @@ void show_fd_locks(struct seq_file *f, - struct file_lock_context *ctx; - int id = 0; - -- ctx = smp_load_acquire(&inode->i_flctx); -+ ctx = locks_inode_context(inode); - if (!ctx) - return; - -diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h -index 3fa77ad7258f2..c8a57cfde64b4 100644 ---- a/fs/nfs/nfs4trace.h -+++ b/fs/nfs/nfs4trace.h -@@ -9,10 +9,10 @@ - #define _TRACE_NFS4_H - - #include --#include -+#include - --#include --#include -+#include -+#include - - #define show_nfs_fattr_flags(valid) \ - __print_flags((unsigned long)valid, "|", \ -diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h -index 8c6cc58679ff8..642f6921852fa 100644 ---- a/fs/nfs/nfstrace.h -+++ b/fs/nfs/nfstrace.h -@@ -11,9 +11,9 @@ - #include - #include - --#include --#include --#include -+#include -+#include -+#include - - #define nfs_show_cache_validity(v) \ - __print_flags(v, "|", \ -diff --git a/fs/nfs/write.c b/fs/nfs/write.c -index f41d24b54fd1f..6a06066684172 100644 ---- a/fs/nfs/write.c -+++ b/fs/nfs/write.c -@@ -667,8 +667,10 @@ static int nfs_writepage_locked(struct page *page, - int err; - - if (wbc->sync_mode == WB_SYNC_NONE && -- NFS_SERVER(inode)->write_congested) -+ NFS_SERVER(inode)->write_congested) { -+ redirty_page_for_writepage(wbc, page); - return AOP_WRITEPAGE_ACTIVATE; -+ } - - nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); - nfs_pageio_init_write(&pgio, inode, 0, -diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig -index f6a2fd3015e75..7c441f2bd4440 100644 ---- a/fs/nfsd/Kconfig -+++ b/fs/nfsd/Kconfig -@@ -8,6 +8,7 @@ config NFSD - select SUNRPC - select EXPORTFS - select NFS_ACL_SUPPORT if NFSD_V2_ACL -+ select NFS_ACL_SUPPORT if NFSD_V3_ACL - depends on MULTIUSER - help - Choose Y here if you want to allow other computers to access -@@ -26,19 +27,29 @@ config NFSD - - Below you can choose which versions of the NFS protocol are - available to clients mounting the NFS server on this system. -- Support for NFS version 2 (RFC 1094) is always available when -+ Support for NFS version 3 (RFC 1813) is always available when - CONFIG_NFSD is selected. - - If unsure, say N. - --config NFSD_V2_ACL -- bool -+config NFSD_V2 -+ bool "NFS server support for NFS version 2 (DEPRECATED)" - depends on NFSD -+ default n -+ help -+ NFSv2 (RFC 1094) was the first publicly-released version of NFS. -+ Unless you are hosting ancient (1990's era) NFS clients, you don't -+ need this. -+ -+ If unsure, say N. -+ -+config NFSD_V2_ACL -+ bool "NFS server support for the NFSv2 ACL protocol extension" -+ depends on NFSD_V2 - - config NFSD_V3_ACL - bool "NFS server support for the NFSv3 ACL protocol extension" - depends on NFSD -- select NFSD_V2_ACL - help - Solaris NFS servers support an auxiliary NFSv3 ACL protocol that - never became an official part of the NFS version 3 protocol. -diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile -index 805c06d5f1b4b..6fffc8f03f740 100644 ---- a/fs/nfsd/Makefile -+++ b/fs/nfsd/Makefile -@@ -10,9 +10,10 @@ obj-$(CONFIG_NFSD) += nfsd.o - # this one should be compiled first, as the tracing macros can easily blow up - nfsd-y += trace.o - --nfsd-y += nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ -- export.o auth.o lockd.o nfscache.o nfsxdr.o \ -+nfsd-y += nfssvc.o nfsctl.o nfsfh.o vfs.o \ -+ export.o auth.o lockd.o nfscache.o \ - stats.o filecache.o nfs3proc.o nfs3xdr.o -+nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o - nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o - nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o - nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ -diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c -index e7e6e78d965db..01d7fd108cf3d 100644 ---- a/fs/nfsd/blocklayout.c -+++ b/fs/nfsd/blocklayout.c -@@ -12,6 +12,7 @@ - #include "blocklayoutxdr.h" - #include "pnfs.h" - #include "filecache.h" -+#include "vfs.h" - - #define NFSDDBG_FACILITY NFSDDBG_PNFS - -diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c -index 2455dc8be18a8..1ed2f691ebb90 100644 ---- a/fs/nfsd/blocklayoutxdr.c -+++ b/fs/nfsd/blocklayoutxdr.c -@@ -9,6 +9,7 @@ - - #include "nfsd.h" - #include "blocklayoutxdr.h" -+#include "vfs.h" - - #define NFSDDBG_FACILITY NFSDDBG_PNFS - -diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h -index ee0e3aba4a6e5..d03f7f6a8642d 100644 ---- a/fs/nfsd/export.h -+++ b/fs/nfsd/export.h -@@ -115,7 +115,6 @@ struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *); - int exp_rootfh(struct net *, struct auth_domain *, - char *path, struct knfsd_fh *, int maxsize); - __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); --__be32 nfserrno(int errno); - - static inline void exp_put(struct svc_export *exp) - { -diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c -index 5cb8cce153a57..697acf5c3c681 100644 ---- a/fs/nfsd/filecache.c -+++ b/fs/nfsd/filecache.c -@@ -1,7 +1,32 @@ -+// SPDX-License-Identifier: GPL-2.0 - /* -- * Open file cache. -+ * The NFSD open file cache. - * - * (c) 2015 - Jeff Layton -+ * -+ * An nfsd_file object is a per-file collection of open state that binds -+ * together: -+ * - a struct file * -+ * - a user credential -+ * - a network namespace -+ * - a read-ahead context -+ * - monitoring for writeback errors -+ * -+ * nfsd_file objects are reference-counted. Consumers acquire a new -+ * object via the nfsd_file_acquire API. They manage their interest in -+ * the acquired object, and hence the object's reference count, via -+ * nfsd_file_get and nfsd_file_put. There are two varieties of nfsd_file -+ * object: -+ * -+ * * non-garbage-collected: When a consumer wants to precisely control -+ * the lifetime of a file's open state, it acquires a non-garbage- -+ * collected nfsd_file. The final nfsd_file_put releases the open -+ * state immediately. -+ * -+ * * garbage-collected: When a consumer does not control the lifetime -+ * of open state, it acquires a garbage-collected nfsd_file. The -+ * final nfsd_file_put allows the open state to linger for a period -+ * during which it may be re-used. - */ - - #include -@@ -186,12 +211,9 @@ static const struct rhashtable_params nfsd_file_rhash_params = { - static void - nfsd_file_schedule_laundrette(void) - { -- if ((atomic_read(&nfsd_file_rhash_tbl.nelems) == 0) || -- test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 0) -- return; -- -- queue_delayed_work(system_wq, &nfsd_filecache_laundrette, -- NFSD_LAUNDRETTE_DELAY); -+ if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags)) -+ queue_delayed_work(system_wq, &nfsd_filecache_laundrette, -+ NFSD_LAUNDRETTE_DELAY); - } - - static void -@@ -589,7 +611,8 @@ static void - nfsd_file_gc_worker(struct work_struct *work) - { - nfsd_file_gc(); -- nfsd_file_schedule_laundrette(); -+ if (list_lru_count(&nfsd_file_lru)) -+ nfsd_file_schedule_laundrette(); - } - - static unsigned long -diff --git a/fs/nfsd/flexfilelayout.c b/fs/nfsd/flexfilelayout.c -index 070f90ed09b61..3ca5304440ff0 100644 ---- a/fs/nfsd/flexfilelayout.c -+++ b/fs/nfsd/flexfilelayout.c -@@ -15,6 +15,7 @@ - - #include "flexfilelayoutxdr.h" - #include "pnfs.h" -+#include "vfs.h" - - #define NFSDDBG_FACILITY NFSDDBG_PNFS - -diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h -index 8c854ba3285bb..51a4b7885cae2 100644 ---- a/fs/nfsd/netns.h -+++ b/fs/nfsd/netns.h -@@ -195,7 +195,7 @@ struct nfsd_net { - - atomic_t nfsd_courtesy_clients; - struct shrinker nfsd_client_shrinker; -- struct delayed_work nfsd_shrinker_work; -+ struct work_struct nfsd_shrinker_work; - }; - - /* Simple check to find out if a given net was properly initialized */ -diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c -index 39989c14c8a1e..4eae2c5af2edf 100644 ---- a/fs/nfsd/nfs4callback.c -+++ b/fs/nfsd/nfs4callback.c -@@ -76,6 +76,17 @@ static __be32 *xdr_encode_empty_array(__be32 *p) - * 1 Protocol" - */ - -+static void encode_uint32(struct xdr_stream *xdr, u32 n) -+{ -+ WARN_ON_ONCE(xdr_stream_encode_u32(xdr, n) < 0); -+} -+ -+static void encode_bitmap4(struct xdr_stream *xdr, const __u32 *bitmap, -+ size_t len) -+{ -+ WARN_ON_ONCE(xdr_stream_encode_uint32_array(xdr, bitmap, len) < 0); -+} -+ - /* - * nfs_cb_opnum4 - * -@@ -328,6 +339,24 @@ static void encode_cb_recall4args(struct xdr_stream *xdr, - hdr->nops++; - } - -+/* -+ * CB_RECALLANY4args -+ * -+ * struct CB_RECALLANY4args { -+ * uint32_t craa_objects_to_keep; -+ * bitmap4 craa_type_mask; -+ * }; -+ */ -+static void -+encode_cb_recallany4args(struct xdr_stream *xdr, -+ struct nfs4_cb_compound_hdr *hdr, struct nfsd4_cb_recall_any *ra) -+{ -+ encode_nfs_cb_opnum4(xdr, OP_CB_RECALL_ANY); -+ encode_uint32(xdr, ra->ra_keep); -+ encode_bitmap4(xdr, ra->ra_bmval, ARRAY_SIZE(ra->ra_bmval)); -+ hdr->nops++; -+} -+ - /* - * CB_SEQUENCE4args - * -@@ -482,6 +511,26 @@ static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr, - encode_cb_nops(&hdr); - } - -+/* -+ * 20.6. Operation 8: CB_RECALL_ANY - Keep Any N Recallable Objects -+ */ -+static void -+nfs4_xdr_enc_cb_recall_any(struct rpc_rqst *req, -+ struct xdr_stream *xdr, const void *data) -+{ -+ const struct nfsd4_callback *cb = data; -+ struct nfsd4_cb_recall_any *ra; -+ struct nfs4_cb_compound_hdr hdr = { -+ .ident = cb->cb_clp->cl_cb_ident, -+ .minorversion = cb->cb_clp->cl_minorversion, -+ }; -+ -+ ra = container_of(cb, struct nfsd4_cb_recall_any, ra_cb); -+ encode_cb_compound4args(xdr, &hdr); -+ encode_cb_sequence4args(xdr, cb, &hdr); -+ encode_cb_recallany4args(xdr, &hdr, ra); -+ encode_cb_nops(&hdr); -+} - - /* - * NFSv4.0 and NFSv4.1 XDR decode functions -@@ -520,6 +569,28 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, - return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status); - } - -+/* -+ * 20.6. Operation 8: CB_RECALL_ANY - Keep Any N Recallable Objects -+ */ -+static int -+nfs4_xdr_dec_cb_recall_any(struct rpc_rqst *rqstp, -+ struct xdr_stream *xdr, -+ void *data) -+{ -+ struct nfsd4_callback *cb = data; -+ struct nfs4_cb_compound_hdr hdr; -+ int status; -+ -+ status = decode_cb_compound4res(xdr, &hdr); -+ if (unlikely(status)) -+ return status; -+ status = decode_cb_sequence4res(xdr, cb); -+ if (unlikely(status || cb->cb_seq_status)) -+ return status; -+ status = decode_cb_op_status(xdr, OP_CB_RECALL_ANY, &cb->cb_status); -+ return status; -+} -+ - #ifdef CONFIG_NFSD_PNFS - /* - * CB_LAYOUTRECALL4args -@@ -783,6 +854,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = { - #endif - PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), - PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), -+ PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), - }; - - static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)]; -diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c -index e70a1a2999b7b..5e9809aff37eb 100644 ---- a/fs/nfsd/nfs4idmap.c -+++ b/fs/nfsd/nfs4idmap.c -@@ -41,6 +41,7 @@ - #include "idmap.h" - #include "nfsd.h" - #include "netns.h" -+#include "vfs.h" - - /* - * Turn off idmapping when using AUTH_SYS. -diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c -index a9105e95b59c5..ba53cd89ec62c 100644 ---- a/fs/nfsd/nfs4proc.c -+++ b/fs/nfsd/nfs4proc.c -@@ -943,12 +943,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - &read->rd_stateid, RD_STATE, - &read->rd_nf, NULL); -- if (status) { -- dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); -- goto out; -- } -- status = nfs_ok; --out: -+ - read->rd_rqstp = rqstp; - read->rd_fhp = &cstate->current_fh; - return status; -@@ -1117,10 +1112,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - status = nfs4_preprocess_stateid_op(rqstp, cstate, - &cstate->current_fh, &setattr->sa_stateid, - WR_STATE, NULL, NULL); -- if (status) { -- dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); -+ if (status) - return status; -- } - } - err = fh_want_write(&cstate->current_fh); - if (err) -@@ -1170,10 +1163,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - write->wr_offset, cnt); - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - stateid, WR_STATE, &nf, NULL); -- if (status) { -- dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); -+ if (status) - return status; -- } - - write->wr_how_written = write->wr_stable_how; - -@@ -1204,17 +1195,13 @@ nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, - src_stateid, RD_STATE, src, NULL); -- if (status) { -- dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); -+ if (status) - goto out; -- } - - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - dst_stateid, WR_STATE, dst, NULL); -- if (status) { -- dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); -+ if (status) - goto out_put_src; -- } - - /* fix up for NFS-specific error code */ - if (!S_ISREG(file_inode((*src)->nf_file)->i_mode) || -@@ -1935,10 +1922,8 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - &fallocate->falloc_stateid, - WR_STATE, &nf, NULL); -- if (status != nfs_ok) { -- dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); -+ if (status != nfs_ok) - return status; -- } - - status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, nf->nf_file, - fallocate->falloc_offset, -@@ -1994,10 +1979,8 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - &seek->seek_stateid, - RD_STATE, &nf, NULL); -- if (status) { -- dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); -+ if (status) - return status; -- } - - switch (seek->seek_whence) { - case NFS4_CONTENT_DATA: -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index b3f6dda930d8b..b9d694ec25d19 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -44,7 +44,9 @@ - #include - #include - #include -+#include - #include -+ - #include "xdr4.h" - #include "xdr4cb.h" - #include "vfs.h" -@@ -84,6 +86,7 @@ static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - static void nfs4_free_ol_stateid(struct nfs4_stid *stid); - void nfsd4_end_grace(struct nfsd_net *nn); - static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); -+static void nfsd4_file_hash_remove(struct nfs4_file *fi); - - /* Locking: */ - -@@ -588,11 +591,8 @@ static void nfsd4_free_file_rcu(struct rcu_head *rcu) - void - put_nfs4_file(struct nfs4_file *fi) - { -- might_lock(&state_lock); -- -- if (refcount_dec_and_lock(&fi->fi_ref, &state_lock)) { -- hlist_del_rcu(&fi->fi_hash); -- spin_unlock(&state_lock); -+ if (refcount_dec_and_test(&fi->fi_ref)) { -+ nfsd4_file_hash_remove(fi); - WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate)); - WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); - call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); -@@ -717,19 +717,20 @@ static unsigned int ownerstr_hashval(struct xdr_netobj *ownername) - return ret & OWNER_HASH_MASK; - } - --/* hash table for nfs4_file */ --#define FILE_HASH_BITS 8 --#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) -- --static unsigned int file_hashval(struct svc_fh *fh) --{ -- struct inode *inode = d_inode(fh->fh_dentry); -+static struct rhltable nfs4_file_rhltable ____cacheline_aligned_in_smp; - -- /* XXX: why not (here & in file cache) use inode? */ -- return (unsigned int)hash_long(inode->i_ino, FILE_HASH_BITS); --} -+static const struct rhashtable_params nfs4_file_rhash_params = { -+ .key_len = sizeof_field(struct nfs4_file, fi_inode), -+ .key_offset = offsetof(struct nfs4_file, fi_inode), -+ .head_offset = offsetof(struct nfs4_file, fi_rlist), - --static struct hlist_head file_hashtbl[FILE_HASH_SIZE]; -+ /* -+ * Start with a single page hash table to reduce resizing churn -+ * on light workloads. -+ */ -+ .min_size = 256, -+ .automatic_shrinking = true, -+}; - - /* - * Check if courtesy clients have conflicting access and resolve it if possible -@@ -1367,6 +1368,8 @@ static void revoke_delegation(struct nfs4_delegation *dp) - - WARN_ON(!list_empty(&dp->dl_recall_lru)); - -+ trace_nfsd_stid_revoke(&dp->dl_stid); -+ - if (clp->cl_minorversion) { - spin_lock(&clp->cl_lock); - dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID; -@@ -1831,13 +1834,12 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs, - int numslots = fattrs->maxreqs; - int slotsize = slot_bytes(fattrs); - struct nfsd4_session *new; -- int mem, i; -+ int i; - -- BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot *) -- + sizeof(struct nfsd4_session) > PAGE_SIZE); -- mem = numslots * sizeof(struct nfsd4_slot *); -+ BUILD_BUG_ON(struct_size(new, se_slots, NFSD_MAX_SLOTS_PER_SESSION) -+ > PAGE_SIZE); - -- new = kzalloc(sizeof(*new) + mem, GFP_KERNEL); -+ new = kzalloc(struct_size(new, se_slots, numslots), GFP_KERNEL); - if (!new) - return NULL; - /* allocate each struct nfsd4_slot and data cache in one piece */ -@@ -2143,6 +2145,7 @@ static void __free_client(struct kref *k) - kfree(clp->cl_nii_domain.data); - kfree(clp->cl_nii_name.data); - idr_destroy(&clp->cl_stateids); -+ kfree(clp->cl_ra); - kmem_cache_free(client_slab, clp); - } - -@@ -2870,6 +2873,37 @@ static const struct tree_descr client_files[] = { - [3] = {""}, - }; - -+static int -+nfsd4_cb_recall_any_done(struct nfsd4_callback *cb, -+ struct rpc_task *task) -+{ -+ trace_nfsd_cb_recall_any_done(cb, task); -+ switch (task->tk_status) { -+ case -NFS4ERR_DELAY: -+ rpc_delay(task, 2 * HZ); -+ return 0; -+ default: -+ return 1; -+ } -+} -+ -+static void -+nfsd4_cb_recall_any_release(struct nfsd4_callback *cb) -+{ -+ struct nfs4_client *clp = cb->cb_clp; -+ struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); -+ -+ spin_lock(&nn->client_lock); -+ clear_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); -+ put_client_renew_locked(clp); -+ spin_unlock(&nn->client_lock); -+} -+ -+static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops = { -+ .done = nfsd4_cb_recall_any_done, -+ .release = nfsd4_cb_recall_any_release, -+}; -+ - static struct nfs4_client *create_client(struct xdr_netobj name, - struct svc_rqst *rqstp, nfs4_verifier *verf) - { -@@ -2907,6 +2941,14 @@ static struct nfs4_client *create_client(struct xdr_netobj name, - free_client(clp); - return NULL; - } -+ clp->cl_ra = kzalloc(sizeof(*clp->cl_ra), GFP_KERNEL); -+ if (!clp->cl_ra) { -+ free_client(clp); -+ return NULL; -+ } -+ clp->cl_ra_time = 0; -+ nfsd4_init_cb(&clp->cl_ra->ra_cb, clp, &nfsd4_cb_recall_any_ops, -+ NFSPROC4_CLNT_CB_RECALL_ANY); - return clp; - } - -@@ -4276,11 +4318,9 @@ static struct nfs4_file *nfsd4_alloc_file(void) - } - - /* OPEN Share state helper functions */ --static void nfsd4_init_file(struct svc_fh *fh, unsigned int hashval, -- struct nfs4_file *fp) --{ -- lockdep_assert_held(&state_lock); - -+static void nfsd4_file_init(const struct svc_fh *fh, struct nfs4_file *fp) -+{ - refcount_set(&fp->fi_ref, 1); - spin_lock_init(&fp->fi_lock); - INIT_LIST_HEAD(&fp->fi_stateids); -@@ -4298,7 +4338,6 @@ static void nfsd4_init_file(struct svc_fh *fh, unsigned int hashval, - INIT_LIST_HEAD(&fp->fi_lo_states); - atomic_set(&fp->fi_lo_recalls, 0); - #endif -- hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]); - } - - void -@@ -4363,25 +4402,27 @@ nfsd4_init_slabs(void) - } - - static unsigned long --nfsd_courtesy_client_count(struct shrinker *shrink, struct shrink_control *sc) -+nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc) - { -- int cnt; -+ int count; - struct nfsd_net *nn = container_of(shrink, - struct nfsd_net, nfsd_client_shrinker); - -- cnt = atomic_read(&nn->nfsd_courtesy_clients); -- if (cnt > 0) -- mod_delayed_work(laundry_wq, &nn->nfsd_shrinker_work, 0); -- return (unsigned long)cnt; -+ count = atomic_read(&nn->nfsd_courtesy_clients); -+ if (!count) -+ count = atomic_long_read(&num_delegations); -+ if (count) -+ queue_work(laundry_wq, &nn->nfsd_shrinker_work); -+ return (unsigned long)count; - } - - static unsigned long --nfsd_courtesy_client_scan(struct shrinker *shrink, struct shrink_control *sc) -+nfsd4_state_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc) - { - return SHRINK_STOP; - } - --int -+void - nfsd4_init_leases_net(struct nfsd_net *nn) - { - struct sysinfo si; -@@ -4403,16 +4444,6 @@ nfsd4_init_leases_net(struct nfsd_net *nn) - nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB); - - atomic_set(&nn->nfsd_courtesy_clients, 0); -- nn->nfsd_client_shrinker.scan_objects = nfsd_courtesy_client_scan; -- nn->nfsd_client_shrinker.count_objects = nfsd_courtesy_client_count; -- nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; -- return register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client"); --} -- --void --nfsd4_leases_net_shutdown(struct nfsd_net *nn) --{ -- unregister_shrinker(&nn->nfsd_client_shrinker); - } - - static void init_nfs4_replay(struct nfs4_replay *rp) -@@ -4683,71 +4714,80 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) - nfs4_put_stid(&last->st_stid); - } - --/* search file_hashtbl[] for file */ --static struct nfs4_file * --find_file_locked(struct svc_fh *fh, unsigned int hashval) -+static noinline_for_stack struct nfs4_file * -+nfsd4_file_hash_lookup(const struct svc_fh *fhp) - { -- struct nfs4_file *fp; -+ struct inode *inode = d_inode(fhp->fh_dentry); -+ struct rhlist_head *tmp, *list; -+ struct nfs4_file *fi; - -- hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, -- lockdep_is_held(&state_lock)) { -- if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { -- if (refcount_inc_not_zero(&fp->fi_ref)) -- return fp; -+ rcu_read_lock(); -+ list = rhltable_lookup(&nfs4_file_rhltable, &inode, -+ nfs4_file_rhash_params); -+ rhl_for_each_entry_rcu(fi, tmp, list, fi_rlist) { -+ if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { -+ if (refcount_inc_not_zero(&fi->fi_ref)) { -+ rcu_read_unlock(); -+ return fi; -+ } - } - } -+ rcu_read_unlock(); - return NULL; - } - --static struct nfs4_file *insert_file(struct nfs4_file *new, struct svc_fh *fh, -- unsigned int hashval) -+/* -+ * On hash insertion, identify entries with the same inode but -+ * distinct filehandles. They will all be on the list returned -+ * by rhltable_lookup(). -+ * -+ * inode->i_lock prevents racing insertions from adding an entry -+ * for the same inode/fhp pair twice. -+ */ -+static noinline_for_stack struct nfs4_file * -+nfsd4_file_hash_insert(struct nfs4_file *new, const struct svc_fh *fhp) - { -- struct nfs4_file *fp; -+ struct inode *inode = d_inode(fhp->fh_dentry); -+ struct rhlist_head *tmp, *list; - struct nfs4_file *ret = NULL; - bool alias_found = false; -+ struct nfs4_file *fi; -+ int err; - -- spin_lock(&state_lock); -- hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, -- lockdep_is_held(&state_lock)) { -- if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { -- if (refcount_inc_not_zero(&fp->fi_ref)) -- ret = fp; -- } else if (d_inode(fh->fh_dentry) == fp->fi_inode) -- fp->fi_aliased = alias_found = true; -- } -- if (likely(ret == NULL)) { -- nfsd4_init_file(fh, hashval, new); -- new->fi_aliased = alias_found; -- ret = new; -+ rcu_read_lock(); -+ spin_lock(&inode->i_lock); -+ -+ list = rhltable_lookup(&nfs4_file_rhltable, &inode, -+ nfs4_file_rhash_params); -+ rhl_for_each_entry_rcu(fi, tmp, list, fi_rlist) { -+ if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { -+ if (refcount_inc_not_zero(&fi->fi_ref)) -+ ret = fi; -+ } else -+ fi->fi_aliased = alias_found = true; - } -- spin_unlock(&state_lock); -- return ret; --} -+ if (ret) -+ goto out_unlock; - --static struct nfs4_file * find_file(struct svc_fh *fh) --{ -- struct nfs4_file *fp; -- unsigned int hashval = file_hashval(fh); -+ nfsd4_file_init(fhp, new); -+ err = rhltable_insert(&nfs4_file_rhltable, &new->fi_rlist, -+ nfs4_file_rhash_params); -+ if (err) -+ goto out_unlock; - -- rcu_read_lock(); -- fp = find_file_locked(fh, hashval); -+ new->fi_aliased = alias_found; -+ ret = new; -+ -+out_unlock: -+ spin_unlock(&inode->i_lock); - rcu_read_unlock(); -- return fp; -+ return ret; - } - --static struct nfs4_file * --find_or_add_file(struct nfs4_file *new, struct svc_fh *fh) -+static noinline_for_stack void nfsd4_file_hash_remove(struct nfs4_file *fi) - { -- struct nfs4_file *fp; -- unsigned int hashval = file_hashval(fh); -- -- rcu_read_lock(); -- fp = find_file_locked(fh, hashval); -- rcu_read_unlock(); -- if (fp) -- return fp; -- -- return insert_file(new, fh, hashval); -+ rhltable_remove(&nfs4_file_rhltable, &fi->fi_rlist, -+ nfs4_file_rhash_params); - } - - /* -@@ -4760,9 +4800,10 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) - struct nfs4_file *fp; - __be32 ret = nfs_ok; - -- fp = find_file(current_fh); -+ fp = nfsd4_file_hash_lookup(current_fh); - if (!fp) - return ret; -+ - /* Check for conflicting share reservations */ - spin_lock(&fp->fi_lock); - if (fp->fi_share_deny & deny_type) -@@ -4774,7 +4815,7 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) - - static bool nfsd4_deleg_present(const struct inode *inode) - { -- struct file_lock_context *ctx = smp_load_acquire(&inode->i_flctx); -+ struct file_lock_context *ctx = locks_inode_context(inode); - - return ctx && !list_empty_careful(&ctx->flc_lease); - } -@@ -5655,7 +5696,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf - * and check for delegations in the process of being recalled. - * If not found, create the nfs4_file struct - */ -- fp = find_or_add_file(open->op_file, current_fh); -+ fp = nfsd4_file_hash_insert(open->op_file, current_fh); -+ if (unlikely(!fp)) -+ return nfserr_jukebox; - if (fp != open->op_file) { - status = nfs4_check_deleg(cl, open, &dp); - if (status) -@@ -5932,7 +5975,7 @@ nfs4_lockowner_has_blockers(struct nfs4_lockowner *lo) - - list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) { - nf = stp->st_stid.sc_file; -- ctx = nf->fi_inode->i_flctx; -+ ctx = locks_inode_context(nf->fi_inode); - if (!ctx) - continue; - if (locks_owner_has_blockers(ctx, lo)) -@@ -6160,17 +6203,63 @@ laundromat_main(struct work_struct *laundry) - } - - static void --courtesy_client_reaper(struct work_struct *reaper) -+courtesy_client_reaper(struct nfsd_net *nn) - { - struct list_head reaplist; -- struct delayed_work *dwork = to_delayed_work(reaper); -- struct nfsd_net *nn = container_of(dwork, struct nfsd_net, -- nfsd_shrinker_work); - - nfs4_get_courtesy_client_reaplist(nn, &reaplist); - nfs4_process_client_reaplist(&reaplist); - } - -+static void -+deleg_reaper(struct nfsd_net *nn) -+{ -+ struct list_head *pos, *next; -+ struct nfs4_client *clp; -+ struct list_head cblist; -+ -+ INIT_LIST_HEAD(&cblist); -+ spin_lock(&nn->client_lock); -+ list_for_each_safe(pos, next, &nn->client_lru) { -+ clp = list_entry(pos, struct nfs4_client, cl_lru); -+ if (clp->cl_state != NFSD4_ACTIVE || -+ list_empty(&clp->cl_delegations) || -+ atomic_read(&clp->cl_delegs_in_recall) || -+ test_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags) || -+ (ktime_get_boottime_seconds() - -+ clp->cl_ra_time < 5)) { -+ continue; -+ } -+ list_add(&clp->cl_ra_cblist, &cblist); -+ -+ /* release in nfsd4_cb_recall_any_release */ -+ atomic_inc(&clp->cl_rpc_users); -+ set_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); -+ clp->cl_ra_time = ktime_get_boottime_seconds(); -+ } -+ spin_unlock(&nn->client_lock); -+ -+ while (!list_empty(&cblist)) { -+ clp = list_first_entry(&cblist, struct nfs4_client, -+ cl_ra_cblist); -+ list_del_init(&clp->cl_ra_cblist); -+ clp->cl_ra->ra_keep = 0; -+ clp->cl_ra->ra_bmval[0] = BIT(RCA4_TYPE_MASK_RDATA_DLG); -+ trace_nfsd_cb_recall_any(clp->cl_ra); -+ nfsd4_run_cb(&clp->cl_ra->ra_cb); -+ } -+} -+ -+static void -+nfsd4_state_shrinker_worker(struct work_struct *work) -+{ -+ struct nfsd_net *nn = container_of(work, struct nfsd_net, -+ nfsd_shrinker_work); -+ -+ courtesy_client_reaper(nn); -+ deleg_reaper(nn); -+} -+ - static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stid *stp) - { - if (!fh_match(&fhp->fh_handle, &stp->sc_file->fi_fhandle)) -@@ -6935,6 +7024,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - if (status) - goto put_stateid; - -+ trace_nfsd_deleg_return(stateid); - wake_up_var(d_inode(cstate->current_fh.fh_dentry)); - destroy_delegation(dp); - put_stateid: -@@ -7748,7 +7838,7 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) - } - - inode = locks_inode(nf->nf_file); -- flctx = inode->i_flctx; -+ flctx = locks_inode_context(inode); - - if (flctx && !list_empty_careful(&flctx->flc_posix)) { - spin_lock(&flctx->flc_lock); -@@ -7995,11 +8085,20 @@ static int nfs4_state_create_net(struct net *net) - INIT_LIST_HEAD(&nn->blocked_locks_lru); - - INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main); -- INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, courtesy_client_reaper); -+ INIT_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); - get_net(net); - -+ nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; -+ nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; -+ nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; -+ -+ if (register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client")) -+ goto err_shrinker; - return 0; - -+err_shrinker: -+ put_net(net); -+ kfree(nn->sessionid_hashtbl); - err_sessionid: - kfree(nn->unconf_id_hashtbl); - err_unconf_id: -@@ -8071,10 +8170,16 @@ nfs4_state_start(void) - { - int ret; - -- ret = nfsd4_create_callback_queue(); -+ ret = rhltable_init(&nfs4_file_rhltable, &nfs4_file_rhash_params); - if (ret) - return ret; - -+ ret = nfsd4_create_callback_queue(); -+ if (ret) { -+ rhltable_destroy(&nfs4_file_rhltable); -+ return ret; -+ } -+ - set_max_delegations(); - return 0; - } -@@ -8086,6 +8191,8 @@ nfs4_state_shutdown_net(struct net *net) - struct list_head *pos, *next, reaplist; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); - -+ unregister_shrinker(&nn->nfsd_client_shrinker); -+ cancel_work(&nn->nfsd_shrinker_work); - cancel_delayed_work_sync(&nn->laundromat_work); - locks_end_grace(&nn->nfsd4_manager); - -@@ -8114,6 +8221,7 @@ void - nfs4_state_shutdown(void) - { - nfsd4_destroy_callback_queue(); -+ rhltable_destroy(&nfs4_file_rhltable); - } - - static void -diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c -index 89a579be042e5..597f14a80512f 100644 ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -770,16 +770,18 @@ nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs) - - static __be32 - nfsd4_decode_access(struct nfsd4_compoundargs *argp, -- struct nfsd4_access *access) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_access *access = &u->access; - if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0) - return nfserr_bad_xdr; - return nfs_ok; - } - - static __be32 --nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) -+nfsd4_decode_close(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_close *close = &u->close; - if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0) - return nfserr_bad_xdr; - return nfsd4_decode_stateid4(argp, &close->cl_stateid); -@@ -787,8 +789,9 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) - - - static __be32 --nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) -+nfsd4_decode_commit(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_commit *commit = &u->commit; - if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0) - return nfserr_bad_xdr; - if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0) -@@ -798,8 +801,9 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit - } - - static __be32 --nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) -+nfsd4_decode_create(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_create *create = &u->create; - __be32 *p, status; - - memset(create, 0, sizeof(*create)); -@@ -844,22 +848,25 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create - } - - static inline __be32 --nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) -+nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_delegreturn *dr = &u->delegreturn; - return nfsd4_decode_stateid4(argp, &dr->dr_stateid); - } - - static inline __be32 --nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) -+nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_getattr *getattr = &u->getattr; - memset(getattr, 0, sizeof(*getattr)); - return nfsd4_decode_bitmap4(argp, getattr->ga_bmval, - ARRAY_SIZE(getattr->ga_bmval)); - } - - static __be32 --nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) -+nfsd4_decode_link(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_link *link = &u->link; - memset(link, 0, sizeof(*link)); - return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen); - } -@@ -907,8 +914,9 @@ nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) - } - - static __be32 --nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) -+nfsd4_decode_lock(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_lock *lock = &u->lock; - memset(lock, 0, sizeof(*lock)); - if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0) - return nfserr_bad_xdr; -@@ -924,8 +932,9 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) - } - - static __be32 --nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) -+nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_lockt *lockt = &u->lockt; - memset(lockt, 0, sizeof(*lockt)); - if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0) - return nfserr_bad_xdr; -@@ -940,8 +949,9 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) - } - - static __be32 --nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) -+nfsd4_decode_locku(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_locku *locku = &u->locku; - __be32 status; - - if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0) -@@ -962,8 +972,9 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) - } - - static __be32 --nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) -+nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_lookup *lookup = &u->lookup; - return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len); - } - -@@ -1143,8 +1154,9 @@ nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp, - } - - static __be32 --nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) -+nfsd4_decode_open(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_open *open = &u->open; - __be32 status; - u32 dummy; - -@@ -1171,8 +1183,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) - } - - static __be32 --nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) -+nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_open_confirm *open_conf = &u->open_confirm; - __be32 status; - - if (argp->minorversion >= 1) -@@ -1190,8 +1204,10 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con - } - - static __be32 --nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) -+nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_open_downgrade *open_down = &u->open_downgrade; - __be32 status; - - memset(open_down, 0, sizeof(*open_down)); -@@ -1209,8 +1225,9 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d - } - - static __be32 --nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) -+nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_putfh *putfh = &u->putfh; - __be32 *p; - - if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0) -@@ -1229,7 +1246,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) - } - - static __be32 --nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) -+nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) - { - if (argp->minorversion == 0) - return nfs_ok; -@@ -1237,8 +1254,9 @@ nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) - } - - static __be32 --nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) -+nfsd4_decode_read(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_read *read = &u->read; - __be32 status; - - memset(read, 0, sizeof(*read)); -@@ -1254,8 +1272,9 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) - } - - static __be32 --nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) -+nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_readdir *readdir = &u->readdir; - __be32 status; - - memset(readdir, 0, sizeof(*readdir)); -@@ -1276,15 +1295,17 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read - } - - static __be32 --nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) -+nfsd4_decode_remove(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_remove *remove = &u->remove; - memset(&remove->rm_cinfo, 0, sizeof(remove->rm_cinfo)); - return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen); - } - - static __be32 --nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) -+nfsd4_decode_rename(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_rename *rename = &u->rename; - __be32 status; - - memset(rename, 0, sizeof(*rename)); -@@ -1295,22 +1316,25 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename - } - - static __be32 --nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) -+nfsd4_decode_renew(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ clientid_t *clientid = &u->renew; - return nfsd4_decode_clientid4(argp, clientid); - } - - static __be32 - nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, -- struct nfsd4_secinfo *secinfo) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_secinfo *secinfo = &u->secinfo; - secinfo->si_exp = NULL; - return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen); - } - - static __be32 --nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) -+nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_setattr *setattr = &u->setattr; - __be32 status; - - memset(setattr, 0, sizeof(*setattr)); -@@ -1324,8 +1348,9 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta - } - - static __be32 --nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) -+nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_setclientid *setclientid = &u->setclientid; - __be32 *p, status; - - memset(setclientid, 0, sizeof(*setclientid)); -@@ -1367,8 +1392,10 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient - } - - static __be32 --nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) -+nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_setclientid_confirm *scd_c = &u->setclientid_confirm; - __be32 status; - - if (argp->minorversion >= 1) -@@ -1382,8 +1409,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s - - /* Also used for NVERIFY */ - static __be32 --nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) -+nfsd4_decode_verify(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_verify *verify = &u->verify; - __be32 *p, status; - - memset(verify, 0, sizeof(*verify)); -@@ -1409,8 +1437,9 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify - } - - static __be32 --nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) -+nfsd4_decode_write(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_write *write = &u->write; - __be32 status; - - status = nfsd4_decode_stateid4(argp, &write->wr_stateid); -@@ -1434,8 +1463,10 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) - } - - static __be32 --nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) -+nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; - __be32 status; - - if (argp->minorversion >= 1) -@@ -1452,16 +1483,20 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel - return nfs_ok; - } - --static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc) -+static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_backchannel_ctl *bc = &u->backchannel_ctl; - memset(bc, 0, sizeof(*bc)); - if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0) - return nfserr_bad_xdr; - return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec); - } - --static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) -+static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session; - u32 use_conn_in_rdma_mode; - __be32 status; - -@@ -1603,8 +1638,9 @@ nfsd4_decode_nfs_impl_id4(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, -- struct nfsd4_exchange_id *exid) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_exchange_id *exid = &u->exchange_id; - __be32 status; - - memset(exid, 0, sizeof(*exid)); -@@ -1656,8 +1692,9 @@ nfsd4_decode_channel_attrs4(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, -- struct nfsd4_create_session *sess) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_create_session *sess = &u->create_session; - __be32 status; - - memset(sess, 0, sizeof(*sess)); -@@ -1681,23 +1718,26 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp, -- struct nfsd4_destroy_session *destroy_session) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_destroy_session *destroy_session = &u->destroy_session; - return nfsd4_decode_sessionid4(argp, &destroy_session->sessionid); - } - - static __be32 - nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, -- struct nfsd4_free_stateid *free_stateid) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_free_stateid *free_stateid = &u->free_stateid; - return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid); - } - - #ifdef CONFIG_NFSD_PNFS - static __be32 - nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp, -- struct nfsd4_getdeviceinfo *gdev) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_getdeviceinfo *gdev = &u->getdeviceinfo; - __be32 status; - - memset(gdev, 0, sizeof(*gdev)); -@@ -1717,8 +1757,9 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp, -- struct nfsd4_layoutcommit *lcp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutcommit *lcp = &u->layoutcommit; - __be32 *p, status; - - memset(lcp, 0, sizeof(*lcp)); -@@ -1753,8 +1794,9 @@ nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp, -- struct nfsd4_layoutget *lgp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutget *lgp = &u->layoutget; - __be32 status; - - memset(lgp, 0, sizeof(*lgp)); -@@ -1781,8 +1823,9 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp, -- struct nfsd4_layoutreturn *lrp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutreturn *lrp = &u->layoutreturn; - memset(lrp, 0, sizeof(*lrp)); - if (xdr_stream_decode_bool(argp->xdr, &lrp->lr_reclaim) < 0) - return nfserr_bad_xdr; -@@ -1795,8 +1838,9 @@ nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp, - #endif /* CONFIG_NFSD_PNFS */ - - static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, -- struct nfsd4_secinfo_no_name *sin) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_secinfo_no_name *sin = &u->secinfo_no_name; - if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0) - return nfserr_bad_xdr; - -@@ -1806,8 +1850,9 @@ static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, -- struct nfsd4_sequence *seq) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_sequence *seq = &u->sequence; - __be32 *p, status; - - status = nfsd4_decode_sessionid4(argp, &seq->sessionid); -@@ -1826,8 +1871,10 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, - } - - static __be32 --nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid) -+nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_test_stateid *test_stateid = &u->test_stateid; - struct nfsd4_test_stateid_id *stateid; - __be32 status; - u32 i; -@@ -1852,14 +1899,16 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta - } - - static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, -- struct nfsd4_destroy_clientid *dc) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_destroy_clientid *dc = &u->destroy_clientid; - return nfsd4_decode_clientid4(argp, &dc->clientid); - } - - static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, -- struct nfsd4_reclaim_complete *rc) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_reclaim_complete *rc = &u->reclaim_complete; - if (xdr_stream_decode_bool(argp->xdr, &rc->rca_one_fs) < 0) - return nfserr_bad_xdr; - return nfs_ok; -@@ -1867,8 +1916,9 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp, -- struct nfsd4_fallocate *fallocate) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_fallocate *fallocate = &u->allocate; - __be32 status; - - status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid); -@@ -1924,8 +1974,9 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, - } - - static __be32 --nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) -+nfsd4_decode_copy(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_copy *copy = &u->copy; - u32 consecutive, i, count, sync; - struct nl4_server *ns_dummy; - __be32 status; -@@ -1982,8 +2033,9 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) - - static __be32 - nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, -- struct nfsd4_copy_notify *cn) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_copy_notify *cn = &u->copy_notify; - __be32 status; - - memset(cn, 0, sizeof(*cn)); -@@ -2002,16 +2054,18 @@ nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp, -- struct nfsd4_offload_status *os) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_offload_status *os = &u->offload_status; - os->count = 0; - os->status = 0; - return nfsd4_decode_stateid4(argp, &os->stateid); - } - - static __be32 --nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) -+nfsd4_decode_seek(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_seek *seek = &u->seek; - __be32 status; - - status = nfsd4_decode_stateid4(argp, &seek->seek_stateid); -@@ -2028,8 +2082,9 @@ nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) - } - - static __be32 --nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone) -+nfsd4_decode_clone(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) - { -+ struct nfsd4_clone *clone = &u->clone; - __be32 status; - - status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid); -@@ -2154,8 +2209,9 @@ nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep) - */ - static __be32 - nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp, -- struct nfsd4_getxattr *getxattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_getxattr *getxattr = &u->getxattr; - __be32 status; - u32 maxcount; - -@@ -2173,8 +2229,9 @@ nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp, -- struct nfsd4_setxattr *setxattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_setxattr *setxattr = &u->setxattr; - u32 flags, maxcount, size; - __be32 status; - -@@ -2214,8 +2271,9 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp, -- struct nfsd4_listxattrs *listxattrs) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_listxattrs *listxattrs = &u->listxattrs; - u32 maxcount; - - memset(listxattrs, 0, sizeof(*listxattrs)); -@@ -2245,113 +2303,114 @@ nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp, - - static __be32 - nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp, -- struct nfsd4_removexattr *removexattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_removexattr *removexattr = &u->removexattr; - memset(removexattr, 0, sizeof(*removexattr)); - return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name); - } - - static __be32 --nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) -+nfsd4_decode_noop(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) - { - return nfs_ok; - } - - static __be32 --nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) -+nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) - { - return nfserr_notsupp; - } - --typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); -+typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u); - - static const nfsd4_dec nfsd4_dec_ops[] = { -- [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, -- [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, -- [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, -- [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, -- [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, -- [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, -- [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, -- [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, -- [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, -- [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, -- [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, -- [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, -- [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, -- [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, -- [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, -- [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, -- [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh, -- [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_READ] = (nfsd4_dec)nfsd4_decode_read, -- [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, -- [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, -- [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, -- [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew, -- [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, -- [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, -- [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, -- [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid, -- [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm, -- [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, -- [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, -- [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, -+ [OP_ACCESS] = nfsd4_decode_access, -+ [OP_CLOSE] = nfsd4_decode_close, -+ [OP_COMMIT] = nfsd4_decode_commit, -+ [OP_CREATE] = nfsd4_decode_create, -+ [OP_DELEGPURGE] = nfsd4_decode_notsupp, -+ [OP_DELEGRETURN] = nfsd4_decode_delegreturn, -+ [OP_GETATTR] = nfsd4_decode_getattr, -+ [OP_GETFH] = nfsd4_decode_noop, -+ [OP_LINK] = nfsd4_decode_link, -+ [OP_LOCK] = nfsd4_decode_lock, -+ [OP_LOCKT] = nfsd4_decode_lockt, -+ [OP_LOCKU] = nfsd4_decode_locku, -+ [OP_LOOKUP] = nfsd4_decode_lookup, -+ [OP_LOOKUPP] = nfsd4_decode_noop, -+ [OP_NVERIFY] = nfsd4_decode_verify, -+ [OP_OPEN] = nfsd4_decode_open, -+ [OP_OPENATTR] = nfsd4_decode_notsupp, -+ [OP_OPEN_CONFIRM] = nfsd4_decode_open_confirm, -+ [OP_OPEN_DOWNGRADE] = nfsd4_decode_open_downgrade, -+ [OP_PUTFH] = nfsd4_decode_putfh, -+ [OP_PUTPUBFH] = nfsd4_decode_putpubfh, -+ [OP_PUTROOTFH] = nfsd4_decode_noop, -+ [OP_READ] = nfsd4_decode_read, -+ [OP_READDIR] = nfsd4_decode_readdir, -+ [OP_READLINK] = nfsd4_decode_noop, -+ [OP_REMOVE] = nfsd4_decode_remove, -+ [OP_RENAME] = nfsd4_decode_rename, -+ [OP_RENEW] = nfsd4_decode_renew, -+ [OP_RESTOREFH] = nfsd4_decode_noop, -+ [OP_SAVEFH] = nfsd4_decode_noop, -+ [OP_SECINFO] = nfsd4_decode_secinfo, -+ [OP_SETATTR] = nfsd4_decode_setattr, -+ [OP_SETCLIENTID] = nfsd4_decode_setclientid, -+ [OP_SETCLIENTID_CONFIRM] = nfsd4_decode_setclientid_confirm, -+ [OP_VERIFY] = nfsd4_decode_verify, -+ [OP_WRITE] = nfsd4_decode_write, -+ [OP_RELEASE_LOCKOWNER] = nfsd4_decode_release_lockowner, - - /* new operations for NFSv4.1 */ -- [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, -- [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, -- [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, -- [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, -- [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, -- [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid, -- [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, -+ [OP_BACKCHANNEL_CTL] = nfsd4_decode_backchannel_ctl, -+ [OP_BIND_CONN_TO_SESSION] = nfsd4_decode_bind_conn_to_session, -+ [OP_EXCHANGE_ID] = nfsd4_decode_exchange_id, -+ [OP_CREATE_SESSION] = nfsd4_decode_create_session, -+ [OP_DESTROY_SESSION] = nfsd4_decode_destroy_session, -+ [OP_FREE_STATEID] = nfsd4_decode_free_stateid, -+ [OP_GET_DIR_DELEGATION] = nfsd4_decode_notsupp, - #ifdef CONFIG_NFSD_PNFS -- [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_getdeviceinfo, -- [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_layoutcommit, -- [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_layoutget, -- [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_layoutreturn, -+ [OP_GETDEVICEINFO] = nfsd4_decode_getdeviceinfo, -+ [OP_GETDEVICELIST] = nfsd4_decode_notsupp, -+ [OP_LAYOUTCOMMIT] = nfsd4_decode_layoutcommit, -+ [OP_LAYOUTGET] = nfsd4_decode_layoutget, -+ [OP_LAYOUTRETURN] = nfsd4_decode_layoutreturn, - #else -- [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, -+ [OP_GETDEVICEINFO] = nfsd4_decode_notsupp, -+ [OP_GETDEVICELIST] = nfsd4_decode_notsupp, -+ [OP_LAYOUTCOMMIT] = nfsd4_decode_notsupp, -+ [OP_LAYOUTGET] = nfsd4_decode_notsupp, -+ [OP_LAYOUTRETURN] = nfsd4_decode_notsupp, - #endif -- [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, -- [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, -- [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, -- [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid, -- [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, -+ [OP_SECINFO_NO_NAME] = nfsd4_decode_secinfo_no_name, -+ [OP_SEQUENCE] = nfsd4_decode_sequence, -+ [OP_SET_SSV] = nfsd4_decode_notsupp, -+ [OP_TEST_STATEID] = nfsd4_decode_test_stateid, -+ [OP_WANT_DELEGATION] = nfsd4_decode_notsupp, -+ [OP_DESTROY_CLIENTID] = nfsd4_decode_destroy_clientid, -+ [OP_RECLAIM_COMPLETE] = nfsd4_decode_reclaim_complete, - - /* new operations for NFSv4.2 */ -- [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, -- [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy, -- [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify, -- [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, -- [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_OFFLOAD_CANCEL] = (nfsd4_dec)nfsd4_decode_offload_status, -- [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_offload_status, -- [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_read, -- [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek, -- [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp, -- [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone, -+ [OP_ALLOCATE] = nfsd4_decode_fallocate, -+ [OP_COPY] = nfsd4_decode_copy, -+ [OP_COPY_NOTIFY] = nfsd4_decode_copy_notify, -+ [OP_DEALLOCATE] = nfsd4_decode_fallocate, -+ [OP_IO_ADVISE] = nfsd4_decode_notsupp, -+ [OP_LAYOUTERROR] = nfsd4_decode_notsupp, -+ [OP_LAYOUTSTATS] = nfsd4_decode_notsupp, -+ [OP_OFFLOAD_CANCEL] = nfsd4_decode_offload_status, -+ [OP_OFFLOAD_STATUS] = nfsd4_decode_offload_status, -+ [OP_READ_PLUS] = nfsd4_decode_read, -+ [OP_SEEK] = nfsd4_decode_seek, -+ [OP_WRITE_SAME] = nfsd4_decode_notsupp, -+ [OP_CLONE] = nfsd4_decode_clone, - /* RFC 8276 extended atributes operations */ -- [OP_GETXATTR] = (nfsd4_dec)nfsd4_decode_getxattr, -- [OP_SETXATTR] = (nfsd4_dec)nfsd4_decode_setxattr, -- [OP_LISTXATTRS] = (nfsd4_dec)nfsd4_decode_listxattrs, -- [OP_REMOVEXATTR] = (nfsd4_dec)nfsd4_decode_removexattr, -+ [OP_GETXATTR] = nfsd4_decode_getxattr, -+ [OP_SETXATTR] = nfsd4_decode_setxattr, -+ [OP_LISTXATTRS] = nfsd4_decode_listxattrs, -+ [OP_REMOVEXATTR] = nfsd4_decode_removexattr, - }; - - static inline bool -@@ -3643,8 +3702,10 @@ nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid) - } - - static __be32 --nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) -+nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_access *access = &u->access; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3656,8 +3717,10 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ - return 0; - } - --static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) -+static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3673,8 +3736,10 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, - } - - static __be32 --nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) -+nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_close *close = &u->close; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_encode_stateid(xdr, &close->cl_stateid); -@@ -3682,8 +3747,10 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c - - - static __be32 --nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) -+nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_commit *commit = &u->commit; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3696,8 +3763,10 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ - } - - static __be32 --nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) -+nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_create *create = &u->create; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3710,8 +3779,10 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ - } - - static __be32 --nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) -+nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_getattr *getattr = &u->getattr; - struct svc_fh *fhp = getattr->ga_fhp; - struct xdr_stream *xdr = resp->xdr; - -@@ -3720,8 +3791,10 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 - } - - static __be32 --nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp) -+nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct svc_fh **fhpp = &u->getfh; - struct xdr_stream *xdr = resp->xdr; - struct svc_fh *fhp = *fhpp; - unsigned int len; -@@ -3775,8 +3848,10 @@ nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld) - } - - static __be32 --nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) -+nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_lock *lock = &u->lock; - struct xdr_stream *xdr = resp->xdr; - - if (!nfserr) -@@ -3788,8 +3863,10 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo - } - - static __be32 --nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) -+nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_lockt *lockt = &u->lockt; - struct xdr_stream *xdr = resp->xdr; - - if (nfserr == nfserr_denied) -@@ -3798,8 +3875,10 @@ nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l - } - - static __be32 --nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) -+nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_locku *locku = &u->locku; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_encode_stateid(xdr, &locku->lu_stateid); -@@ -3807,8 +3886,10 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l - - - static __be32 --nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) -+nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_link *link = &u->link; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3821,8 +3902,10 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li - - - static __be32 --nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) -+nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_open *open = &u->open; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -3915,16 +3998,20 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op - } - - static __be32 --nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) -+nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_open_confirm *oc = &u->open_confirm; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); - } - - static __be32 --nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) -+nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_open_downgrade *od = &u->open_downgrade; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_encode_stateid(xdr, &od->od_stateid); -@@ -4023,8 +4110,9 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, - - static __be32 - nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_read *read) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_read *read = &u->read; - bool splice_ok = test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags); - unsigned long maxcount; - struct xdr_stream *xdr = resp->xdr; -@@ -4065,8 +4153,10 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, - } - - static __be32 --nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) -+nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_readlink *readlink = &u->readlink; - __be32 *p, *maxcount_p, zero = xdr_zero; - struct xdr_stream *xdr = resp->xdr; - int length_offset = xdr->buf->len; -@@ -4110,8 +4200,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd - } - - static __be32 --nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) -+nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_readdir *readdir = &u->readdir; - int maxcount; - int bytes_left; - loff_t offset; -@@ -4201,8 +4293,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 - } - - static __be32 --nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) -+nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_remove *remove = &u->remove; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4214,8 +4308,10 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ - } - - static __be32 --nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) -+nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_rename *rename = &u->rename; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4297,8 +4393,9 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp) - - static __be32 - nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_secinfo *secinfo) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_secinfo *secinfo = &u->secinfo; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp); -@@ -4306,8 +4403,9 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_secinfo_no_name *secinfo) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_secinfo_no_name *secinfo = &u->secinfo_no_name; - struct xdr_stream *xdr = resp->xdr; - - return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp); -@@ -4318,8 +4416,10 @@ nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, - * regardless of the error status. - */ - static __be32 --nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) -+nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_setattr *setattr = &u->setattr; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4342,8 +4442,10 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 - } - - static __be32 --nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) -+nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_setclientid *scd = &u->setclientid; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4366,8 +4468,10 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n - } - - static __be32 --nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) -+nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *u) - { -+ struct nfsd4_write *write = &u->write; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4383,8 +4487,9 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w - - static __be32 - nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_exchange_id *exid) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_exchange_id *exid = &u->exchange_id; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - char *major_id; -@@ -4461,8 +4566,9 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_create_session *sess) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_create_session *sess = &u->create_session; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4514,8 +4620,9 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_sequence *seq) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_sequence *seq = &u->sequence; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4537,8 +4644,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_test_stateid *test_stateid) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_test_stateid *test_stateid = &u->test_stateid; - struct xdr_stream *xdr = resp->xdr; - struct nfsd4_test_stateid_id *stateid, *next; - __be32 *p; -@@ -4558,8 +4666,9 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, - #ifdef CONFIG_NFSD_PNFS - static __be32 - nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_getdeviceinfo *gdev) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_getdeviceinfo *gdev = &u->getdeviceinfo; - struct xdr_stream *xdr = resp->xdr; - const struct nfsd4_layout_ops *ops; - u32 starting_len = xdr->buf->len, needed_len; -@@ -4611,8 +4720,9 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_layoutget *lgp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutget *lgp = &u->layoutget; - struct xdr_stream *xdr = resp->xdr; - const struct nfsd4_layout_ops *ops; - __be32 *p; -@@ -4638,8 +4748,9 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_layoutcommit *lcp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutcommit *lcp = &u->layoutcommit; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4659,8 +4770,9 @@ nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_layoutreturn *lrp) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_layoutreturn *lrp = &u->layoutreturn; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4745,8 +4857,9 @@ nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns) - - static __be32 - nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_copy *copy) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_copy *copy = &u->copy; - __be32 *p; - - nfserr = nfsd42_encode_write_res(resp, ©->cp_res, -@@ -4762,8 +4875,9 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_offload_status *os) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_offload_status *os = &u->offload_status; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4777,156 +4891,83 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, -- struct nfsd4_read *read, -- unsigned long *maxcount, u32 *eof, -- loff_t *pos) -+ struct nfsd4_read *read) - { -- struct xdr_stream *xdr = resp->xdr; -+ bool splice_ok = test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags); - struct file *file = read->rd_nf->nf_file; -- int starting_len = xdr->buf->len; -- loff_t hole_pos; -- __be32 nfserr; -- __be32 *p, tmp; -- __be64 tmp64; -- -- hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE); -- if (hole_pos > read->rd_offset) -- *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset); -- *maxcount = min_t(unsigned long, *maxcount, (xdr->buf->buflen - xdr->buf->len)); -+ struct xdr_stream *xdr = resp->xdr; -+ unsigned long maxcount; -+ __be32 nfserr, *p; - - /* Content type, offset, byte count */ - p = xdr_reserve_space(xdr, 4 + 8 + 4); - if (!p) -- return nfserr_resource; -+ return nfserr_io; -+ if (resp->xdr->buf->page_len && splice_ok) { -+ WARN_ON_ONCE(splice_ok); -+ return nfserr_serverfault; -+ } - -- read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount); -- if (read->rd_vlen < 0) -- return nfserr_resource; -+ maxcount = min_t(unsigned long, read->rd_length, -+ (xdr->buf->buflen - xdr->buf->len)); - -- nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, -- resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof); -+ if (file->f_op->splice_read && splice_ok) -+ nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount); -+ else -+ nfserr = nfsd4_encode_readv(resp, read, file, maxcount); - if (nfserr) - return nfserr; -- xdr_truncate_encode(xdr, starting_len + 16 + xdr_align_size(*maxcount)); -- -- tmp = htonl(NFS4_CONTENT_DATA); -- write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); -- tmp64 = cpu_to_be64(read->rd_offset); -- write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8); -- tmp = htonl(*maxcount); -- write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4); -- -- tmp = xdr_zero; -- write_bytes_to_xdr_buf(xdr->buf, starting_len + 16 + *maxcount, &tmp, -- xdr_pad_size(*maxcount)); -- return nfs_ok; --} -- --static __be32 --nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, -- struct nfsd4_read *read, -- unsigned long *maxcount, u32 *eof) --{ -- struct file *file = read->rd_nf->nf_file; -- loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); -- loff_t f_size = i_size_read(file_inode(file)); -- unsigned long count; -- __be32 *p; -- -- if (data_pos == -ENXIO) -- data_pos = f_size; -- else if (data_pos <= read->rd_offset || (data_pos < f_size && data_pos % PAGE_SIZE)) -- return nfsd4_encode_read_plus_data(resp, read, maxcount, eof, &f_size); -- count = data_pos - read->rd_offset; - -- /* Content type, offset, byte count */ -- p = xdr_reserve_space(resp->xdr, 4 + 8 + 8); -- if (!p) -- return nfserr_resource; -- -- *p++ = htonl(NFS4_CONTENT_HOLE); -+ *p++ = cpu_to_be32(NFS4_CONTENT_DATA); - p = xdr_encode_hyper(p, read->rd_offset); -- p = xdr_encode_hyper(p, count); -+ *p = cpu_to_be32(read->rd_length); - -- *eof = (read->rd_offset + count) >= f_size; -- *maxcount = min_t(unsigned long, count, *maxcount); - return nfs_ok; - } - - static __be32 - nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_read *read) -+ union nfsd4_op_u *u) - { -- unsigned long maxcount, count; -+ struct nfsd4_read *read = &u->read; -+ struct file *file = read->rd_nf->nf_file; - struct xdr_stream *xdr = resp->xdr; -- struct file *file; - int starting_len = xdr->buf->len; -- int last_segment = xdr->buf->len; -- int segments = 0; -- __be32 *p, tmp; -- bool is_data; -- loff_t pos; -- u32 eof; -+ u32 segments = 0; -+ __be32 *p; - - if (nfserr) - return nfserr; -- file = read->rd_nf->nf_file; - - /* eof flag, segment count */ - p = xdr_reserve_space(xdr, 4 + 4); - if (!p) -- return nfserr_resource; -+ return nfserr_io; - xdr_commit_encode(xdr); - -- maxcount = min_t(unsigned long, read->rd_length, -- (xdr->buf->buflen - xdr->buf->len)); -- count = maxcount; -- -- eof = read->rd_offset >= i_size_read(file_inode(file)); -- if (eof) -+ read->rd_eof = read->rd_offset >= i_size_read(file_inode(file)); -+ if (read->rd_eof) - goto out; - -- pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE); -- is_data = pos > read->rd_offset; -- -- while (count > 0 && !eof) { -- maxcount = count; -- if (is_data) -- nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof, -- segments == 0 ? &pos : NULL); -- else -- nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof); -- if (nfserr) -- goto out; -- count -= maxcount; -- read->rd_offset += maxcount; -- is_data = !is_data; -- last_segment = xdr->buf->len; -- segments++; -- } -- --out: -- if (nfserr && segments == 0) -+ nfserr = nfsd4_encode_read_plus_data(resp, read); -+ if (nfserr) { - xdr_truncate_encode(xdr, starting_len); -- else { -- if (nfserr) { -- xdr_truncate_encode(xdr, last_segment); -- nfserr = nfs_ok; -- eof = 0; -- } -- tmp = htonl(eof); -- write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); -- tmp = htonl(segments); -- write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4); -+ return nfserr; - } - -+ segments++; -+ -+out: -+ p = xdr_encode_bool(p, read->rd_eof); -+ *p = cpu_to_be32(segments); - return nfserr; - } - - static __be32 - nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_copy_notify *cn) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_copy_notify *cn = &u->copy_notify; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -4960,8 +5001,9 @@ nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_seek *seek) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_seek *seek = &u->seek; - __be32 *p; - - p = xdr_reserve_space(resp->xdr, 4 + 8); -@@ -4972,7 +5014,8 @@ nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, - } - - static __be32 --nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) -+nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, -+ union nfsd4_op_u *p) - { - return nfserr; - } -@@ -5023,8 +5066,9 @@ nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen) - - static __be32 - nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_getxattr *getxattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_getxattr *getxattr = &u->getxattr; - struct xdr_stream *xdr = resp->xdr; - __be32 *p, err; - -@@ -5047,8 +5091,9 @@ nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_setxattr *setxattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_setxattr *setxattr = &u->setxattr; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -5088,8 +5133,9 @@ nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs, - - static __be32 - nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_listxattrs *listxattrs) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_listxattrs *listxattrs = &u->listxattrs; - struct xdr_stream *xdr = resp->xdr; - u32 cookie_offset, count_offset, eof; - u32 left, xdrleft, slen, count; -@@ -5199,8 +5245,9 @@ nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr, - - static __be32 - nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr, -- struct nfsd4_removexattr *removexattr) -+ union nfsd4_op_u *u) - { -+ struct nfsd4_removexattr *removexattr = &u->removexattr; - struct xdr_stream *xdr = resp->xdr; - __be32 *p; - -@@ -5212,7 +5259,7 @@ nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr, - return 0; - } - --typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); -+typedef __be32(*nfsd4_enc)(struct nfsd4_compoundres *, __be32, union nfsd4_op_u *u); - - /* - * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1 -@@ -5220,93 +5267,93 @@ typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); - * done in the decoding phase. - */ - static const nfsd4_enc nfsd4_enc_ops[] = { -- [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, -- [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, -- [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, -- [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create, -- [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr, -- [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh, -- [OP_LINK] = (nfsd4_enc)nfsd4_encode_link, -- [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock, -- [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt, -- [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku, -- [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, -- [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, -- [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, -- [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_READ] = (nfsd4_enc)nfsd4_encode_read, -- [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir, -- [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink, -- [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove, -- [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename, -- [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo, -- [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr, -- [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid, -- [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write, -- [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop, -+ [OP_ACCESS] = nfsd4_encode_access, -+ [OP_CLOSE] = nfsd4_encode_close, -+ [OP_COMMIT] = nfsd4_encode_commit, -+ [OP_CREATE] = nfsd4_encode_create, -+ [OP_DELEGPURGE] = nfsd4_encode_noop, -+ [OP_DELEGRETURN] = nfsd4_encode_noop, -+ [OP_GETATTR] = nfsd4_encode_getattr, -+ [OP_GETFH] = nfsd4_encode_getfh, -+ [OP_LINK] = nfsd4_encode_link, -+ [OP_LOCK] = nfsd4_encode_lock, -+ [OP_LOCKT] = nfsd4_encode_lockt, -+ [OP_LOCKU] = nfsd4_encode_locku, -+ [OP_LOOKUP] = nfsd4_encode_noop, -+ [OP_LOOKUPP] = nfsd4_encode_noop, -+ [OP_NVERIFY] = nfsd4_encode_noop, -+ [OP_OPEN] = nfsd4_encode_open, -+ [OP_OPENATTR] = nfsd4_encode_noop, -+ [OP_OPEN_CONFIRM] = nfsd4_encode_open_confirm, -+ [OP_OPEN_DOWNGRADE] = nfsd4_encode_open_downgrade, -+ [OP_PUTFH] = nfsd4_encode_noop, -+ [OP_PUTPUBFH] = nfsd4_encode_noop, -+ [OP_PUTROOTFH] = nfsd4_encode_noop, -+ [OP_READ] = nfsd4_encode_read, -+ [OP_READDIR] = nfsd4_encode_readdir, -+ [OP_READLINK] = nfsd4_encode_readlink, -+ [OP_REMOVE] = nfsd4_encode_remove, -+ [OP_RENAME] = nfsd4_encode_rename, -+ [OP_RENEW] = nfsd4_encode_noop, -+ [OP_RESTOREFH] = nfsd4_encode_noop, -+ [OP_SAVEFH] = nfsd4_encode_noop, -+ [OP_SECINFO] = nfsd4_encode_secinfo, -+ [OP_SETATTR] = nfsd4_encode_setattr, -+ [OP_SETCLIENTID] = nfsd4_encode_setclientid, -+ [OP_SETCLIENTID_CONFIRM] = nfsd4_encode_noop, -+ [OP_VERIFY] = nfsd4_encode_noop, -+ [OP_WRITE] = nfsd4_encode_write, -+ [OP_RELEASE_LOCKOWNER] = nfsd4_encode_noop, - - /* NFSv4.1 operations */ -- [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, -- [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, -- [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, -- [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, -+ [OP_BACKCHANNEL_CTL] = nfsd4_encode_noop, -+ [OP_BIND_CONN_TO_SESSION] = nfsd4_encode_bind_conn_to_session, -+ [OP_EXCHANGE_ID] = nfsd4_encode_exchange_id, -+ [OP_CREATE_SESSION] = nfsd4_encode_create_session, -+ [OP_DESTROY_SESSION] = nfsd4_encode_noop, -+ [OP_FREE_STATEID] = nfsd4_encode_noop, -+ [OP_GET_DIR_DELEGATION] = nfsd4_encode_noop, - #ifdef CONFIG_NFSD_PNFS -- [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_getdeviceinfo, -- [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_layoutcommit, -- [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_layoutget, -- [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_layoutreturn, -+ [OP_GETDEVICEINFO] = nfsd4_encode_getdeviceinfo, -+ [OP_GETDEVICELIST] = nfsd4_encode_noop, -+ [OP_LAYOUTCOMMIT] = nfsd4_encode_layoutcommit, -+ [OP_LAYOUTGET] = nfsd4_encode_layoutget, -+ [OP_LAYOUTRETURN] = nfsd4_encode_layoutreturn, - #else -- [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, -+ [OP_GETDEVICEINFO] = nfsd4_encode_noop, -+ [OP_GETDEVICELIST] = nfsd4_encode_noop, -+ [OP_LAYOUTCOMMIT] = nfsd4_encode_noop, -+ [OP_LAYOUTGET] = nfsd4_encode_noop, -+ [OP_LAYOUTRETURN] = nfsd4_encode_noop, - #endif -- [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, -- [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, -- [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid, -- [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop, -+ [OP_SECINFO_NO_NAME] = nfsd4_encode_secinfo_no_name, -+ [OP_SEQUENCE] = nfsd4_encode_sequence, -+ [OP_SET_SSV] = nfsd4_encode_noop, -+ [OP_TEST_STATEID] = nfsd4_encode_test_stateid, -+ [OP_WANT_DELEGATION] = nfsd4_encode_noop, -+ [OP_DESTROY_CLIENTID] = nfsd4_encode_noop, -+ [OP_RECLAIM_COMPLETE] = nfsd4_encode_noop, - - /* NFSv4.2 operations */ -- [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy, -- [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify, -- [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_LAYOUTSTATS] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_OFFLOAD_CANCEL] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_offload_status, -- [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_read_plus, -- [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek, -- [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop, -- [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop, -+ [OP_ALLOCATE] = nfsd4_encode_noop, -+ [OP_COPY] = nfsd4_encode_copy, -+ [OP_COPY_NOTIFY] = nfsd4_encode_copy_notify, -+ [OP_DEALLOCATE] = nfsd4_encode_noop, -+ [OP_IO_ADVISE] = nfsd4_encode_noop, -+ [OP_LAYOUTERROR] = nfsd4_encode_noop, -+ [OP_LAYOUTSTATS] = nfsd4_encode_noop, -+ [OP_OFFLOAD_CANCEL] = nfsd4_encode_noop, -+ [OP_OFFLOAD_STATUS] = nfsd4_encode_offload_status, -+ [OP_READ_PLUS] = nfsd4_encode_read_plus, -+ [OP_SEEK] = nfsd4_encode_seek, -+ [OP_WRITE_SAME] = nfsd4_encode_noop, -+ [OP_CLONE] = nfsd4_encode_noop, - - /* RFC 8276 extended atributes operations */ -- [OP_GETXATTR] = (nfsd4_enc)nfsd4_encode_getxattr, -- [OP_SETXATTR] = (nfsd4_enc)nfsd4_encode_setxattr, -- [OP_LISTXATTRS] = (nfsd4_enc)nfsd4_encode_listxattrs, -- [OP_REMOVEXATTR] = (nfsd4_enc)nfsd4_encode_removexattr, -+ [OP_GETXATTR] = nfsd4_encode_getxattr, -+ [OP_SETXATTR] = nfsd4_encode_setxattr, -+ [OP_LISTXATTRS] = nfsd4_encode_listxattrs, -+ [OP_REMOVEXATTR] = nfsd4_encode_removexattr, - }; - - /* -diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c -index 573de0d49e172..76a60e7a75097 100644 ---- a/fs/nfsd/nfsctl.c -+++ b/fs/nfsd/nfsctl.c -@@ -581,7 +581,9 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) - - cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; - switch(num) { -+#ifdef CONFIG_NFSD_V2 - case 2: -+#endif - case 3: - nfsd_vers(nn, num, cmd); - break; -@@ -601,7 +603,9 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) - } - break; - default: -- return -EINVAL; -+ /* Ignore requests to disable non-existent versions */ -+ if (cmd == NFSD_SET) -+ return -EINVAL; - } - vers += len + 1; - } while ((len = qword_get(&mesg, vers, size)) > 0); -@@ -1448,9 +1452,7 @@ static __net_init int nfsd_init_net(struct net *net) - goto out_idmap_error; - nn->nfsd_versions = NULL; - nn->nfsd4_minorversions = NULL; -- retval = nfsd4_init_leases_net(nn); -- if (retval) -- goto out_drc_error; -+ nfsd4_init_leases_net(nn); - retval = nfsd_reply_cache_init(nn); - if (retval) - goto out_cache_error; -@@ -1460,8 +1462,6 @@ static __net_init int nfsd_init_net(struct net *net) - return 0; - - out_cache_error: -- nfsd4_leases_net_shutdown(nn); --out_drc_error: - nfsd_idmap_shutdown(net); - out_idmap_error: - nfsd_export_shutdown(net); -@@ -1477,7 +1477,6 @@ static __net_exit void nfsd_exit_net(struct net *net) - nfsd_idmap_shutdown(net); - nfsd_export_shutdown(net); - nfsd_netns_free_versions(net_generic(net, nfsd_net_id)); -- nfsd4_leases_net_shutdown(nn); - } - - static struct pernet_operations nfsd_net_ops = { -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 09726c5b9a317..fa0144a742678 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -64,8 +64,7 @@ struct readdir_cd { - - - extern struct svc_program nfsd_program; --extern const struct svc_version nfsd_version2, nfsd_version3, -- nfsd_version4; -+extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; - extern struct mutex nfsd_mutex; - extern spinlock_t nfsd_drc_lock; - extern unsigned long nfsd_drc_max_mem; -@@ -505,8 +504,7 @@ extern void unregister_cld_notifier(void); - extern void nfsd4_ssc_init_umount_work(struct nfsd_net *nn); - #endif - --extern int nfsd4_init_leases_net(struct nfsd_net *nn); --extern void nfsd4_leases_net_shutdown(struct nfsd_net *nn); -+extern void nfsd4_init_leases_net(struct nfsd_net *nn); - - #else /* CONFIG_NFSD_V4 */ - static inline int nfsd4_is_junction(struct dentry *dentry) -@@ -514,8 +512,7 @@ static inline int nfsd4_is_junction(struct dentry *dentry) - return 0; - } - --static inline int nfsd4_init_leases_net(struct nfsd_net *nn) { return 0; }; --static inline void nfsd4_leases_net_shutdown(struct nfsd_net *nn) {}; -+static inline void nfsd4_init_leases_net(struct nfsd_net *nn) { }; - - #define register_cld_notifier() 0 - #define unregister_cld_notifier() do { } while(0) -diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h -index c3ae6414fc5cf..513e028b0bbee 100644 ---- a/fs/nfsd/nfsfh.h -+++ b/fs/nfsd/nfsfh.h -@@ -220,7 +220,7 @@ __be32 fh_update(struct svc_fh *); - void fh_put(struct svc_fh *); - - static __inline__ struct svc_fh * --fh_copy(struct svc_fh *dst, struct svc_fh *src) -+fh_copy(struct svc_fh *dst, const struct svc_fh *src) - { - WARN_ON(src->fh_dentry); - -@@ -229,7 +229,7 @@ fh_copy(struct svc_fh *dst, struct svc_fh *src) - } - - static inline void --fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src) -+fh_copy_shallow(struct knfsd_fh *dst, const struct knfsd_fh *src) - { - dst->fh_size = src->fh_size; - memcpy(&dst->fh_raw, &src->fh_raw, src->fh_size); -@@ -243,7 +243,8 @@ fh_init(struct svc_fh *fhp, int maxsize) - return fhp; - } - --static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) -+static inline bool fh_match(const struct knfsd_fh *fh1, -+ const struct knfsd_fh *fh2) - { - if (fh1->fh_size != fh2->fh_size) - return false; -@@ -252,7 +253,8 @@ static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) - return true; - } - --static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) -+static inline bool fh_fsid_match(const struct knfsd_fh *fh1, -+ const struct knfsd_fh *fh2) - { - if (fh1->fh_fsid_type != fh2->fh_fsid_type) - return false; -diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c -index 82b3ddeacc338..9744443c39652 100644 ---- a/fs/nfsd/nfsproc.c -+++ b/fs/nfsd/nfsproc.c -@@ -211,7 +211,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) - if (resp->status == nfs_ok) - resp->status = fh_getattr(&resp->fh, &resp->stat); - else if (resp->status == nfserr_jukebox) -- return rpc_drop_reply; -+ set_bit(RQ_DROPME, &rqstp->rq_flags); - return rpc_success; - } - -@@ -246,7 +246,7 @@ nfsd_proc_write(struct svc_rqst *rqstp) - if (resp->status == nfs_ok) - resp->status = fh_getattr(&resp->fh, &resp->stat); - else if (resp->status == nfserr_jukebox) -- return rpc_drop_reply; -+ set_bit(RQ_DROPME, &rqstp->rq_flags); - return rpc_success; - } - -@@ -848,65 +848,3 @@ const struct svc_version nfsd_version2 = { - .vs_dispatch = nfsd_dispatch, - .vs_xdrsize = NFS2_SVC_XDRSIZE, - }; -- --/* -- * Map errnos to NFS errnos. -- */ --__be32 --nfserrno (int errno) --{ -- static struct { -- __be32 nfserr; -- int syserr; -- } nfs_errtbl[] = { -- { nfs_ok, 0 }, -- { nfserr_perm, -EPERM }, -- { nfserr_noent, -ENOENT }, -- { nfserr_io, -EIO }, -- { nfserr_nxio, -ENXIO }, -- { nfserr_fbig, -E2BIG }, -- { nfserr_stale, -EBADF }, -- { nfserr_acces, -EACCES }, -- { nfserr_exist, -EEXIST }, -- { nfserr_xdev, -EXDEV }, -- { nfserr_mlink, -EMLINK }, -- { nfserr_nodev, -ENODEV }, -- { nfserr_notdir, -ENOTDIR }, -- { nfserr_isdir, -EISDIR }, -- { nfserr_inval, -EINVAL }, -- { nfserr_fbig, -EFBIG }, -- { nfserr_nospc, -ENOSPC }, -- { nfserr_rofs, -EROFS }, -- { nfserr_mlink, -EMLINK }, -- { nfserr_nametoolong, -ENAMETOOLONG }, -- { nfserr_notempty, -ENOTEMPTY }, --#ifdef EDQUOT -- { nfserr_dquot, -EDQUOT }, --#endif -- { nfserr_stale, -ESTALE }, -- { nfserr_jukebox, -ETIMEDOUT }, -- { nfserr_jukebox, -ERESTARTSYS }, -- { nfserr_jukebox, -EAGAIN }, -- { nfserr_jukebox, -EWOULDBLOCK }, -- { nfserr_jukebox, -ENOMEM }, -- { nfserr_io, -ETXTBSY }, -- { nfserr_notsupp, -EOPNOTSUPP }, -- { nfserr_toosmall, -ETOOSMALL }, -- { nfserr_serverfault, -ESERVERFAULT }, -- { nfserr_serverfault, -ENFILE }, -- { nfserr_io, -EREMOTEIO }, -- { nfserr_stale, -EOPENSTALE }, -- { nfserr_io, -EUCLEAN }, -- { nfserr_perm, -ENOKEY }, -- { nfserr_no_grace, -ENOGRACE}, -- }; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { -- if (nfs_errtbl[i].syserr == errno) -- return nfs_errtbl[i].nfserr; -- } -- WARN_ONCE(1, "nfsd: non-standard errno: %d\n", errno); -- return nfserr_io; --} -- -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index c7695ebd28dc3..0c75636054a54 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -91,8 +91,12 @@ unsigned long nfsd_drc_mem_used; - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) - static struct svc_stat nfsd_acl_svcstats; - static const struct svc_version *nfsd_acl_version[] = { -+# if defined(CONFIG_NFSD_V2_ACL) - [2] = &nfsd_acl_version2, -+# endif -+# if defined(CONFIG_NFSD_V3_ACL) - [3] = &nfsd_acl_version3, -+# endif - }; - - #define NFSD_ACL_MINVERS 2 -@@ -116,7 +120,9 @@ static struct svc_stat nfsd_acl_svcstats = { - #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ - - static const struct svc_version *nfsd_version[] = { -+#if defined(CONFIG_NFSD_V2) - [2] = &nfsd_version2, -+#endif - [3] = &nfsd_version3, - #if defined(CONFIG_NFSD_V4) - [4] = &nfsd_version4, -@@ -1065,7 +1071,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - - nfs_reply = xdr_inline_decode(&rqstp->rq_res_stream, 0); - *statp = proc->pc_func(rqstp); -- if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags)) -+ if (test_bit(RQ_DROPME, &rqstp->rq_flags)) - goto out_update_drop; - - if (!proc->pc_encode(rqstp, &rqstp->rq_res_stream)) -diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h -index e2daef3cc0034..e94634d305912 100644 ---- a/fs/nfsd/state.h -+++ b/fs/nfsd/state.h -@@ -368,6 +368,7 @@ struct nfs4_client { - #define NFSD4_CLIENT_UPCALL_LOCK (5) /* upcall serialization */ - #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ - 1 << NFSD4_CLIENT_CB_KILL) -+#define NFSD4_CLIENT_CB_RECALL_ANY (6) - unsigned long cl_flags; - const struct cred *cl_cb_cred; - struct rpc_clnt *cl_cb_client; -@@ -411,6 +412,10 @@ struct nfs4_client { - - unsigned int cl_state; - atomic_t cl_delegs_in_recall; -+ -+ struct nfsd4_cb_recall_any *cl_ra; -+ time64_t cl_ra_time; -+ struct list_head cl_ra_cblist; - }; - - /* struct nfs4_client_reset -@@ -536,16 +541,13 @@ struct nfs4_clnt_odstate { - * inode can have multiple filehandles associated with it, so there is - * (potentially) a many to one relationship between this struct and struct - * inode. -- * -- * These are hashed by filehandle in the file_hashtbl, which is protected by -- * the global state_lock spinlock. - */ - struct nfs4_file { - refcount_t fi_ref; - struct inode * fi_inode; - bool fi_aliased; - spinlock_t fi_lock; -- struct hlist_node fi_hash; /* hash on fi_fhandle */ -+ struct rhlist_head fi_rlist; - struct list_head fi_stateids; - union { - struct list_head fi_delegations; -@@ -639,6 +641,7 @@ enum nfsd4_cb_op { - NFSPROC4_CLNT_CB_OFFLOAD, - NFSPROC4_CLNT_CB_SEQUENCE, - NFSPROC4_CLNT_CB_NOTIFY_LOCK, -+ NFSPROC4_CLNT_CB_RECALL_ANY, - }; - - /* Returns true iff a is later than b: */ -diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h -index 132335011ccae..4183819ea0829 100644 ---- a/fs/nfsd/trace.h -+++ b/fs/nfsd/trace.h -@@ -9,9 +9,12 @@ - #define _NFSD_TRACE_H - - #include -+#include -+#include - - #include "export.h" - #include "nfsfh.h" -+#include "xdr4.h" - - #define NFSD_TRACE_PROC_RES_FIELDS \ - __field(unsigned int, netns_ino) \ -@@ -604,6 +607,7 @@ DEFINE_STATEID_EVENT(layout_recall_release); - - DEFINE_STATEID_EVENT(open); - DEFINE_STATEID_EVENT(deleg_read); -+DEFINE_STATEID_EVENT(deleg_return); - DEFINE_STATEID_EVENT(deleg_recall); - - DECLARE_EVENT_CLASS(nfsd_stateseqid_class, -@@ -636,6 +640,61 @@ DEFINE_EVENT(nfsd_stateseqid_class, nfsd_##name, \ - DEFINE_STATESEQID_EVENT(preprocess); - DEFINE_STATESEQID_EVENT(open_confirm); - -+TRACE_DEFINE_ENUM(NFS4_OPEN_STID); -+TRACE_DEFINE_ENUM(NFS4_LOCK_STID); -+TRACE_DEFINE_ENUM(NFS4_DELEG_STID); -+TRACE_DEFINE_ENUM(NFS4_CLOSED_STID); -+TRACE_DEFINE_ENUM(NFS4_REVOKED_DELEG_STID); -+TRACE_DEFINE_ENUM(NFS4_CLOSED_DELEG_STID); -+TRACE_DEFINE_ENUM(NFS4_LAYOUT_STID); -+ -+#define show_stid_type(x) \ -+ __print_flags(x, "|", \ -+ { NFS4_OPEN_STID, "OPEN" }, \ -+ { NFS4_LOCK_STID, "LOCK" }, \ -+ { NFS4_DELEG_STID, "DELEG" }, \ -+ { NFS4_CLOSED_STID, "CLOSED" }, \ -+ { NFS4_REVOKED_DELEG_STID, "REVOKED" }, \ -+ { NFS4_CLOSED_DELEG_STID, "CLOSED_DELEG" }, \ -+ { NFS4_LAYOUT_STID, "LAYOUT" }) -+ -+DECLARE_EVENT_CLASS(nfsd_stid_class, -+ TP_PROTO( -+ const struct nfs4_stid *stid -+ ), -+ TP_ARGS(stid), -+ TP_STRUCT__entry( -+ __field(unsigned long, sc_type) -+ __field(int, sc_count) -+ __field(u32, cl_boot) -+ __field(u32, cl_id) -+ __field(u32, si_id) -+ __field(u32, si_generation) -+ ), -+ TP_fast_assign( -+ const stateid_t *stp = &stid->sc_stateid; -+ -+ __entry->sc_type = stid->sc_type; -+ __entry->sc_count = refcount_read(&stid->sc_count); -+ __entry->cl_boot = stp->si_opaque.so_clid.cl_boot; -+ __entry->cl_id = stp->si_opaque.so_clid.cl_id; -+ __entry->si_id = stp->si_opaque.so_id; -+ __entry->si_generation = stp->si_generation; -+ ), -+ TP_printk("client %08x:%08x stateid %08x:%08x ref=%d type=%s", -+ __entry->cl_boot, __entry->cl_id, -+ __entry->si_id, __entry->si_generation, -+ __entry->sc_count, show_stid_type(__entry->sc_type) -+ ) -+); -+ -+#define DEFINE_STID_EVENT(name) \ -+DEFINE_EVENT(nfsd_stid_class, nfsd_stid_##name, \ -+ TP_PROTO(const struct nfs4_stid *stid), \ -+ TP_ARGS(stid)) -+ -+DEFINE_STID_EVENT(revoke); -+ - DECLARE_EVENT_CLASS(nfsd_clientid_class, - TP_PROTO(const clientid_t *clid), - TP_ARGS(clid), -@@ -1436,6 +1495,32 @@ TRACE_EVENT(nfsd_cb_offload, - __entry->fh_hash, __entry->count, __entry->status) - ); - -+TRACE_EVENT(nfsd_cb_recall_any, -+ TP_PROTO( -+ const struct nfsd4_cb_recall_any *ra -+ ), -+ TP_ARGS(ra), -+ TP_STRUCT__entry( -+ __field(u32, cl_boot) -+ __field(u32, cl_id) -+ __field(u32, keep) -+ __field(unsigned long, bmval0) -+ __sockaddr(addr, ra->ra_cb.cb_clp->cl_cb_conn.cb_addrlen) -+ ), -+ TP_fast_assign( -+ __entry->cl_boot = ra->ra_cb.cb_clp->cl_clientid.cl_boot; -+ __entry->cl_id = ra->ra_cb.cb_clp->cl_clientid.cl_id; -+ __entry->keep = ra->ra_keep; -+ __entry->bmval0 = ra->ra_bmval[0]; -+ __assign_sockaddr(addr, &ra->ra_cb.cb_clp->cl_addr, -+ ra->ra_cb.cb_clp->cl_cb_conn.cb_addrlen); -+ ), -+ TP_printk("addr=%pISpc client %08x:%08x keep=%u bmval0=%s", -+ __get_sockaddr(addr), __entry->cl_boot, __entry->cl_id, -+ __entry->keep, show_rca_mask(__entry->bmval0) -+ ) -+); -+ - DECLARE_EVENT_CLASS(nfsd_cb_done_class, - TP_PROTO( - const stateid_t *stp, -@@ -1475,6 +1560,27 @@ DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_notify_lock_done); - DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_layout_done); - DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_offload_done); - -+TRACE_EVENT(nfsd_cb_recall_any_done, -+ TP_PROTO( -+ const struct nfsd4_callback *cb, -+ const struct rpc_task *task -+ ), -+ TP_ARGS(cb, task), -+ TP_STRUCT__entry( -+ __field(u32, cl_boot) -+ __field(u32, cl_id) -+ __field(int, status) -+ ), -+ TP_fast_assign( -+ __entry->status = task->tk_status; -+ __entry->cl_boot = cb->cb_clp->cl_clientid.cl_boot; -+ __entry->cl_id = cb->cb_clp->cl_clientid.cl_id; -+ ), -+ TP_printk("client %08x:%08x status=%d", -+ __entry->cl_boot, __entry->cl_id, __entry->status -+ ) -+); -+ - #endif /* _NFSD_TRACE_H */ - - #undef TRACE_INCLUDE_PATH -diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c -index eccc6ce55a63a..5d6a61d47a905 100644 ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -49,6 +49,69 @@ - - #define NFSDDBG_FACILITY NFSDDBG_FILEOP - -+/** -+ * nfserrno - Map Linux errnos to NFS errnos -+ * @errno: POSIX(-ish) error code to be mapped -+ * -+ * Returns the appropriate (net-endian) nfserr_* (or nfs_ok if errno is 0). If -+ * it's an error we don't expect, log it once and return nfserr_io. -+ */ -+__be32 -+nfserrno (int errno) -+{ -+ static struct { -+ __be32 nfserr; -+ int syserr; -+ } nfs_errtbl[] = { -+ { nfs_ok, 0 }, -+ { nfserr_perm, -EPERM }, -+ { nfserr_noent, -ENOENT }, -+ { nfserr_io, -EIO }, -+ { nfserr_nxio, -ENXIO }, -+ { nfserr_fbig, -E2BIG }, -+ { nfserr_stale, -EBADF }, -+ { nfserr_acces, -EACCES }, -+ { nfserr_exist, -EEXIST }, -+ { nfserr_xdev, -EXDEV }, -+ { nfserr_mlink, -EMLINK }, -+ { nfserr_nodev, -ENODEV }, -+ { nfserr_notdir, -ENOTDIR }, -+ { nfserr_isdir, -EISDIR }, -+ { nfserr_inval, -EINVAL }, -+ { nfserr_fbig, -EFBIG }, -+ { nfserr_nospc, -ENOSPC }, -+ { nfserr_rofs, -EROFS }, -+ { nfserr_mlink, -EMLINK }, -+ { nfserr_nametoolong, -ENAMETOOLONG }, -+ { nfserr_notempty, -ENOTEMPTY }, -+ { nfserr_dquot, -EDQUOT }, -+ { nfserr_stale, -ESTALE }, -+ { nfserr_jukebox, -ETIMEDOUT }, -+ { nfserr_jukebox, -ERESTARTSYS }, -+ { nfserr_jukebox, -EAGAIN }, -+ { nfserr_jukebox, -EWOULDBLOCK }, -+ { nfserr_jukebox, -ENOMEM }, -+ { nfserr_io, -ETXTBSY }, -+ { nfserr_notsupp, -EOPNOTSUPP }, -+ { nfserr_toosmall, -ETOOSMALL }, -+ { nfserr_serverfault, -ESERVERFAULT }, -+ { nfserr_serverfault, -ENFILE }, -+ { nfserr_io, -EREMOTEIO }, -+ { nfserr_stale, -EOPENSTALE }, -+ { nfserr_io, -EUCLEAN }, -+ { nfserr_perm, -ENOKEY }, -+ { nfserr_no_grace, -ENOGRACE}, -+ }; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { -+ if (nfs_errtbl[i].syserr == errno) -+ return nfs_errtbl[i].nfserr; -+ } -+ WARN_ONCE(1, "nfsd: non-standard errno: %d\n", errno); -+ return nfserr_io; -+} -+ - /* - * Called from nfsd_lookup and encode_dirent. Check if we have crossed - * a mount point. -@@ -1317,7 +1380,6 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, - iap->ia_mode &= ~current_umask(); - - err = 0; -- host_err = 0; - switch (type) { - case S_IFREG: - host_err = vfs_create(&init_user_ns, dirp, dchild, iap->ia_mode, true); -diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h -index 9744b041105b5..dbdfef7ae85bb 100644 ---- a/fs/nfsd/vfs.h -+++ b/fs/nfsd/vfs.h -@@ -60,6 +60,7 @@ static inline void nfsd_attrs_free(struct nfsd_attrs *attrs) - posix_acl_release(attrs->na_dpacl); - } - -+__be32 nfserrno (int errno); - int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, - struct svc_export **expp); - __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, -diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h -index 36c3340c1d54a..510978e602da6 100644 ---- a/fs/nfsd/xdr4.h -+++ b/fs/nfsd/xdr4.h -@@ -896,5 +896,10 @@ struct nfsd4_operation { - union nfsd4_op_u *); - }; - -+struct nfsd4_cb_recall_any { -+ struct nfsd4_callback ra_cb; -+ u32 ra_keep; -+ u32 ra_bmval[1]; -+}; - - #endif -diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h -index 547cf07cf4e08..0d39af1b00a0f 100644 ---- a/fs/nfsd/xdr4cb.h -+++ b/fs/nfsd/xdr4cb.h -@@ -48,3 +48,9 @@ - #define NFS4_dec_cb_offload_sz (cb_compound_dec_hdr_sz + \ - cb_sequence_dec_sz + \ - op_dec_sz) -+#define NFS4_enc_cb_recall_any_sz (cb_compound_enc_hdr_sz + \ -+ cb_sequence_enc_sz + \ -+ 1 + 1 + 1) -+#define NFS4_dec_cb_recall_any_sz (cb_compound_dec_hdr_sz + \ -+ cb_sequence_dec_sz + \ -+ op_dec_sz) -diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c -index bb7e33c240737..d260260900241 100644 ---- a/fs/ntfs3/frecord.c -+++ b/fs/ntfs3/frecord.c -@@ -102,7 +102,7 @@ void ni_clear(struct ntfs_inode *ni) - { - struct rb_node *node; - -- if (!ni->vfs_inode.i_nlink && is_rec_inuse(ni->mi.mrec)) -+ if (!ni->vfs_inode.i_nlink && ni->mi.mrec && is_rec_inuse(ni->mi.mrec)) - ni_delete_all(ni); - - al_destroy(ni); -@@ -3255,6 +3255,9 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint) - return 0; - } - -+ if (!ni->mi.mrec) -+ goto out; -+ - if (is_rec_inuse(ni->mi.mrec) && - !(sbi->flags & NTFS_FLAGS_LOG_REPLAYING) && inode->i_nlink) { - bool modified = false; -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index 1eac80d55b554..4c2d079b3d49b 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -1674,6 +1674,7 @@ struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST rno, bool dir) - - out: - if (err) { -+ make_bad_inode(inode); - iput(inode); - ni = ERR_PTR(err); - } -diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c -index 7371f7855e4c4..eee01db6e0cc5 100644 ---- a/fs/ntfs3/index.c -+++ b/fs/ntfs3/index.c -@@ -998,6 +998,7 @@ struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni, - struct ATTR_LIST_ENTRY *le = NULL; - struct ATTRIB *a; - const struct INDEX_NAMES *in = &s_index_names[indx->type]; -+ struct INDEX_ROOT *root = NULL; - - a = ni_find_attr(ni, NULL, &le, ATTR_ROOT, in->name, in->name_len, NULL, - mi); -@@ -1007,7 +1008,15 @@ struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni, - if (attr) - *attr = a; - -- return resident_data_ex(a, sizeof(struct INDEX_ROOT)); -+ root = resident_data_ex(a, sizeof(struct INDEX_ROOT)); -+ -+ /* length check */ -+ if (root && offsetof(struct INDEX_ROOT, ihdr) + le32_to_cpu(root->ihdr.used) > -+ le32_to_cpu(a->res.data_size)) { -+ return NULL; -+ } -+ -+ return root; - } - - static int indx_write(struct ntfs_index *indx, struct ntfs_inode *ni, -diff --git a/include/linux/bvec.h b/include/linux/bvec.h -index 9e3dac51eb26b..d4dbaae8b5218 100644 ---- a/include/linux/bvec.h -+++ b/include/linux/bvec.h -@@ -59,7 +59,7 @@ struct bvec_iter { - - unsigned int bi_bvec_done; /* number of bytes completed in - current bvec */ --} __packed; -+} __packed __aligned(4); - - struct bvec_iter_all { - struct bio_vec bv; -diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h -index 9192986b1a731..ac862422df158 100644 ---- a/include/linux/decompress/mm.h -+++ b/include/linux/decompress/mm.h -@@ -48,7 +48,7 @@ MALLOC_VISIBLE void *malloc(int size) - if (!malloc_ptr) - malloc_ptr = free_mem_ptr; - -- malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ -+ malloc_ptr = (malloc_ptr + 7) & ~7; /* Align */ - - p = (void *)malloc_ptr; - malloc_ptr += size; -diff --git a/include/linux/efi.h b/include/linux/efi.h -index 4e1bfee9675d2..de6d6558a4d30 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -390,6 +390,7 @@ void efi_native_runtime_setup(void); - #define EFI_RT_PROPERTIES_TABLE_GUID EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9) - #define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) - #define EFI_SMBIOS_PROTOCOL_GUID EFI_GUID(0x03583ff6, 0xcb36, 0x4940, 0x94, 0x7e, 0xb9, 0xb3, 0x9f, 0x4a, 0xfa, 0xf7) -+#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID EFI_GUID(0xf4560cf6, 0x40ec, 0x4b4a, 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89) - - #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) - #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 67313881f8ac1..092d8fa10153f 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1189,6 +1189,13 @@ extern void show_fd_locks(struct seq_file *f, - struct file *filp, struct files_struct *files); - extern bool locks_owner_has_blockers(struct file_lock_context *flctx, - fl_owner_t owner); -+ -+static inline struct file_lock_context * -+locks_inode_context(const struct inode *inode) -+{ -+ return smp_load_acquire(&inode->i_flctx); -+} -+ - #else /* !CONFIG_FILE_LOCKING */ - static inline int fcntl_getlk(struct file *file, unsigned int cmd, - struct flock __user *user) -@@ -1334,6 +1341,13 @@ static inline bool locks_owner_has_blockers(struct file_lock_context *flctx, - { - return false; - } -+ -+static inline struct file_lock_context * -+locks_inode_context(const struct inode *inode) -+{ -+ return NULL; -+} -+ - #endif /* !CONFIG_FILE_LOCKING */ - - static inline struct inode *file_inode(const struct file *f) -diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h -index bef8db9d6c085..e5f4b6f8d1c09 100644 ---- a/include/linux/netfilter.h -+++ b/include/linux/netfilter.h -@@ -437,11 +437,13 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) - #include - - void nf_ct_attach(struct sk_buff *, const struct sk_buff *); -+void nf_ct_set_closing(struct nf_conntrack *nfct); - struct nf_conntrack_tuple; - bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple, - const struct sk_buff *skb); - #else - static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} -+static inline void nf_ct_set_closing(struct nf_conntrack *nfct) {} - struct nf_conntrack_tuple; - static inline bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple, - const struct sk_buff *skb) -@@ -459,6 +461,8 @@ struct nf_ct_hook { - bool (*get_tuple_skb)(struct nf_conntrack_tuple *, - const struct sk_buff *); - void (*attach)(struct sk_buff *nskb, const struct sk_buff *skb); -+ void (*set_closing)(struct nf_conntrack *nfct); -+ int (*confirm)(struct sk_buff *skb); - }; - extern const struct nf_ct_hook __rcu *nf_ct_hook; - -diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h -index 8d04b6a5964c4..730003c4f4af4 100644 ---- a/include/linux/nfs4.h -+++ b/include/linux/nfs4.h -@@ -732,4 +732,17 @@ enum nfs4_setxattr_options { - SETXATTR4_CREATE = 1, - SETXATTR4_REPLACE = 2, - }; -+ -+enum { -+ RCA4_TYPE_MASK_RDATA_DLG = 0, -+ RCA4_TYPE_MASK_WDATA_DLG = 1, -+ RCA4_TYPE_MASK_DIR_DLG = 2, -+ RCA4_TYPE_MASK_FILE_LAYOUT = 3, -+ RCA4_TYPE_MASK_BLK_LAYOUT = 4, -+ RCA4_TYPE_MASK_OBJ_LAYOUT_MIN = 8, -+ RCA4_TYPE_MASK_OBJ_LAYOUT_MAX = 9, -+ RCA4_TYPE_MASK_OTHER_LAYOUT_MIN = 12, -+ RCA4_TYPE_MASK_OTHER_LAYOUT_MAX = 15, -+}; -+ - #endif -diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h -index 43ac3fa760dbe..9783b9107d76b 100644 ---- a/include/linux/usb/composite.h -+++ b/include/linux/usb/composite.h -@@ -412,6 +412,8 @@ extern int composite_dev_prepare(struct usb_composite_driver *composite, - extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, - struct usb_ep *ep0); - void composite_dev_cleanup(struct usb_composite_dev *cdev); -+void check_remote_wakeup_config(struct usb_gadget *g, -+ struct usb_configuration *c); - - static inline struct usb_composite_driver *to_cdriver( - struct usb_gadget_driver *gdrv) -diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h -index dc3092cea99e9..5bec668b41dcd 100644 ---- a/include/linux/usb/gadget.h -+++ b/include/linux/usb/gadget.h -@@ -309,6 +309,7 @@ struct usb_udc; - struct usb_gadget_ops { - int (*get_frame)(struct usb_gadget *); - int (*wakeup)(struct usb_gadget *); -+ int (*set_remote_wakeup)(struct usb_gadget *, int set); - int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); - int (*vbus_session) (struct usb_gadget *, int is_active); - int (*vbus_draw) (struct usb_gadget *, unsigned mA); -@@ -383,6 +384,8 @@ struct usb_gadget_ops { - * @connected: True if gadget is connected. - * @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag - * indicates that it supports LPM as per the LPM ECN & errata. -+ * @wakeup_capable: True if gadget is capable of sending remote wakeup. -+ * @wakeup_armed: True if gadget is armed by the host for remote wakeup. - * @irq: the interrupt number for device controller. - * @id_number: a unique ID number for ensuring that gadget names are distinct - * -@@ -444,6 +447,8 @@ struct usb_gadget { - unsigned deactivated:1; - unsigned connected:1; - unsigned lpm_capable:1; -+ unsigned wakeup_capable:1; -+ unsigned wakeup_armed:1; - int irq; - int id_number; - }; -@@ -600,6 +605,7 @@ static inline int gadget_is_otg(struct usb_gadget *g) - #if IS_ENABLED(CONFIG_USB_GADGET) - int usb_gadget_frame_number(struct usb_gadget *gadget); - int usb_gadget_wakeup(struct usb_gadget *gadget); -+int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set); - int usb_gadget_set_selfpowered(struct usb_gadget *gadget); - int usb_gadget_clear_selfpowered(struct usb_gadget *gadget); - int usb_gadget_vbus_connect(struct usb_gadget *gadget); -@@ -615,6 +621,8 @@ static inline int usb_gadget_frame_number(struct usb_gadget *gadget) - { return 0; } - static inline int usb_gadget_wakeup(struct usb_gadget *gadget) - { return 0; } -+static inline int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set) -+{ return 0; } - static inline int usb_gadget_set_selfpowered(struct usb_gadget *gadget) - { return 0; } - static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget) -diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h -index c48186bf47372..21da31e1dff5d 100644 ---- a/include/net/ipv6_stubs.h -+++ b/include/net/ipv6_stubs.h -@@ -85,6 +85,11 @@ struct ipv6_bpf_stub { - sockptr_t optval, unsigned int optlen); - int (*ipv6_getsockopt)(struct sock *sk, int level, int optname, - sockptr_t optval, sockptr_t optlen); -+ int (*ipv6_dev_get_saddr)(struct net *net, -+ const struct net_device *dst_dev, -+ const struct in6_addr *daddr, -+ unsigned int prefs, -+ struct in6_addr *saddr); - }; - extern const struct ipv6_bpf_stub *ipv6_bpf_stub __read_mostly; - -diff --git a/include/net/mctp.h b/include/net/mctp.h -index 82800d521c3de..7ed84054f4623 100644 ---- a/include/net/mctp.h -+++ b/include/net/mctp.h -@@ -249,6 +249,7 @@ struct mctp_route { - struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, - mctp_eid_t daddr); - -+/* always takes ownership of skb */ - int mctp_local_output(struct sock *sk, struct mctp_route *rt, - struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag); - -diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h -index 6a2019aaa4644..3dbf947285be2 100644 ---- a/include/net/netfilter/nf_conntrack.h -+++ b/include/net/netfilter/nf_conntrack.h -@@ -125,6 +125,12 @@ struct nf_conn { - union nf_conntrack_proto proto; - }; - -+static inline struct nf_conn * -+nf_ct_to_nf_conn(const struct nf_conntrack *nfct) -+{ -+ return container_of(nfct, struct nf_conn, ct_general); -+} -+ - static inline struct nf_conn * - nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) - { -@@ -175,6 +181,8 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) - - void nf_ct_destroy(struct nf_conntrack *nfct); - -+void nf_conntrack_tcp_set_closing(struct nf_conn *ct); -+ - /* decrement reference count on a conntrack */ - static inline void nf_ct_put(struct nf_conn *ct) - { -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index d2751ed536df2..a64713fe52640 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -204,6 +204,7 @@ struct scsi_device { - unsigned use_10_for_rw:1; /* first try 10-byte read / write */ - unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ - unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ -+ unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ - unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ - unsigned no_write_same:1; /* no WRITE SAME command */ - unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ -@@ -479,28 +480,51 @@ extern const char *scsi_device_state_name(enum scsi_device_state); - extern int scsi_is_sdev_device(const struct device *); - extern int scsi_is_target_device(const struct device *); - extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); --extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, -- int data_direction, void *buffer, unsigned bufflen, -- unsigned char *sense, struct scsi_sense_hdr *sshdr, -- int timeout, int retries, blk_opf_t flags, -- req_flags_t rq_flags, int *resid); -+ -+/* Optional arguments to scsi_execute_cmd */ -+struct scsi_exec_args { -+ unsigned char *sense; /* sense buffer */ -+ unsigned int sense_len; /* sense buffer len */ -+ struct scsi_sense_hdr *sshdr; /* decoded sense header */ -+ blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */ -+ int *resid; /* residual length */ -+}; -+ -+int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, -+ blk_opf_t opf, void *buffer, unsigned int bufflen, -+ int timeout, int retries, -+ const struct scsi_exec_args *args); -+ - /* Make sure any sense buffer is the correct size. */ --#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ -- sshdr, timeout, retries, flags, rq_flags, resid) \ -+#define scsi_execute(_sdev, _cmd, _data_dir, _buffer, _bufflen, _sense, \ -+ _sshdr, _timeout, _retries, _flags, _rq_flags, \ -+ _resid) \ - ({ \ -- BUILD_BUG_ON((sense) != NULL && \ -- sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \ -- __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \ -- sense, sshdr, timeout, retries, flags, rq_flags, \ -- resid); \ -+ scsi_execute_cmd(_sdev, _cmd, (_data_dir == DMA_TO_DEVICE ? \ -+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN) | _flags, \ -+ _buffer, _bufflen, _timeout, _retries, \ -+ &(struct scsi_exec_args) { \ -+ .sense = _sense, \ -+ .sshdr = _sshdr, \ -+ .req_flags = _rq_flags & RQF_PM ? \ -+ BLK_MQ_REQ_PM : 0, \ -+ .resid = _resid, \ -+ }); \ - }) -+ - static inline int scsi_execute_req(struct scsi_device *sdev, - const unsigned char *cmd, int data_direction, void *buffer, - unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, - int retries, int *resid) - { -- return scsi_execute(sdev, cmd, data_direction, buffer, -- bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); -+ return scsi_execute_cmd(sdev, cmd, -+ data_direction == DMA_TO_DEVICE ? -+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN, buffer, -+ bufflen, timeout, retries, -+ &(struct scsi_exec_args) { -+ .sshdr = sshdr, -+ .resid = resid, -+ }); - } - extern void sdev_disable_disk_events(struct scsi_device *sdev); - extern void sdev_enable_disk_events(struct scsi_device *sdev); -diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h -deleted file mode 100644 -index 738b97f22f365..0000000000000 ---- a/include/trace/events/fs.h -+++ /dev/null -@@ -1,122 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Display helpers for generic filesystem items -- * -- * Author: Chuck Lever -- * -- * Copyright (c) 2020, Oracle and/or its affiliates. -- */ -- --#include -- --#define show_fs_dirent_type(x) \ -- __print_symbolic(x, \ -- { DT_UNKNOWN, "UNKNOWN" }, \ -- { DT_FIFO, "FIFO" }, \ -- { DT_CHR, "CHR" }, \ -- { DT_DIR, "DIR" }, \ -- { DT_BLK, "BLK" }, \ -- { DT_REG, "REG" }, \ -- { DT_LNK, "LNK" }, \ -- { DT_SOCK, "SOCK" }, \ -- { DT_WHT, "WHT" }) -- --#define show_fs_fcntl_open_flags(x) \ -- __print_flags(x, "|", \ -- { O_WRONLY, "O_WRONLY" }, \ -- { O_RDWR, "O_RDWR" }, \ -- { O_CREAT, "O_CREAT" }, \ -- { O_EXCL, "O_EXCL" }, \ -- { O_NOCTTY, "O_NOCTTY" }, \ -- { O_TRUNC, "O_TRUNC" }, \ -- { O_APPEND, "O_APPEND" }, \ -- { O_NONBLOCK, "O_NONBLOCK" }, \ -- { O_DSYNC, "O_DSYNC" }, \ -- { O_DIRECT, "O_DIRECT" }, \ -- { O_LARGEFILE, "O_LARGEFILE" }, \ -- { O_DIRECTORY, "O_DIRECTORY" }, \ -- { O_NOFOLLOW, "O_NOFOLLOW" }, \ -- { O_NOATIME, "O_NOATIME" }, \ -- { O_CLOEXEC, "O_CLOEXEC" }) -- --#define __fmode_flag(x) { (__force unsigned long)FMODE_##x, #x } --#define show_fs_fmode_flags(x) \ -- __print_flags(x, "|", \ -- __fmode_flag(READ), \ -- __fmode_flag(WRITE), \ -- __fmode_flag(EXEC)) -- --#ifdef CONFIG_64BIT --#define show_fs_fcntl_cmd(x) \ -- __print_symbolic(x, \ -- { F_DUPFD, "DUPFD" }, \ -- { F_GETFD, "GETFD" }, \ -- { F_SETFD, "SETFD" }, \ -- { F_GETFL, "GETFL" }, \ -- { F_SETFL, "SETFL" }, \ -- { F_GETLK, "GETLK" }, \ -- { F_SETLK, "SETLK" }, \ -- { F_SETLKW, "SETLKW" }, \ -- { F_SETOWN, "SETOWN" }, \ -- { F_GETOWN, "GETOWN" }, \ -- { F_SETSIG, "SETSIG" }, \ -- { F_GETSIG, "GETSIG" }, \ -- { F_SETOWN_EX, "SETOWN_EX" }, \ -- { F_GETOWN_EX, "GETOWN_EX" }, \ -- { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ -- { F_OFD_GETLK, "OFD_GETLK" }, \ -- { F_OFD_SETLK, "OFD_SETLK" }, \ -- { F_OFD_SETLKW, "OFD_SETLKW" }) --#else /* CONFIG_64BIT */ --#define show_fs_fcntl_cmd(x) \ -- __print_symbolic(x, \ -- { F_DUPFD, "DUPFD" }, \ -- { F_GETFD, "GETFD" }, \ -- { F_SETFD, "SETFD" }, \ -- { F_GETFL, "GETFL" }, \ -- { F_SETFL, "SETFL" }, \ -- { F_GETLK, "GETLK" }, \ -- { F_SETLK, "SETLK" }, \ -- { F_SETLKW, "SETLKW" }, \ -- { F_SETOWN, "SETOWN" }, \ -- { F_GETOWN, "GETOWN" }, \ -- { F_SETSIG, "SETSIG" }, \ -- { F_GETSIG, "GETSIG" }, \ -- { F_GETLK64, "GETLK64" }, \ -- { F_SETLK64, "SETLK64" }, \ -- { F_SETLKW64, "SETLKW64" }, \ -- { F_SETOWN_EX, "SETOWN_EX" }, \ -- { F_GETOWN_EX, "GETOWN_EX" }, \ -- { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ -- { F_OFD_GETLK, "OFD_GETLK" }, \ -- { F_OFD_SETLK, "OFD_SETLK" }, \ -- { F_OFD_SETLKW, "OFD_SETLKW" }) --#endif /* CONFIG_64BIT */ -- --#define show_fs_fcntl_lock_type(x) \ -- __print_symbolic(x, \ -- { F_RDLCK, "RDLCK" }, \ -- { F_WRLCK, "WRLCK" }, \ -- { F_UNLCK, "UNLCK" }) -- --#define show_fs_lookup_flags(flags) \ -- __print_flags(flags, "|", \ -- { LOOKUP_FOLLOW, "FOLLOW" }, \ -- { LOOKUP_DIRECTORY, "DIRECTORY" }, \ -- { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \ -- { LOOKUP_EMPTY, "EMPTY" }, \ -- { LOOKUP_DOWN, "DOWN" }, \ -- { LOOKUP_MOUNTPOINT, "MOUNTPOINT" }, \ -- { LOOKUP_REVAL, "REVAL" }, \ -- { LOOKUP_RCU, "RCU" }, \ -- { LOOKUP_OPEN, "OPEN" }, \ -- { LOOKUP_CREATE, "CREATE" }, \ -- { LOOKUP_EXCL, "EXCL" }, \ -- { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \ -- { LOOKUP_PARENT, "PARENT" }, \ -- { LOOKUP_NO_SYMLINKS, "NO_SYMLINKS" }, \ -- { LOOKUP_NO_MAGICLINKS, "NO_MAGICLINKS" }, \ -- { LOOKUP_NO_XDEV, "NO_XDEV" }, \ -- { LOOKUP_BENEATH, "BENEATH" }, \ -- { LOOKUP_IN_ROOT, "IN_ROOT" }, \ -- { LOOKUP_CACHED, "CACHED" }) -diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h -deleted file mode 100644 -index 09ffdbb04134d..0000000000000 ---- a/include/trace/events/nfs.h -+++ /dev/null -@@ -1,375 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Display helpers for NFS protocol elements -- * -- * Author: Chuck Lever -- * -- * Copyright (c) 2020, Oracle and/or its affiliates. -- */ -- --#include --#include --#include -- --TRACE_DEFINE_ENUM(NFS_OK); --TRACE_DEFINE_ENUM(NFSERR_PERM); --TRACE_DEFINE_ENUM(NFSERR_NOENT); --TRACE_DEFINE_ENUM(NFSERR_IO); --TRACE_DEFINE_ENUM(NFSERR_NXIO); --TRACE_DEFINE_ENUM(NFSERR_EAGAIN); --TRACE_DEFINE_ENUM(NFSERR_ACCES); --TRACE_DEFINE_ENUM(NFSERR_EXIST); --TRACE_DEFINE_ENUM(NFSERR_XDEV); --TRACE_DEFINE_ENUM(NFSERR_NODEV); --TRACE_DEFINE_ENUM(NFSERR_NOTDIR); --TRACE_DEFINE_ENUM(NFSERR_ISDIR); --TRACE_DEFINE_ENUM(NFSERR_INVAL); --TRACE_DEFINE_ENUM(NFSERR_FBIG); --TRACE_DEFINE_ENUM(NFSERR_NOSPC); --TRACE_DEFINE_ENUM(NFSERR_ROFS); --TRACE_DEFINE_ENUM(NFSERR_MLINK); --TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); --TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); --TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); --TRACE_DEFINE_ENUM(NFSERR_DQUOT); --TRACE_DEFINE_ENUM(NFSERR_STALE); --TRACE_DEFINE_ENUM(NFSERR_REMOTE); --TRACE_DEFINE_ENUM(NFSERR_WFLUSH); --TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); --TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); --TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); --TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); --TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); --TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); --TRACE_DEFINE_ENUM(NFSERR_BADTYPE); --TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); -- --#define show_nfs_status(x) \ -- __print_symbolic(x, \ -- { NFS_OK, "OK" }, \ -- { NFSERR_PERM, "PERM" }, \ -- { NFSERR_NOENT, "NOENT" }, \ -- { NFSERR_IO, "IO" }, \ -- { NFSERR_NXIO, "NXIO" }, \ -- { ECHILD, "CHILD" }, \ -- { NFSERR_EAGAIN, "AGAIN" }, \ -- { NFSERR_ACCES, "ACCES" }, \ -- { NFSERR_EXIST, "EXIST" }, \ -- { NFSERR_XDEV, "XDEV" }, \ -- { NFSERR_NODEV, "NODEV" }, \ -- { NFSERR_NOTDIR, "NOTDIR" }, \ -- { NFSERR_ISDIR, "ISDIR" }, \ -- { NFSERR_INVAL, "INVAL" }, \ -- { NFSERR_FBIG, "FBIG" }, \ -- { NFSERR_NOSPC, "NOSPC" }, \ -- { NFSERR_ROFS, "ROFS" }, \ -- { NFSERR_MLINK, "MLINK" }, \ -- { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \ -- { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \ -- { NFSERR_NOTEMPTY, "NOTEMPTY" }, \ -- { NFSERR_DQUOT, "DQUOT" }, \ -- { NFSERR_STALE, "STALE" }, \ -- { NFSERR_REMOTE, "REMOTE" }, \ -- { NFSERR_WFLUSH, "WFLUSH" }, \ -- { NFSERR_BADHANDLE, "BADHANDLE" }, \ -- { NFSERR_NOT_SYNC, "NOTSYNC" }, \ -- { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \ -- { NFSERR_NOTSUPP, "NOTSUPP" }, \ -- { NFSERR_TOOSMALL, "TOOSMALL" }, \ -- { NFSERR_SERVERFAULT, "REMOTEIO" }, \ -- { NFSERR_BADTYPE, "BADTYPE" }, \ -- { NFSERR_JUKEBOX, "JUKEBOX" }) -- --TRACE_DEFINE_ENUM(NFS_UNSTABLE); --TRACE_DEFINE_ENUM(NFS_DATA_SYNC); --TRACE_DEFINE_ENUM(NFS_FILE_SYNC); -- --#define show_nfs_stable_how(x) \ -- __print_symbolic(x, \ -- { NFS_UNSTABLE, "UNSTABLE" }, \ -- { NFS_DATA_SYNC, "DATA_SYNC" }, \ -- { NFS_FILE_SYNC, "FILE_SYNC" }) -- --TRACE_DEFINE_ENUM(NFS4_OK); --TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); --TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); --TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); --TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); --TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); --TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); --TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); --TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); --TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); --TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); --TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); --TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); --TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); --TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); --TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); --TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); --TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); --TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); --TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); --TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); --TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); --TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); --TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); --TRACE_DEFINE_ENUM(NFS4ERR_DELAY); --TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); --TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); --TRACE_DEFINE_ENUM(NFS4ERR_DENIED); --TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); --TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); --TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); --TRACE_DEFINE_ENUM(NFS4ERR_EXIST); --TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); --TRACE_DEFINE_ENUM(NFS4ERR_FBIG); --TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); --TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); --TRACE_DEFINE_ENUM(NFS4ERR_GRACE); --TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); --TRACE_DEFINE_ENUM(NFS4ERR_INVAL); --TRACE_DEFINE_ENUM(NFS4ERR_IO); --TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); --TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); --TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); --TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); --TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); --TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); --TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); --TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); --TRACE_DEFINE_ENUM(NFS4ERR_MLINK); --TRACE_DEFINE_ENUM(NFS4ERR_MOVED); --TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); --TRACE_DEFINE_ENUM(NFS4ERR_NOENT); --TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); --TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); --TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); --TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); --TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); --TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); --TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); --TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); --TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); --TRACE_DEFINE_ENUM(NFS4ERR_NXIO); --TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); --TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); --TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); --TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); --TRACE_DEFINE_ENUM(NFS4ERR_PERM); --TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); --TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); --TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); --TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); --TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); --TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); --TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); --TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); --TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); --TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); --TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); --TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); --TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); --TRACE_DEFINE_ENUM(NFS4ERR_ROFS); --TRACE_DEFINE_ENUM(NFS4ERR_SAME); --TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); --TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); --TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); --TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); --TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); --TRACE_DEFINE_ENUM(NFS4ERR_STALE); --TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); --TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); --TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); --TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); --TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); --TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); --TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); --TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); --TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); --TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); --TRACE_DEFINE_ENUM(NFS4ERR_XDEV); -- --TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); --TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); -- --#define show_nfs4_status(x) \ -- __print_symbolic(x, \ -- { NFS4_OK, "OK" }, \ -- { EPERM, "EPERM" }, \ -- { ENOENT, "ENOENT" }, \ -- { EIO, "EIO" }, \ -- { ENXIO, "ENXIO" }, \ -- { EACCES, "EACCES" }, \ -- { EEXIST, "EEXIST" }, \ -- { EXDEV, "EXDEV" }, \ -- { ENOTDIR, "ENOTDIR" }, \ -- { EISDIR, "EISDIR" }, \ -- { EFBIG, "EFBIG" }, \ -- { ENOSPC, "ENOSPC" }, \ -- { EROFS, "EROFS" }, \ -- { EMLINK, "EMLINK" }, \ -- { ENAMETOOLONG, "ENAMETOOLONG" }, \ -- { ENOTEMPTY, "ENOTEMPTY" }, \ -- { EDQUOT, "EDQUOT" }, \ -- { ESTALE, "ESTALE" }, \ -- { EBADHANDLE, "EBADHANDLE" }, \ -- { EBADCOOKIE, "EBADCOOKIE" }, \ -- { ENOTSUPP, "ENOTSUPP" }, \ -- { ETOOSMALL, "ETOOSMALL" }, \ -- { EREMOTEIO, "EREMOTEIO" }, \ -- { EBADTYPE, "EBADTYPE" }, \ -- { EAGAIN, "EAGAIN" }, \ -- { ELOOP, "ELOOP" }, \ -- { EOPNOTSUPP, "EOPNOTSUPP" }, \ -- { EDEADLK, "EDEADLK" }, \ -- { ENOMEM, "ENOMEM" }, \ -- { EKEYEXPIRED, "EKEYEXPIRED" }, \ -- { ETIMEDOUT, "ETIMEDOUT" }, \ -- { ERESTARTSYS, "ERESTARTSYS" }, \ -- { ECONNREFUSED, "ECONNREFUSED" }, \ -- { ECONNRESET, "ECONNRESET" }, \ -- { ENETUNREACH, "ENETUNREACH" }, \ -- { EHOSTUNREACH, "EHOSTUNREACH" }, \ -- { EHOSTDOWN, "EHOSTDOWN" }, \ -- { EPIPE, "EPIPE" }, \ -- { EPFNOSUPPORT, "EPFNOSUPPORT" }, \ -- { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \ -- { NFS4ERR_ACCESS, "ACCESS" }, \ -- { NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \ -- { NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \ -- { NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \ -- { NFS4ERR_BADCHAR, "BADCHAR" }, \ -- { NFS4ERR_BADHANDLE, "BADHANDLE" }, \ -- { NFS4ERR_BADIOMODE, "BADIOMODE" }, \ -- { NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \ -- { NFS4ERR_BADLABEL, "BADLABEL" }, \ -- { NFS4ERR_BADNAME, "BADNAME" }, \ -- { NFS4ERR_BADOWNER, "BADOWNER" }, \ -- { NFS4ERR_BADSESSION, "BADSESSION" }, \ -- { NFS4ERR_BADSLOT, "BADSLOT" }, \ -- { NFS4ERR_BADTYPE, "BADTYPE" }, \ -- { NFS4ERR_BADXDR, "BADXDR" }, \ -- { NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \ -- { NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \ -- { NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \ -- { NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \ -- { NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \ -- { NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \ -- { NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -- { NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \ -- { NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \ -- { NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \ -- { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \ -- { NFS4ERR_DEADLOCK, "DEADLOCK" }, \ -- { NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \ -- { NFS4ERR_DELAY, "DELAY" }, \ -- { NFS4ERR_DELEG_ALREADY_WANTED, "DELEG_ALREADY_WANTED" }, \ -- { NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \ -- { NFS4ERR_DENIED, "DENIED" }, \ -- { NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \ -- { NFS4ERR_DQUOT, "DQUOT" }, \ -- { NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \ -- { NFS4ERR_EXIST, "EXIST" }, \ -- { NFS4ERR_EXPIRED, "EXPIRED" }, \ -- { NFS4ERR_FBIG, "FBIG" }, \ -- { NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \ -- { NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \ -- { NFS4ERR_GRACE, "GRACE" }, \ -- { NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \ -- { NFS4ERR_INVAL, "INVAL" }, \ -- { NFS4ERR_IO, "IO" }, \ -- { NFS4ERR_ISDIR, "ISDIR" }, \ -- { NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \ -- { NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \ -- { NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \ -- { NFS4ERR_LOCKED, "LOCKED" }, \ -- { NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \ -- { NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \ -- { NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \ -- { NFS4ERR_MLINK, "MLINK" }, \ -- { NFS4ERR_MOVED, "MOVED" }, \ -- { NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \ -- { NFS4ERR_NOENT, "NOENT" }, \ -- { NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \ -- { NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \ -- { NFS4ERR_NOSPC, "NOSPC" }, \ -- { NFS4ERR_NOTDIR, "NOTDIR" }, \ -- { NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \ -- { NFS4ERR_NOTSUPP, "NOTSUPP" }, \ -- { NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \ -- { NFS4ERR_NOT_SAME, "NOT_SAME" }, \ -- { NFS4ERR_NO_GRACE, "NO_GRACE" }, \ -- { NFS4ERR_NXIO, "NXIO" }, \ -- { NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \ -- { NFS4ERR_OPENMODE, "OPENMODE" }, \ -- { NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \ -- { NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \ -- { NFS4ERR_PERM, "PERM" }, \ -- { NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \ -- { NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \ -- { NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \ -- { NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \ -- { NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \ -- { NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \ -- { NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \ -- { NFS4ERR_REP_TOO_BIG_TO_CACHE, "REP_TOO_BIG_TO_CACHE" }, \ -- { NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \ -- { NFS4ERR_RESOURCE, "RESOURCE" }, \ -- { NFS4ERR_RESTOREFH, "RESTOREFH" }, \ -- { NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \ -- { NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \ -- { NFS4ERR_ROFS, "ROFS" }, \ -- { NFS4ERR_SAME, "SAME" }, \ -- { NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \ -- { NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \ -- { NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \ -- { NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \ -- { NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \ -- { NFS4ERR_STALE, "STALE" }, \ -- { NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \ -- { NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \ -- { NFS4ERR_SYMLINK, "SYMLINK" }, \ -- { NFS4ERR_TOOSMALL, "TOOSMALL" }, \ -- { NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \ -- { NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \ -- { NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \ -- { NFS4ERR_WRONGSEC, "WRONGSEC" }, \ -- { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ -- { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ -- { NFS4ERR_XDEV, "XDEV" }, \ -- /* ***** Internal to Linux NFS client ***** */ \ -- { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ -- { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) -- --#define show_nfs4_verifier(x) \ -- __print_hex_str(x, NFS4_VERIFIER_SIZE) -- --TRACE_DEFINE_ENUM(IOMODE_READ); --TRACE_DEFINE_ENUM(IOMODE_RW); --TRACE_DEFINE_ENUM(IOMODE_ANY); -- --#define show_pnfs_layout_iomode(x) \ -- __print_symbolic(x, \ -- { IOMODE_READ, "READ" }, \ -- { IOMODE_RW, "RW" }, \ -- { IOMODE_ANY, "ANY" }) -- --#define show_nfs4_seq4_status(x) \ -- __print_flags(x, "|", \ -- { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -- { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, "CB_GSS_CONTEXTS_EXPIRING" }, \ -- { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, "CB_GSS_CONTEXTS_EXPIRED" }, \ -- { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \ -- { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \ -- { SEQ4_STATUS_ADMIN_STATE_REVOKED, "ADMIN_STATE_REVOKED" }, \ -- { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, "RECALLABLE_STATE_REVOKED" }, \ -- { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \ -- { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, "RESTART_RECLAIM_NEEDED" }, \ -- { SEQ4_STATUS_CB_PATH_DOWN_SESSION, "CB_PATH_DOWN_SESSION" }, \ -- { SEQ4_STATUS_BACKCHANNEL_FAULT, "BACKCHANNEL_FAULT" }) -diff --git a/include/trace/events/rdma.h b/include/trace/events/rdma.h -deleted file mode 100644 -index 81bb454fc2888..0000000000000 ---- a/include/trace/events/rdma.h -+++ /dev/null -@@ -1,168 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (c) 2017 Oracle. All rights reserved. -- */ -- --/* -- * enum ib_event_type, from include/rdma/ib_verbs.h -- */ --#define IB_EVENT_LIST \ -- ib_event(CQ_ERR) \ -- ib_event(QP_FATAL) \ -- ib_event(QP_REQ_ERR) \ -- ib_event(QP_ACCESS_ERR) \ -- ib_event(COMM_EST) \ -- ib_event(SQ_DRAINED) \ -- ib_event(PATH_MIG) \ -- ib_event(PATH_MIG_ERR) \ -- ib_event(DEVICE_FATAL) \ -- ib_event(PORT_ACTIVE) \ -- ib_event(PORT_ERR) \ -- ib_event(LID_CHANGE) \ -- ib_event(PKEY_CHANGE) \ -- ib_event(SM_CHANGE) \ -- ib_event(SRQ_ERR) \ -- ib_event(SRQ_LIMIT_REACHED) \ -- ib_event(QP_LAST_WQE_REACHED) \ -- ib_event(CLIENT_REREGISTER) \ -- ib_event(GID_CHANGE) \ -- ib_event_end(WQ_FATAL) -- --#undef ib_event --#undef ib_event_end -- --#define ib_event(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); --#define ib_event_end(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); -- --IB_EVENT_LIST -- --#undef ib_event --#undef ib_event_end -- --#define ib_event(x) { IB_EVENT_##x, #x }, --#define ib_event_end(x) { IB_EVENT_##x, #x } -- --#define rdma_show_ib_event(x) \ -- __print_symbolic(x, IB_EVENT_LIST) -- --/* -- * enum ib_wc_status type, from include/rdma/ib_verbs.h -- */ --#define IB_WC_STATUS_LIST \ -- ib_wc_status(SUCCESS) \ -- ib_wc_status(LOC_LEN_ERR) \ -- ib_wc_status(LOC_QP_OP_ERR) \ -- ib_wc_status(LOC_EEC_OP_ERR) \ -- ib_wc_status(LOC_PROT_ERR) \ -- ib_wc_status(WR_FLUSH_ERR) \ -- ib_wc_status(MW_BIND_ERR) \ -- ib_wc_status(BAD_RESP_ERR) \ -- ib_wc_status(LOC_ACCESS_ERR) \ -- ib_wc_status(REM_INV_REQ_ERR) \ -- ib_wc_status(REM_ACCESS_ERR) \ -- ib_wc_status(REM_OP_ERR) \ -- ib_wc_status(RETRY_EXC_ERR) \ -- ib_wc_status(RNR_RETRY_EXC_ERR) \ -- ib_wc_status(LOC_RDD_VIOL_ERR) \ -- ib_wc_status(REM_INV_RD_REQ_ERR) \ -- ib_wc_status(REM_ABORT_ERR) \ -- ib_wc_status(INV_EECN_ERR) \ -- ib_wc_status(INV_EEC_STATE_ERR) \ -- ib_wc_status(FATAL_ERR) \ -- ib_wc_status(RESP_TIMEOUT_ERR) \ -- ib_wc_status_end(GENERAL_ERR) -- --#undef ib_wc_status --#undef ib_wc_status_end -- --#define ib_wc_status(x) TRACE_DEFINE_ENUM(IB_WC_##x); --#define ib_wc_status_end(x) TRACE_DEFINE_ENUM(IB_WC_##x); -- --IB_WC_STATUS_LIST -- --#undef ib_wc_status --#undef ib_wc_status_end -- --#define ib_wc_status(x) { IB_WC_##x, #x }, --#define ib_wc_status_end(x) { IB_WC_##x, #x } -- --#define rdma_show_wc_status(x) \ -- __print_symbolic(x, IB_WC_STATUS_LIST) -- --/* -- * enum ib_cm_event_type, from include/rdma/ib_cm.h -- */ --#define IB_CM_EVENT_LIST \ -- ib_cm_event(REQ_ERROR) \ -- ib_cm_event(REQ_RECEIVED) \ -- ib_cm_event(REP_ERROR) \ -- ib_cm_event(REP_RECEIVED) \ -- ib_cm_event(RTU_RECEIVED) \ -- ib_cm_event(USER_ESTABLISHED) \ -- ib_cm_event(DREQ_ERROR) \ -- ib_cm_event(DREQ_RECEIVED) \ -- ib_cm_event(DREP_RECEIVED) \ -- ib_cm_event(TIMEWAIT_EXIT) \ -- ib_cm_event(MRA_RECEIVED) \ -- ib_cm_event(REJ_RECEIVED) \ -- ib_cm_event(LAP_ERROR) \ -- ib_cm_event(LAP_RECEIVED) \ -- ib_cm_event(APR_RECEIVED) \ -- ib_cm_event(SIDR_REQ_ERROR) \ -- ib_cm_event(SIDR_REQ_RECEIVED) \ -- ib_cm_event_end(SIDR_REP_RECEIVED) -- --#undef ib_cm_event --#undef ib_cm_event_end -- --#define ib_cm_event(x) TRACE_DEFINE_ENUM(IB_CM_##x); --#define ib_cm_event_end(x) TRACE_DEFINE_ENUM(IB_CM_##x); -- --IB_CM_EVENT_LIST -- --#undef ib_cm_event --#undef ib_cm_event_end -- --#define ib_cm_event(x) { IB_CM_##x, #x }, --#define ib_cm_event_end(x) { IB_CM_##x, #x } -- --#define rdma_show_ib_cm_event(x) \ -- __print_symbolic(x, IB_CM_EVENT_LIST) -- --/* -- * enum rdma_cm_event_type, from include/rdma/rdma_cm.h -- */ --#define RDMA_CM_EVENT_LIST \ -- rdma_cm_event(ADDR_RESOLVED) \ -- rdma_cm_event(ADDR_ERROR) \ -- rdma_cm_event(ROUTE_RESOLVED) \ -- rdma_cm_event(ROUTE_ERROR) \ -- rdma_cm_event(CONNECT_REQUEST) \ -- rdma_cm_event(CONNECT_RESPONSE) \ -- rdma_cm_event(CONNECT_ERROR) \ -- rdma_cm_event(UNREACHABLE) \ -- rdma_cm_event(REJECTED) \ -- rdma_cm_event(ESTABLISHED) \ -- rdma_cm_event(DISCONNECTED) \ -- rdma_cm_event(DEVICE_REMOVAL) \ -- rdma_cm_event(MULTICAST_JOIN) \ -- rdma_cm_event(MULTICAST_ERROR) \ -- rdma_cm_event(ADDR_CHANGE) \ -- rdma_cm_event_end(TIMEWAIT_EXIT) -- --#undef rdma_cm_event --#undef rdma_cm_event_end -- --#define rdma_cm_event(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); --#define rdma_cm_event_end(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); -- --RDMA_CM_EVENT_LIST -- --#undef rdma_cm_event --#undef rdma_cm_event_end -- --#define rdma_cm_event(x) { RDMA_CM_EVENT_##x, #x }, --#define rdma_cm_event_end(x) { RDMA_CM_EVENT_##x, #x } -- --#define rdma_show_cm_event(x) \ -- __print_symbolic(x, RDMA_CM_EVENT_LIST) -diff --git a/include/trace/events/rpcgss.h b/include/trace/events/rpcgss.h -index c9048f3e471bb..3f121eed369e8 100644 ---- a/include/trace/events/rpcgss.h -+++ b/include/trace/events/rpcgss.h -@@ -13,7 +13,7 @@ - - #include - --#include -+#include - - /** - ** GSS-API related trace events -diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h -index fcd3b3f1020a6..8f461e04e5f09 100644 ---- a/include/trace/events/rpcrdma.h -+++ b/include/trace/events/rpcrdma.h -@@ -15,8 +15,8 @@ - #include - #include - --#include --#include -+#include -+#include - - /** - ** Event classes -diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h -index f48f2ab9d238b..ffe2679a13ced 100644 ---- a/include/trace/events/sunrpc.h -+++ b/include/trace/events/sunrpc.h -@@ -14,7 +14,7 @@ - #include - #include - --#include -+#include - - TRACE_DEFINE_ENUM(SOCK_STREAM); - TRACE_DEFINE_ENUM(SOCK_DGRAM); -diff --git a/include/trace/events/sunrpc_base.h b/include/trace/events/sunrpc_base.h -deleted file mode 100644 -index 588557d07ea82..0000000000000 ---- a/include/trace/events/sunrpc_base.h -+++ /dev/null -@@ -1,18 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Copyright (c) 2021 Oracle and/or its affiliates. -- * -- * Common types and format specifiers for sunrpc. -- */ -- --#if !defined(_TRACE_SUNRPC_BASE_H) --#define _TRACE_SUNRPC_BASE_H -- --#include -- --#define SUNRPC_TRACE_PID_SPECIFIER "%08x" --#define SUNRPC_TRACE_CLID_SPECIFIER "%08x" --#define SUNRPC_TRACE_TASK_SPECIFIER \ -- "task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER -- --#endif /* _TRACE_SUNRPC_BASE_H */ -diff --git a/include/trace/misc/fs.h b/include/trace/misc/fs.h -new file mode 100644 -index 0000000000000..738b97f22f365 ---- /dev/null -+++ b/include/trace/misc/fs.h -@@ -0,0 +1,122 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Display helpers for generic filesystem items -+ * -+ * Author: Chuck Lever -+ * -+ * Copyright (c) 2020, Oracle and/or its affiliates. -+ */ -+ -+#include -+ -+#define show_fs_dirent_type(x) \ -+ __print_symbolic(x, \ -+ { DT_UNKNOWN, "UNKNOWN" }, \ -+ { DT_FIFO, "FIFO" }, \ -+ { DT_CHR, "CHR" }, \ -+ { DT_DIR, "DIR" }, \ -+ { DT_BLK, "BLK" }, \ -+ { DT_REG, "REG" }, \ -+ { DT_LNK, "LNK" }, \ -+ { DT_SOCK, "SOCK" }, \ -+ { DT_WHT, "WHT" }) -+ -+#define show_fs_fcntl_open_flags(x) \ -+ __print_flags(x, "|", \ -+ { O_WRONLY, "O_WRONLY" }, \ -+ { O_RDWR, "O_RDWR" }, \ -+ { O_CREAT, "O_CREAT" }, \ -+ { O_EXCL, "O_EXCL" }, \ -+ { O_NOCTTY, "O_NOCTTY" }, \ -+ { O_TRUNC, "O_TRUNC" }, \ -+ { O_APPEND, "O_APPEND" }, \ -+ { O_NONBLOCK, "O_NONBLOCK" }, \ -+ { O_DSYNC, "O_DSYNC" }, \ -+ { O_DIRECT, "O_DIRECT" }, \ -+ { O_LARGEFILE, "O_LARGEFILE" }, \ -+ { O_DIRECTORY, "O_DIRECTORY" }, \ -+ { O_NOFOLLOW, "O_NOFOLLOW" }, \ -+ { O_NOATIME, "O_NOATIME" }, \ -+ { O_CLOEXEC, "O_CLOEXEC" }) -+ -+#define __fmode_flag(x) { (__force unsigned long)FMODE_##x, #x } -+#define show_fs_fmode_flags(x) \ -+ __print_flags(x, "|", \ -+ __fmode_flag(READ), \ -+ __fmode_flag(WRITE), \ -+ __fmode_flag(EXEC)) -+ -+#ifdef CONFIG_64BIT -+#define show_fs_fcntl_cmd(x) \ -+ __print_symbolic(x, \ -+ { F_DUPFD, "DUPFD" }, \ -+ { F_GETFD, "GETFD" }, \ -+ { F_SETFD, "SETFD" }, \ -+ { F_GETFL, "GETFL" }, \ -+ { F_SETFL, "SETFL" }, \ -+ { F_GETLK, "GETLK" }, \ -+ { F_SETLK, "SETLK" }, \ -+ { F_SETLKW, "SETLKW" }, \ -+ { F_SETOWN, "SETOWN" }, \ -+ { F_GETOWN, "GETOWN" }, \ -+ { F_SETSIG, "SETSIG" }, \ -+ { F_GETSIG, "GETSIG" }, \ -+ { F_SETOWN_EX, "SETOWN_EX" }, \ -+ { F_GETOWN_EX, "GETOWN_EX" }, \ -+ { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ -+ { F_OFD_GETLK, "OFD_GETLK" }, \ -+ { F_OFD_SETLK, "OFD_SETLK" }, \ -+ { F_OFD_SETLKW, "OFD_SETLKW" }) -+#else /* CONFIG_64BIT */ -+#define show_fs_fcntl_cmd(x) \ -+ __print_symbolic(x, \ -+ { F_DUPFD, "DUPFD" }, \ -+ { F_GETFD, "GETFD" }, \ -+ { F_SETFD, "SETFD" }, \ -+ { F_GETFL, "GETFL" }, \ -+ { F_SETFL, "SETFL" }, \ -+ { F_GETLK, "GETLK" }, \ -+ { F_SETLK, "SETLK" }, \ -+ { F_SETLKW, "SETLKW" }, \ -+ { F_SETOWN, "SETOWN" }, \ -+ { F_GETOWN, "GETOWN" }, \ -+ { F_SETSIG, "SETSIG" }, \ -+ { F_GETSIG, "GETSIG" }, \ -+ { F_GETLK64, "GETLK64" }, \ -+ { F_SETLK64, "SETLK64" }, \ -+ { F_SETLKW64, "SETLKW64" }, \ -+ { F_SETOWN_EX, "SETOWN_EX" }, \ -+ { F_GETOWN_EX, "GETOWN_EX" }, \ -+ { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ -+ { F_OFD_GETLK, "OFD_GETLK" }, \ -+ { F_OFD_SETLK, "OFD_SETLK" }, \ -+ { F_OFD_SETLKW, "OFD_SETLKW" }) -+#endif /* CONFIG_64BIT */ -+ -+#define show_fs_fcntl_lock_type(x) \ -+ __print_symbolic(x, \ -+ { F_RDLCK, "RDLCK" }, \ -+ { F_WRLCK, "WRLCK" }, \ -+ { F_UNLCK, "UNLCK" }) -+ -+#define show_fs_lookup_flags(flags) \ -+ __print_flags(flags, "|", \ -+ { LOOKUP_FOLLOW, "FOLLOW" }, \ -+ { LOOKUP_DIRECTORY, "DIRECTORY" }, \ -+ { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \ -+ { LOOKUP_EMPTY, "EMPTY" }, \ -+ { LOOKUP_DOWN, "DOWN" }, \ -+ { LOOKUP_MOUNTPOINT, "MOUNTPOINT" }, \ -+ { LOOKUP_REVAL, "REVAL" }, \ -+ { LOOKUP_RCU, "RCU" }, \ -+ { LOOKUP_OPEN, "OPEN" }, \ -+ { LOOKUP_CREATE, "CREATE" }, \ -+ { LOOKUP_EXCL, "EXCL" }, \ -+ { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \ -+ { LOOKUP_PARENT, "PARENT" }, \ -+ { LOOKUP_NO_SYMLINKS, "NO_SYMLINKS" }, \ -+ { LOOKUP_NO_MAGICLINKS, "NO_MAGICLINKS" }, \ -+ { LOOKUP_NO_XDEV, "NO_XDEV" }, \ -+ { LOOKUP_BENEATH, "BENEATH" }, \ -+ { LOOKUP_IN_ROOT, "IN_ROOT" }, \ -+ { LOOKUP_CACHED, "CACHED" }) -diff --git a/include/trace/misc/nfs.h b/include/trace/misc/nfs.h -new file mode 100644 -index 0000000000000..0d9d48dca38a8 ---- /dev/null -+++ b/include/trace/misc/nfs.h -@@ -0,0 +1,387 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Display helpers for NFS protocol elements -+ * -+ * Author: Chuck Lever -+ * -+ * Copyright (c) 2020, Oracle and/or its affiliates. -+ */ -+ -+#include -+#include -+#include -+ -+TRACE_DEFINE_ENUM(NFS_OK); -+TRACE_DEFINE_ENUM(NFSERR_PERM); -+TRACE_DEFINE_ENUM(NFSERR_NOENT); -+TRACE_DEFINE_ENUM(NFSERR_IO); -+TRACE_DEFINE_ENUM(NFSERR_NXIO); -+TRACE_DEFINE_ENUM(NFSERR_EAGAIN); -+TRACE_DEFINE_ENUM(NFSERR_ACCES); -+TRACE_DEFINE_ENUM(NFSERR_EXIST); -+TRACE_DEFINE_ENUM(NFSERR_XDEV); -+TRACE_DEFINE_ENUM(NFSERR_NODEV); -+TRACE_DEFINE_ENUM(NFSERR_NOTDIR); -+TRACE_DEFINE_ENUM(NFSERR_ISDIR); -+TRACE_DEFINE_ENUM(NFSERR_INVAL); -+TRACE_DEFINE_ENUM(NFSERR_FBIG); -+TRACE_DEFINE_ENUM(NFSERR_NOSPC); -+TRACE_DEFINE_ENUM(NFSERR_ROFS); -+TRACE_DEFINE_ENUM(NFSERR_MLINK); -+TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); -+TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); -+TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); -+TRACE_DEFINE_ENUM(NFSERR_DQUOT); -+TRACE_DEFINE_ENUM(NFSERR_STALE); -+TRACE_DEFINE_ENUM(NFSERR_REMOTE); -+TRACE_DEFINE_ENUM(NFSERR_WFLUSH); -+TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); -+TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); -+TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); -+TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); -+TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); -+TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); -+TRACE_DEFINE_ENUM(NFSERR_BADTYPE); -+TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); -+ -+#define show_nfs_status(x) \ -+ __print_symbolic(x, \ -+ { NFS_OK, "OK" }, \ -+ { NFSERR_PERM, "PERM" }, \ -+ { NFSERR_NOENT, "NOENT" }, \ -+ { NFSERR_IO, "IO" }, \ -+ { NFSERR_NXIO, "NXIO" }, \ -+ { ECHILD, "CHILD" }, \ -+ { NFSERR_EAGAIN, "AGAIN" }, \ -+ { NFSERR_ACCES, "ACCES" }, \ -+ { NFSERR_EXIST, "EXIST" }, \ -+ { NFSERR_XDEV, "XDEV" }, \ -+ { NFSERR_NODEV, "NODEV" }, \ -+ { NFSERR_NOTDIR, "NOTDIR" }, \ -+ { NFSERR_ISDIR, "ISDIR" }, \ -+ { NFSERR_INVAL, "INVAL" }, \ -+ { NFSERR_FBIG, "FBIG" }, \ -+ { NFSERR_NOSPC, "NOSPC" }, \ -+ { NFSERR_ROFS, "ROFS" }, \ -+ { NFSERR_MLINK, "MLINK" }, \ -+ { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \ -+ { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \ -+ { NFSERR_NOTEMPTY, "NOTEMPTY" }, \ -+ { NFSERR_DQUOT, "DQUOT" }, \ -+ { NFSERR_STALE, "STALE" }, \ -+ { NFSERR_REMOTE, "REMOTE" }, \ -+ { NFSERR_WFLUSH, "WFLUSH" }, \ -+ { NFSERR_BADHANDLE, "BADHANDLE" }, \ -+ { NFSERR_NOT_SYNC, "NOTSYNC" }, \ -+ { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \ -+ { NFSERR_NOTSUPP, "NOTSUPP" }, \ -+ { NFSERR_TOOSMALL, "TOOSMALL" }, \ -+ { NFSERR_SERVERFAULT, "REMOTEIO" }, \ -+ { NFSERR_BADTYPE, "BADTYPE" }, \ -+ { NFSERR_JUKEBOX, "JUKEBOX" }) -+ -+TRACE_DEFINE_ENUM(NFS_UNSTABLE); -+TRACE_DEFINE_ENUM(NFS_DATA_SYNC); -+TRACE_DEFINE_ENUM(NFS_FILE_SYNC); -+ -+#define show_nfs_stable_how(x) \ -+ __print_symbolic(x, \ -+ { NFS_UNSTABLE, "UNSTABLE" }, \ -+ { NFS_DATA_SYNC, "DATA_SYNC" }, \ -+ { NFS_FILE_SYNC, "FILE_SYNC" }) -+ -+TRACE_DEFINE_ENUM(NFS4_OK); -+TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); -+TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); -+TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); -+TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); -+TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); -+TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); -+TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); -+TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); -+TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); -+TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); -+TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); -+TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); -+TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); -+TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); -+TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); -+TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); -+TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); -+TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); -+TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); -+TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); -+TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); -+TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); -+TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); -+TRACE_DEFINE_ENUM(NFS4ERR_DELAY); -+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); -+TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); -+TRACE_DEFINE_ENUM(NFS4ERR_DENIED); -+TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); -+TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); -+TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); -+TRACE_DEFINE_ENUM(NFS4ERR_EXIST); -+TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); -+TRACE_DEFINE_ENUM(NFS4ERR_FBIG); -+TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); -+TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); -+TRACE_DEFINE_ENUM(NFS4ERR_GRACE); -+TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); -+TRACE_DEFINE_ENUM(NFS4ERR_INVAL); -+TRACE_DEFINE_ENUM(NFS4ERR_IO); -+TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); -+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); -+TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); -+TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); -+TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); -+TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); -+TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); -+TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); -+TRACE_DEFINE_ENUM(NFS4ERR_MLINK); -+TRACE_DEFINE_ENUM(NFS4ERR_MOVED); -+TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); -+TRACE_DEFINE_ENUM(NFS4ERR_NOENT); -+TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); -+TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); -+TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); -+TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); -+TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); -+TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); -+TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); -+TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); -+TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); -+TRACE_DEFINE_ENUM(NFS4ERR_NXIO); -+TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); -+TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); -+TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); -+TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); -+TRACE_DEFINE_ENUM(NFS4ERR_PERM); -+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); -+TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); -+TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); -+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); -+TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); -+TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); -+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); -+TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); -+TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); -+TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); -+TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); -+TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); -+TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); -+TRACE_DEFINE_ENUM(NFS4ERR_ROFS); -+TRACE_DEFINE_ENUM(NFS4ERR_SAME); -+TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); -+TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); -+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); -+TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); -+TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); -+TRACE_DEFINE_ENUM(NFS4ERR_STALE); -+TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); -+TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); -+TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); -+TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); -+TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); -+TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); -+TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); -+TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); -+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); -+TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); -+TRACE_DEFINE_ENUM(NFS4ERR_XDEV); -+ -+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); -+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); -+ -+#define show_nfs4_status(x) \ -+ __print_symbolic(x, \ -+ { NFS4_OK, "OK" }, \ -+ { EPERM, "EPERM" }, \ -+ { ENOENT, "ENOENT" }, \ -+ { EIO, "EIO" }, \ -+ { ENXIO, "ENXIO" }, \ -+ { EACCES, "EACCES" }, \ -+ { EEXIST, "EEXIST" }, \ -+ { EXDEV, "EXDEV" }, \ -+ { ENOTDIR, "ENOTDIR" }, \ -+ { EISDIR, "EISDIR" }, \ -+ { EFBIG, "EFBIG" }, \ -+ { ENOSPC, "ENOSPC" }, \ -+ { EROFS, "EROFS" }, \ -+ { EMLINK, "EMLINK" }, \ -+ { ENAMETOOLONG, "ENAMETOOLONG" }, \ -+ { ENOTEMPTY, "ENOTEMPTY" }, \ -+ { EDQUOT, "EDQUOT" }, \ -+ { ESTALE, "ESTALE" }, \ -+ { EBADHANDLE, "EBADHANDLE" }, \ -+ { EBADCOOKIE, "EBADCOOKIE" }, \ -+ { ENOTSUPP, "ENOTSUPP" }, \ -+ { ETOOSMALL, "ETOOSMALL" }, \ -+ { EREMOTEIO, "EREMOTEIO" }, \ -+ { EBADTYPE, "EBADTYPE" }, \ -+ { EAGAIN, "EAGAIN" }, \ -+ { ELOOP, "ELOOP" }, \ -+ { EOPNOTSUPP, "EOPNOTSUPP" }, \ -+ { EDEADLK, "EDEADLK" }, \ -+ { ENOMEM, "ENOMEM" }, \ -+ { EKEYEXPIRED, "EKEYEXPIRED" }, \ -+ { ETIMEDOUT, "ETIMEDOUT" }, \ -+ { ERESTARTSYS, "ERESTARTSYS" }, \ -+ { ECONNREFUSED, "ECONNREFUSED" }, \ -+ { ECONNRESET, "ECONNRESET" }, \ -+ { ENETUNREACH, "ENETUNREACH" }, \ -+ { EHOSTUNREACH, "EHOSTUNREACH" }, \ -+ { EHOSTDOWN, "EHOSTDOWN" }, \ -+ { EPIPE, "EPIPE" }, \ -+ { EPFNOSUPPORT, "EPFNOSUPPORT" }, \ -+ { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \ -+ { NFS4ERR_ACCESS, "ACCESS" }, \ -+ { NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \ -+ { NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \ -+ { NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \ -+ { NFS4ERR_BADCHAR, "BADCHAR" }, \ -+ { NFS4ERR_BADHANDLE, "BADHANDLE" }, \ -+ { NFS4ERR_BADIOMODE, "BADIOMODE" }, \ -+ { NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \ -+ { NFS4ERR_BADLABEL, "BADLABEL" }, \ -+ { NFS4ERR_BADNAME, "BADNAME" }, \ -+ { NFS4ERR_BADOWNER, "BADOWNER" }, \ -+ { NFS4ERR_BADSESSION, "BADSESSION" }, \ -+ { NFS4ERR_BADSLOT, "BADSLOT" }, \ -+ { NFS4ERR_BADTYPE, "BADTYPE" }, \ -+ { NFS4ERR_BADXDR, "BADXDR" }, \ -+ { NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \ -+ { NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \ -+ { NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \ -+ { NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \ -+ { NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \ -+ { NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \ -+ { NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -+ { NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \ -+ { NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \ -+ { NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \ -+ { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \ -+ { NFS4ERR_DEADLOCK, "DEADLOCK" }, \ -+ { NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \ -+ { NFS4ERR_DELAY, "DELAY" }, \ -+ { NFS4ERR_DELEG_ALREADY_WANTED, "DELEG_ALREADY_WANTED" }, \ -+ { NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \ -+ { NFS4ERR_DENIED, "DENIED" }, \ -+ { NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \ -+ { NFS4ERR_DQUOT, "DQUOT" }, \ -+ { NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \ -+ { NFS4ERR_EXIST, "EXIST" }, \ -+ { NFS4ERR_EXPIRED, "EXPIRED" }, \ -+ { NFS4ERR_FBIG, "FBIG" }, \ -+ { NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \ -+ { NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \ -+ { NFS4ERR_GRACE, "GRACE" }, \ -+ { NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \ -+ { NFS4ERR_INVAL, "INVAL" }, \ -+ { NFS4ERR_IO, "IO" }, \ -+ { NFS4ERR_ISDIR, "ISDIR" }, \ -+ { NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \ -+ { NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \ -+ { NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \ -+ { NFS4ERR_LOCKED, "LOCKED" }, \ -+ { NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \ -+ { NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \ -+ { NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \ -+ { NFS4ERR_MLINK, "MLINK" }, \ -+ { NFS4ERR_MOVED, "MOVED" }, \ -+ { NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \ -+ { NFS4ERR_NOENT, "NOENT" }, \ -+ { NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \ -+ { NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \ -+ { NFS4ERR_NOSPC, "NOSPC" }, \ -+ { NFS4ERR_NOTDIR, "NOTDIR" }, \ -+ { NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \ -+ { NFS4ERR_NOTSUPP, "NOTSUPP" }, \ -+ { NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \ -+ { NFS4ERR_NOT_SAME, "NOT_SAME" }, \ -+ { NFS4ERR_NO_GRACE, "NO_GRACE" }, \ -+ { NFS4ERR_NXIO, "NXIO" }, \ -+ { NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \ -+ { NFS4ERR_OPENMODE, "OPENMODE" }, \ -+ { NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \ -+ { NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \ -+ { NFS4ERR_PERM, "PERM" }, \ -+ { NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \ -+ { NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \ -+ { NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \ -+ { NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \ -+ { NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \ -+ { NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \ -+ { NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \ -+ { NFS4ERR_REP_TOO_BIG_TO_CACHE, "REP_TOO_BIG_TO_CACHE" }, \ -+ { NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \ -+ { NFS4ERR_RESOURCE, "RESOURCE" }, \ -+ { NFS4ERR_RESTOREFH, "RESTOREFH" }, \ -+ { NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \ -+ { NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \ -+ { NFS4ERR_ROFS, "ROFS" }, \ -+ { NFS4ERR_SAME, "SAME" }, \ -+ { NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \ -+ { NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \ -+ { NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \ -+ { NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \ -+ { NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \ -+ { NFS4ERR_STALE, "STALE" }, \ -+ { NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \ -+ { NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \ -+ { NFS4ERR_SYMLINK, "SYMLINK" }, \ -+ { NFS4ERR_TOOSMALL, "TOOSMALL" }, \ -+ { NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \ -+ { NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \ -+ { NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \ -+ { NFS4ERR_WRONGSEC, "WRONGSEC" }, \ -+ { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ -+ { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ -+ { NFS4ERR_XDEV, "XDEV" }, \ -+ /* ***** Internal to Linux NFS client ***** */ \ -+ { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ -+ { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) -+ -+#define show_nfs4_verifier(x) \ -+ __print_hex_str(x, NFS4_VERIFIER_SIZE) -+ -+TRACE_DEFINE_ENUM(IOMODE_READ); -+TRACE_DEFINE_ENUM(IOMODE_RW); -+TRACE_DEFINE_ENUM(IOMODE_ANY); -+ -+#define show_pnfs_layout_iomode(x) \ -+ __print_symbolic(x, \ -+ { IOMODE_READ, "READ" }, \ -+ { IOMODE_RW, "RW" }, \ -+ { IOMODE_ANY, "ANY" }) -+ -+#define show_rca_mask(x) \ -+ __print_flags(x, "|", \ -+ { BIT(RCA4_TYPE_MASK_RDATA_DLG), "RDATA_DLG" }, \ -+ { BIT(RCA4_TYPE_MASK_WDATA_DLG), "WDATA_DLG" }, \ -+ { BIT(RCA4_TYPE_MASK_DIR_DLG), "DIR_DLG" }, \ -+ { BIT(RCA4_TYPE_MASK_FILE_LAYOUT), "FILE_LAYOUT" }, \ -+ { BIT(RCA4_TYPE_MASK_BLK_LAYOUT), "BLK_LAYOUT" }, \ -+ { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MIN), "OBJ_LAYOUT_MIN" }, \ -+ { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MAX), "OBJ_LAYOUT_MAX" }, \ -+ { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MIN), "OTHER_LAYOUT_MIN" }, \ -+ { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MAX), "OTHER_LAYOUT_MAX" }) -+ -+#define show_nfs4_seq4_status(x) \ -+ __print_flags(x, "|", \ -+ { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -+ { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, "CB_GSS_CONTEXTS_EXPIRING" }, \ -+ { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, "CB_GSS_CONTEXTS_EXPIRED" }, \ -+ { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \ -+ { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \ -+ { SEQ4_STATUS_ADMIN_STATE_REVOKED, "ADMIN_STATE_REVOKED" }, \ -+ { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, "RECALLABLE_STATE_REVOKED" }, \ -+ { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \ -+ { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, "RESTART_RECLAIM_NEEDED" }, \ -+ { SEQ4_STATUS_CB_PATH_DOWN_SESSION, "CB_PATH_DOWN_SESSION" }, \ -+ { SEQ4_STATUS_BACKCHANNEL_FAULT, "BACKCHANNEL_FAULT" }) -diff --git a/include/trace/misc/rdma.h b/include/trace/misc/rdma.h -new file mode 100644 -index 0000000000000..81bb454fc2888 ---- /dev/null -+++ b/include/trace/misc/rdma.h -@@ -0,0 +1,168 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2017 Oracle. All rights reserved. -+ */ -+ -+/* -+ * enum ib_event_type, from include/rdma/ib_verbs.h -+ */ -+#define IB_EVENT_LIST \ -+ ib_event(CQ_ERR) \ -+ ib_event(QP_FATAL) \ -+ ib_event(QP_REQ_ERR) \ -+ ib_event(QP_ACCESS_ERR) \ -+ ib_event(COMM_EST) \ -+ ib_event(SQ_DRAINED) \ -+ ib_event(PATH_MIG) \ -+ ib_event(PATH_MIG_ERR) \ -+ ib_event(DEVICE_FATAL) \ -+ ib_event(PORT_ACTIVE) \ -+ ib_event(PORT_ERR) \ -+ ib_event(LID_CHANGE) \ -+ ib_event(PKEY_CHANGE) \ -+ ib_event(SM_CHANGE) \ -+ ib_event(SRQ_ERR) \ -+ ib_event(SRQ_LIMIT_REACHED) \ -+ ib_event(QP_LAST_WQE_REACHED) \ -+ ib_event(CLIENT_REREGISTER) \ -+ ib_event(GID_CHANGE) \ -+ ib_event_end(WQ_FATAL) -+ -+#undef ib_event -+#undef ib_event_end -+ -+#define ib_event(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); -+#define ib_event_end(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); -+ -+IB_EVENT_LIST -+ -+#undef ib_event -+#undef ib_event_end -+ -+#define ib_event(x) { IB_EVENT_##x, #x }, -+#define ib_event_end(x) { IB_EVENT_##x, #x } -+ -+#define rdma_show_ib_event(x) \ -+ __print_symbolic(x, IB_EVENT_LIST) -+ -+/* -+ * enum ib_wc_status type, from include/rdma/ib_verbs.h -+ */ -+#define IB_WC_STATUS_LIST \ -+ ib_wc_status(SUCCESS) \ -+ ib_wc_status(LOC_LEN_ERR) \ -+ ib_wc_status(LOC_QP_OP_ERR) \ -+ ib_wc_status(LOC_EEC_OP_ERR) \ -+ ib_wc_status(LOC_PROT_ERR) \ -+ ib_wc_status(WR_FLUSH_ERR) \ -+ ib_wc_status(MW_BIND_ERR) \ -+ ib_wc_status(BAD_RESP_ERR) \ -+ ib_wc_status(LOC_ACCESS_ERR) \ -+ ib_wc_status(REM_INV_REQ_ERR) \ -+ ib_wc_status(REM_ACCESS_ERR) \ -+ ib_wc_status(REM_OP_ERR) \ -+ ib_wc_status(RETRY_EXC_ERR) \ -+ ib_wc_status(RNR_RETRY_EXC_ERR) \ -+ ib_wc_status(LOC_RDD_VIOL_ERR) \ -+ ib_wc_status(REM_INV_RD_REQ_ERR) \ -+ ib_wc_status(REM_ABORT_ERR) \ -+ ib_wc_status(INV_EECN_ERR) \ -+ ib_wc_status(INV_EEC_STATE_ERR) \ -+ ib_wc_status(FATAL_ERR) \ -+ ib_wc_status(RESP_TIMEOUT_ERR) \ -+ ib_wc_status_end(GENERAL_ERR) -+ -+#undef ib_wc_status -+#undef ib_wc_status_end -+ -+#define ib_wc_status(x) TRACE_DEFINE_ENUM(IB_WC_##x); -+#define ib_wc_status_end(x) TRACE_DEFINE_ENUM(IB_WC_##x); -+ -+IB_WC_STATUS_LIST -+ -+#undef ib_wc_status -+#undef ib_wc_status_end -+ -+#define ib_wc_status(x) { IB_WC_##x, #x }, -+#define ib_wc_status_end(x) { IB_WC_##x, #x } -+ -+#define rdma_show_wc_status(x) \ -+ __print_symbolic(x, IB_WC_STATUS_LIST) -+ -+/* -+ * enum ib_cm_event_type, from include/rdma/ib_cm.h -+ */ -+#define IB_CM_EVENT_LIST \ -+ ib_cm_event(REQ_ERROR) \ -+ ib_cm_event(REQ_RECEIVED) \ -+ ib_cm_event(REP_ERROR) \ -+ ib_cm_event(REP_RECEIVED) \ -+ ib_cm_event(RTU_RECEIVED) \ -+ ib_cm_event(USER_ESTABLISHED) \ -+ ib_cm_event(DREQ_ERROR) \ -+ ib_cm_event(DREQ_RECEIVED) \ -+ ib_cm_event(DREP_RECEIVED) \ -+ ib_cm_event(TIMEWAIT_EXIT) \ -+ ib_cm_event(MRA_RECEIVED) \ -+ ib_cm_event(REJ_RECEIVED) \ -+ ib_cm_event(LAP_ERROR) \ -+ ib_cm_event(LAP_RECEIVED) \ -+ ib_cm_event(APR_RECEIVED) \ -+ ib_cm_event(SIDR_REQ_ERROR) \ -+ ib_cm_event(SIDR_REQ_RECEIVED) \ -+ ib_cm_event_end(SIDR_REP_RECEIVED) -+ -+#undef ib_cm_event -+#undef ib_cm_event_end -+ -+#define ib_cm_event(x) TRACE_DEFINE_ENUM(IB_CM_##x); -+#define ib_cm_event_end(x) TRACE_DEFINE_ENUM(IB_CM_##x); -+ -+IB_CM_EVENT_LIST -+ -+#undef ib_cm_event -+#undef ib_cm_event_end -+ -+#define ib_cm_event(x) { IB_CM_##x, #x }, -+#define ib_cm_event_end(x) { IB_CM_##x, #x } -+ -+#define rdma_show_ib_cm_event(x) \ -+ __print_symbolic(x, IB_CM_EVENT_LIST) -+ -+/* -+ * enum rdma_cm_event_type, from include/rdma/rdma_cm.h -+ */ -+#define RDMA_CM_EVENT_LIST \ -+ rdma_cm_event(ADDR_RESOLVED) \ -+ rdma_cm_event(ADDR_ERROR) \ -+ rdma_cm_event(ROUTE_RESOLVED) \ -+ rdma_cm_event(ROUTE_ERROR) \ -+ rdma_cm_event(CONNECT_REQUEST) \ -+ rdma_cm_event(CONNECT_RESPONSE) \ -+ rdma_cm_event(CONNECT_ERROR) \ -+ rdma_cm_event(UNREACHABLE) \ -+ rdma_cm_event(REJECTED) \ -+ rdma_cm_event(ESTABLISHED) \ -+ rdma_cm_event(DISCONNECTED) \ -+ rdma_cm_event(DEVICE_REMOVAL) \ -+ rdma_cm_event(MULTICAST_JOIN) \ -+ rdma_cm_event(MULTICAST_ERROR) \ -+ rdma_cm_event(ADDR_CHANGE) \ -+ rdma_cm_event_end(TIMEWAIT_EXIT) -+ -+#undef rdma_cm_event -+#undef rdma_cm_event_end -+ -+#define rdma_cm_event(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); -+#define rdma_cm_event_end(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); -+ -+RDMA_CM_EVENT_LIST -+ -+#undef rdma_cm_event -+#undef rdma_cm_event_end -+ -+#define rdma_cm_event(x) { RDMA_CM_EVENT_##x, #x }, -+#define rdma_cm_event_end(x) { RDMA_CM_EVENT_##x, #x } -+ -+#define rdma_show_cm_event(x) \ -+ __print_symbolic(x, RDMA_CM_EVENT_LIST) -diff --git a/include/trace/misc/sunrpc.h b/include/trace/misc/sunrpc.h -new file mode 100644 -index 0000000000000..588557d07ea82 ---- /dev/null -+++ b/include/trace/misc/sunrpc.h -@@ -0,0 +1,18 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2021 Oracle and/or its affiliates. -+ * -+ * Common types and format specifiers for sunrpc. -+ */ -+ -+#if !defined(_TRACE_SUNRPC_BASE_H) -+#define _TRACE_SUNRPC_BASE_H -+ -+#include -+ -+#define SUNRPC_TRACE_PID_SPECIFIER "%08x" -+#define SUNRPC_TRACE_CLID_SPECIFIER "%08x" -+#define SUNRPC_TRACE_TASK_SPECIFIER \ -+ "task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER -+ -+#endif /* _TRACE_SUNRPC_BASE_H */ -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 201dc77ebbd77..d5d2183730b9f 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -3109,6 +3109,10 @@ union bpf_attr { - * **BPF_FIB_LOOKUP_DIRECT** - * Do a direct table lookup vs full lookup using FIB - * rules. -+ * **BPF_FIB_LOOKUP_TBID** -+ * Used with BPF_FIB_LOOKUP_DIRECT. -+ * Use the routing table ID present in *params*->tbid -+ * for the fib lookup. - * **BPF_FIB_LOOKUP_OUTPUT** - * Perform lookup from an egress perspective (default is - * ingress). -@@ -3117,6 +3121,11 @@ union bpf_attr { - * and *params*->smac will not be set as output. A common - * use case is to call **bpf_redirect_neigh**\ () after - * doing **bpf_fib_lookup**\ (). -+ * **BPF_FIB_LOOKUP_SRC** -+ * Derive and set source IP addr in *params*->ipv{4,6}_src -+ * for the nexthop. If the src addr cannot be derived, -+ * **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this -+ * case, *params*->dmac and *params*->smac are not set either. - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct sk_buff** tc cls_act programs. -@@ -6687,6 +6696,8 @@ enum { - BPF_FIB_LOOKUP_DIRECT = (1U << 0), - BPF_FIB_LOOKUP_OUTPUT = (1U << 1), - BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), -+ BPF_FIB_LOOKUP_TBID = (1U << 3), -+ BPF_FIB_LOOKUP_SRC = (1U << 4), - }; - - enum { -@@ -6699,6 +6710,7 @@ enum { - BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */ - BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */ - BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */ -+ BPF_FIB_LKUP_RET_NO_SRC_ADDR, /* failed to derive IP src addr */ - }; - - struct bpf_fib_lookup { -@@ -6733,6 +6745,9 @@ struct bpf_fib_lookup { - __u32 rt_metric; - }; - -+ /* input: source address to consider for lookup -+ * output: source address result from lookup -+ */ - union { - __be32 ipv4_src; - __u32 ipv6_src[4]; /* in6_addr; network order */ -@@ -6747,9 +6762,19 @@ struct bpf_fib_lookup { - __u32 ipv6_dst[4]; /* in6_addr; network order */ - }; - -- /* output */ -- __be16 h_vlan_proto; -- __be16 h_vlan_TCI; -+ union { -+ struct { -+ /* output */ -+ __be16 h_vlan_proto; -+ __be16 h_vlan_TCI; -+ }; -+ /* input: when accompanied with the -+ * 'BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID` flags, a -+ * specific routing table to use for the fib lookup. -+ */ -+ __u32 tbid; -+ }; -+ - __u8 smac[6]; /* ETH_ALEN */ - __u8 dmac[6]; /* ETH_ALEN */ - }; -diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h -index c4c53a9ab9595..ff8d21f9e95b7 100644 ---- a/include/uapi/linux/in6.h -+++ b/include/uapi/linux/in6.h -@@ -145,7 +145,7 @@ struct in6_flowlabel_req { - #define IPV6_TLV_PADN 1 - #define IPV6_TLV_ROUTERALERT 5 - #define IPV6_TLV_CALIPSO 7 /* RFC 5570 */ --#define IPV6_TLV_IOAM 49 /* TEMPORARY IANA allocation for IOAM */ -+#define IPV6_TLV_IOAM 49 /* RFC 9486 */ - #define IPV6_TLV_JUMBO 194 - #define IPV6_TLV_HAO 201 /* home address option */ - -diff --git a/lib/nlattr.c b/lib/nlattr.c -index dffd60e4065fd..86344df0ccf7b 100644 ---- a/lib/nlattr.c -+++ b/lib/nlattr.c -@@ -30,6 +30,8 @@ static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { - [NLA_S16] = sizeof(s16), - [NLA_S32] = sizeof(s32), - [NLA_S64] = sizeof(s64), -+ [NLA_BE16] = sizeof(__be16), -+ [NLA_BE32] = sizeof(__be32), - }; - - static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { -@@ -43,6 +45,8 @@ static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { - [NLA_S16] = sizeof(s16), - [NLA_S32] = sizeof(s32), - [NLA_S64] = sizeof(s64), -+ [NLA_BE16] = sizeof(__be16), -+ [NLA_BE32] = sizeof(__be32), - }; - - /* -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 59577946735b1..9736e762184bd 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -607,6 +608,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, - loff_t off_align = round_up(off, size); - unsigned long len_pad, ret; - -+ if (IS_ENABLED(CONFIG_32BIT) || in_compat_syscall()) -+ return 0; -+ - if (off_end <= off_align || (off_end - off_align) < size) - return 0; - -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index 6a1db678d032f..a8932d449eb63 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -1049,6 +1049,7 @@ static void hci_error_reset(struct work_struct *work) - { - struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset); - -+ hci_dev_hold(hdev); - BT_DBG("%s", hdev->name); - - if (hdev->hw_error) -@@ -1056,10 +1057,10 @@ static void hci_error_reset(struct work_struct *work) - else - bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code); - -- if (hci_dev_do_close(hdev)) -- return; -+ if (!hci_dev_do_close(hdev)) -+ hci_dev_do_open(hdev); - -- hci_dev_do_open(hdev); -+ hci_dev_put(hdev); - } - - void hci_uuids_clear(struct hci_dev *hdev) -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index 56ecc5f97b916..452d839c152fc 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -5282,9 +5282,12 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); -- if (!conn || !hci_conn_ssp_enabled(conn)) -+ if (!conn || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) - goto unlock; - -+ /* Assume remote supports SSP since it has triggered this event */ -+ set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); -+ - hci_conn_hold(conn); - - if (!hci_dev_test_flag(hdev, HCI_MGMT)) -@@ -6716,6 +6719,10 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data, - return send_conn_param_neg_reply(hdev, handle, - HCI_ERROR_UNKNOWN_CONN_ID); - -+ if (max > hcon->le_conn_max_interval) -+ return send_conn_param_neg_reply(hdev, handle, -+ HCI_ERROR_INVALID_LL_PARAMS); -+ - if (hci_check_conn_params(min, max, latency, timeout)) - return send_conn_param_neg_reply(hdev, handle, - HCI_ERROR_INVALID_LL_PARAMS); -@@ -7245,10 +7252,10 @@ static void hci_store_wake_reason(struct hci_dev *hdev, u8 event, - * keep track of the bdaddr of the connection event that woke us up. - */ - if (event == HCI_EV_CONN_REQUEST) { -- bacpy(&hdev->wake_addr, &conn_complete->bdaddr); -+ bacpy(&hdev->wake_addr, &conn_request->bdaddr); - hdev->wake_addr_type = BDADDR_BREDR; - } else if (event == HCI_EV_CONN_COMPLETE) { -- bacpy(&hdev->wake_addr, &conn_request->bdaddr); -+ bacpy(&hdev->wake_addr, &conn_complete->bdaddr); - hdev->wake_addr_type = BDADDR_BREDR; - } else if (event == HCI_EV_LE_META) { - struct hci_ev_le_meta *le_ev = (void *)skb->data; -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index 45d19294aa772..a337340464567 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -2251,8 +2251,11 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev, - - /* During suspend, only wakeable devices can be in acceptlist */ - if (hdev->suspended && -- !(params->flags & HCI_CONN_FLAG_REMOTE_WAKEUP)) -+ !(params->flags & HCI_CONN_FLAG_REMOTE_WAKEUP)) { -+ hci_le_del_accept_list_sync(hdev, ¶ms->addr, -+ params->addr_type); - return 0; -+ } - - /* Select filter policy to accept all advertising */ - if (*num_entries >= hdev->le_accept_list_size) -@@ -5482,7 +5485,7 @@ static int hci_inquiry_sync(struct hci_dev *hdev, u8 length) - - bt_dev_dbg(hdev, ""); - -- if (hci_dev_test_flag(hdev, HCI_INQUIRY)) -+ if (test_bit(HCI_INQUIRY, &hdev->flags)) - return 0; - - hci_dev_lock(hdev); -diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c -index 81f5974e5eb5a..b4cba55be5ad9 100644 ---- a/net/bluetooth/l2cap_core.c -+++ b/net/bluetooth/l2cap_core.c -@@ -5614,7 +5614,13 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, - - memset(&rsp, 0, sizeof(rsp)); - -- err = hci_check_conn_params(min, max, latency, to_multiplier); -+ if (max > hcon->le_conn_max_interval) { -+ BT_DBG("requested connection interval exceeds current bounds."); -+ err = -EINVAL; -+ } else { -+ err = hci_check_conn_params(min, max, latency, to_multiplier); -+ } -+ - if (err) - rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); - else -diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c -index 202ad43e35d6b..bff48d5763635 100644 ---- a/net/bridge/br_netfilter_hooks.c -+++ b/net/bridge/br_netfilter_hooks.c -@@ -43,6 +43,10 @@ - #include - #endif - -+#if IS_ENABLED(CONFIG_NF_CONNTRACK) -+#include -+#endif -+ - static unsigned int brnf_net_id __read_mostly; - - struct brnf_net { -@@ -553,6 +557,90 @@ static unsigned int br_nf_pre_routing(void *priv, - return NF_STOLEN; - } - -+#if IS_ENABLED(CONFIG_NF_CONNTRACK) -+/* conntracks' nf_confirm logic cannot handle cloned skbs referencing -+ * the same nf_conn entry, which will happen for multicast (broadcast) -+ * Frames on bridges. -+ * -+ * Example: -+ * macvlan0 -+ * br0 -+ * ethX ethY -+ * -+ * ethX (or Y) receives multicast or broadcast packet containing -+ * an IP packet, not yet in conntrack table. -+ * -+ * 1. skb passes through bridge and fake-ip (br_netfilter)Prerouting. -+ * -> skb->_nfct now references a unconfirmed entry -+ * 2. skb is broad/mcast packet. bridge now passes clones out on each bridge -+ * interface. -+ * 3. skb gets passed up the stack. -+ * 4. In macvlan case, macvlan driver retains clone(s) of the mcast skb -+ * and schedules a work queue to send them out on the lower devices. -+ * -+ * The clone skb->_nfct is not a copy, it is the same entry as the -+ * original skb. The macvlan rx handler then returns RX_HANDLER_PASS. -+ * 5. Normal conntrack hooks (in NF_INET_LOCAL_IN) confirm the orig skb. -+ * -+ * The Macvlan broadcast worker and normal confirm path will race. -+ * -+ * This race will not happen if step 2 already confirmed a clone. In that -+ * case later steps perform skb_clone() with skb->_nfct already confirmed (in -+ * hash table). This works fine. -+ * -+ * But such confirmation won't happen when eb/ip/nftables rules dropped the -+ * packets before they reached the nf_confirm step in postrouting. -+ * -+ * Work around this problem by explicit confirmation of the entry at -+ * LOCAL_IN time, before upper layer has a chance to clone the unconfirmed -+ * entry. -+ * -+ */ -+static unsigned int br_nf_local_in(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct nf_conntrack *nfct = skb_nfct(skb); -+ const struct nf_ct_hook *ct_hook; -+ struct nf_conn *ct; -+ int ret; -+ -+ if (!nfct || skb->pkt_type == PACKET_HOST) -+ return NF_ACCEPT; -+ -+ ct = container_of(nfct, struct nf_conn, ct_general); -+ if (likely(nf_ct_is_confirmed(ct))) -+ return NF_ACCEPT; -+ -+ WARN_ON_ONCE(skb_shared(skb)); -+ WARN_ON_ONCE(refcount_read(&nfct->use) != 1); -+ -+ /* We can't call nf_confirm here, it would create a dependency -+ * on nf_conntrack module. -+ */ -+ ct_hook = rcu_dereference(nf_ct_hook); -+ if (!ct_hook) { -+ skb->_nfct = 0ul; -+ nf_conntrack_put(nfct); -+ return NF_ACCEPT; -+ } -+ -+ nf_bridge_pull_encap_header(skb); -+ ret = ct_hook->confirm(skb); -+ switch (ret & NF_VERDICT_MASK) { -+ case NF_STOLEN: -+ return NF_STOLEN; -+ default: -+ nf_bridge_push_encap_header(skb); -+ break; -+ } -+ -+ ct = container_of(nfct, struct nf_conn, ct_general); -+ WARN_ON_ONCE(!nf_ct_is_confirmed(ct)); -+ -+ return ret; -+} -+#endif - - /* PF_BRIDGE/FORWARD *************************************************/ - static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -962,6 +1050,14 @@ static const struct nf_hook_ops br_nf_ops[] = { - .hooknum = NF_BR_PRE_ROUTING, - .priority = NF_BR_PRI_BRNF, - }, -+#if IS_ENABLED(CONFIG_NF_CONNTRACK) -+ { -+ .hook = br_nf_local_in, -+ .pf = NFPROTO_BRIDGE, -+ .hooknum = NF_BR_LOCAL_IN, -+ .priority = NF_BR_PRI_LAST, -+ }, -+#endif - { - .hook = br_nf_forward_ip, - .pf = NFPROTO_BRIDGE, -diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c -index 06d94b2c6b5de..c7c27ada67044 100644 ---- a/net/bridge/netfilter/nf_conntrack_bridge.c -+++ b/net/bridge/netfilter/nf_conntrack_bridge.c -@@ -291,6 +291,30 @@ static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb, - return nf_conntrack_in(skb, &bridge_state); - } - -+static unsigned int nf_ct_bridge_in(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ enum ip_conntrack_info ctinfo; -+ struct nf_conn *ct; -+ -+ if (skb->pkt_type == PACKET_HOST) -+ return NF_ACCEPT; -+ -+ /* nf_conntrack_confirm() cannot handle concurrent clones, -+ * this happens for broad/multicast frames with e.g. macvlan on top -+ * of the bridge device. -+ */ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) -+ return NF_ACCEPT; -+ -+ /* let inet prerouting call conntrack again */ -+ skb->_nfct = 0; -+ nf_ct_put(ct); -+ -+ return NF_ACCEPT; -+} -+ - static void nf_ct_bridge_frag_save(struct sk_buff *skb, - struct nf_bridge_frag_data *data) - { -@@ -415,6 +439,12 @@ static struct nf_hook_ops nf_ct_bridge_hook_ops[] __read_mostly = { - .hooknum = NF_BR_PRE_ROUTING, - .priority = NF_IP_PRI_CONNTRACK, - }, -+ { -+ .hook = nf_ct_bridge_in, -+ .pf = NFPROTO_BRIDGE, -+ .hooknum = NF_BR_LOCAL_IN, -+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM, -+ }, - { - .hook = nf_ct_bridge_post, - .pf = NFPROTO_BRIDGE, -diff --git a/net/core/filter.c b/net/core/filter.c -index 3a6110ea4009f..cb7c4651eaec8 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -5752,6 +5752,12 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - u32 tbid = l3mdev_fib_table_rcu(dev) ? : RT_TABLE_MAIN; - struct fib_table *tb; - -+ if (flags & BPF_FIB_LOOKUP_TBID) { -+ tbid = params->tbid; -+ /* zero out for vlan output */ -+ params->tbid = 0; -+ } -+ - tb = fib_get_table(net, tbid); - if (unlikely(!tb)) - return BPF_FIB_LKUP_RET_NOT_FWDED; -@@ -5803,6 +5809,9 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - params->rt_metric = res.fi->fib_priority; - params->ifindex = dev->ifindex; - -+ if (flags & BPF_FIB_LOOKUP_SRC) -+ params->ipv4_src = fib_result_prefsrc(net, &res); -+ - /* xdp and cls_bpf programs are run in RCU-bh so - * rcu_read_lock_bh is not needed here - */ -@@ -5885,6 +5894,12 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - u32 tbid = l3mdev_fib_table_rcu(dev) ? : RT_TABLE_MAIN; - struct fib6_table *tb; - -+ if (flags & BPF_FIB_LOOKUP_TBID) { -+ tbid = params->tbid; -+ /* zero out for vlan output */ -+ params->tbid = 0; -+ } -+ - tb = ipv6_stub->fib6_get_table(net, tbid); - if (unlikely(!tb)) - return BPF_FIB_LKUP_RET_NOT_FWDED; -@@ -5939,6 +5954,18 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - params->rt_metric = res.f6i->fib6_metric; - params->ifindex = dev->ifindex; - -+ if (flags & BPF_FIB_LOOKUP_SRC) { -+ if (res.f6i->fib6_prefsrc.plen) { -+ *src = res.f6i->fib6_prefsrc.addr; -+ } else { -+ err = ipv6_bpf_stub->ipv6_dev_get_saddr(net, dev, -+ &fl6.daddr, 0, -+ src); -+ if (err) -+ return BPF_FIB_LKUP_RET_NO_SRC_ADDR; -+ } -+ } -+ - if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH) - goto set_fwd_params; - -@@ -5957,7 +5984,8 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - #endif - - #define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \ -- BPF_FIB_LOOKUP_SKIP_NEIGH) -+ BPF_FIB_LOOKUP_SKIP_NEIGH | BPF_FIB_LOOKUP_TBID | \ -+ BPF_FIB_LOOKUP_SRC) - - BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx, - struct bpf_fib_lookup *, params, int, plen, u32, flags) -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 7cf1e42d7f93b..ac379e4590f8d 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -5026,10 +5026,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, - struct net *net = sock_net(skb->sk); - struct ifinfomsg *ifm; - struct net_device *dev; -- struct nlattr *br_spec, *attr = NULL; -+ struct nlattr *br_spec, *attr, *br_flags_attr = NULL; - int rem, err = -EOPNOTSUPP; - u16 flags = 0; -- bool have_flags = false; - - if (nlmsg_len(nlh) < sizeof(*ifm)) - return -EINVAL; -@@ -5047,11 +5046,11 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, - br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); - if (br_spec) { - nla_for_each_nested(attr, br_spec, rem) { -- if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) { -+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !br_flags_attr) { - if (nla_len(attr) < sizeof(flags)) - return -EINVAL; - -- have_flags = true; -+ br_flags_attr = attr; - flags = nla_get_u16(attr); - } - -@@ -5095,8 +5094,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, - } - } - -- if (have_flags) -- memcpy(nla_data(attr), &flags, sizeof(flags)); -+ if (br_flags_attr) -+ memcpy(nla_data(br_flags_attr), &flags, sizeof(flags)); - out: - return err; - } -diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c -index 80cdc6f6b34c9..0323ab5023c69 100644 ---- a/net/hsr/hsr_forward.c -+++ b/net/hsr/hsr_forward.c -@@ -83,7 +83,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) - return false; - - /* Get next tlv */ -- total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tag->tlv.HSR_TLV_length; -+ total_length += hsr_sup_tag->tlv.HSR_TLV_length; - if (!pskb_may_pull(skb, total_length)) - return false; - skb_pull(skb, total_length); -diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c -index 24961b304dad0..328f9068c6a43 100644 ---- a/net/ipv4/ip_tunnel.c -+++ b/net/ipv4/ip_tunnel.c -@@ -540,6 +540,20 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, - return 0; - } - -+static void ip_tunnel_adj_headroom(struct net_device *dev, unsigned int headroom) -+{ -+ /* we must cap headroom to some upperlimit, else pskb_expand_head -+ * will overflow header offsets in skb_headers_offset_update(). -+ */ -+ static const unsigned int max_allowed = 512; -+ -+ if (headroom > max_allowed) -+ headroom = max_allowed; -+ -+ if (headroom > READ_ONCE(dev->needed_headroom)) -+ WRITE_ONCE(dev->needed_headroom, headroom); -+} -+ - void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, - u8 proto, int tunnel_hlen) - { -@@ -614,13 +628,13 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, - } - - headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; -- if (headroom > READ_ONCE(dev->needed_headroom)) -- WRITE_ONCE(dev->needed_headroom, headroom); -- -- if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) { -+ if (skb_cow_head(skb, headroom)) { - ip_rt_put(rt); - goto tx_dropped; - } -+ -+ ip_tunnel_adj_headroom(dev, headroom); -+ - iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl, - df, !net_eq(tunnel->net, dev_net(dev))); - return; -@@ -800,16 +814,16 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, - - max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) - + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); -- if (max_headroom > READ_ONCE(dev->needed_headroom)) -- WRITE_ONCE(dev->needed_headroom, max_headroom); - -- if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) { -+ if (skb_cow_head(skb, max_headroom)) { - ip_rt_put(rt); - dev->stats.tx_dropped++; - kfree_skb(skb); - return; - } - -+ ip_tunnel_adj_headroom(dev, max_headroom); -+ - iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, - df, !net_eq(tunnel->net, dev_net(dev))); - return; -diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c -index 4073762996e22..fc761915c5f6f 100644 ---- a/net/ipv4/netfilter/nf_reject_ipv4.c -+++ b/net/ipv4/netfilter/nf_reject_ipv4.c -@@ -279,6 +279,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb, - goto free_nskb; - - nf_ct_attach(nskb, oldskb); -+ nf_ct_set_closing(skb_nfct(oldskb)); - - #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) - /* If we use ip_local_out for bridged traffic, the MAC source on -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 46527b5cc8f0c..1648373692a99 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -5473,9 +5473,10 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, - } - - addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer); -- if (!addr) -- return -EINVAL; -- -+ if (!addr) { -+ err = -EINVAL; -+ goto errout; -+ } - ifm = nlmsg_data(nlh); - if (ifm->ifa_index) - dev = dev_get_by_index(tgt_net, ifm->ifa_index); -diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c -index 0b42eb8c55aaf..62247621cea52 100644 ---- a/net/ipv6/af_inet6.c -+++ b/net/ipv6/af_inet6.c -@@ -1077,6 +1077,7 @@ static const struct ipv6_bpf_stub ipv6_bpf_stub_impl = { - .udp6_lib_lookup = __udp6_lib_lookup, - .ipv6_setsockopt = do_ipv6_setsockopt, - .ipv6_getsockopt = do_ipv6_getsockopt, -+ .ipv6_dev_get_saddr = ipv6_dev_get_saddr, - }; - - static int __init inet6_init(void) -diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c -index 433d98bbe33f7..71d692728230e 100644 ---- a/net/ipv6/netfilter/nf_reject_ipv6.c -+++ b/net/ipv6/netfilter/nf_reject_ipv6.c -@@ -344,6 +344,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb, - nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen); - - nf_ct_attach(nskb, oldskb); -+ nf_ct_set_closing(skb_nfct(oldskb)); - - #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) - /* If we use ip6_local_out for bridged traffic, the MAC source on -diff --git a/net/mctp/route.c b/net/mctp/route.c -index 256bf0b89e6ca..0144d8ebdaefb 100644 ---- a/net/mctp/route.c -+++ b/net/mctp/route.c -@@ -888,7 +888,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt, - dev = dev_get_by_index_rcu(sock_net(sk), cb->ifindex); - if (!dev) { - rcu_read_unlock(); -- return rc; -+ goto out_free; - } - rt->dev = __mctp_dev_get(dev); - rcu_read_unlock(); -@@ -903,7 +903,8 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt, - rt->mtu = 0; - - } else { -- return -EINVAL; -+ rc = -EINVAL; -+ goto out_free; - } - - spin_lock_irqsave(&rt->dev->addrs_lock, flags); -@@ -966,12 +967,17 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt, - rc = mctp_do_fragment_route(rt, skb, mtu, tag); - } - -+ /* route output functions consume the skb, even on error */ -+ skb = NULL; -+ - out_release: - if (!ext_rt) - mctp_route_release(rt); - - mctp_dev_put(tmp_rt.dev); - -+out_free: -+ kfree_skb(skb); - return rc; - } - -diff --git a/net/mptcp/diag.c b/net/mptcp/diag.c -index e57c5f47f0351..7017dd60659dc 100644 ---- a/net/mptcp/diag.c -+++ b/net/mptcp/diag.c -@@ -21,6 +21,9 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb) - bool slow; - int err; - -+ if (inet_sk_state_load(sk) == TCP_LISTEN) -+ return 0; -+ - start = nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP); - if (!start) - return -EMSGSIZE; -@@ -65,7 +68,7 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb) - sf->map_data_len) || - nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) || - nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) || -- nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, sf->local_id)) { -+ nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf))) { - err = -EMSGSIZE; - goto nla_failure; - } -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index 70a1025f093cf..3328870b0c1f8 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -407,23 +407,12 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk) - } - } - --static bool lookup_address_in_vec(const struct mptcp_addr_info *addrs, unsigned int nr, -- const struct mptcp_addr_info *addr) --{ -- int i; -- -- for (i = 0; i < nr; i++) { -- if (addrs[i].id == addr->id) -- return true; -- } -- -- return false; --} -- - /* Fill all the remote addresses into the array addrs[], - * and return the array size. - */ --static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullmesh, -+static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, -+ struct mptcp_addr_info *local, -+ bool fullmesh, - struct mptcp_addr_info *addrs) - { - bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0); -@@ -446,15 +435,28 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm - msk->pm.subflows++; - addrs[i++] = remote; - } else { -+ DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); -+ -+ /* Forbid creation of new subflows matching existing -+ * ones, possibly already created by incoming ADD_ADDR -+ */ -+ bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); -+ mptcp_for_each_subflow(msk, subflow) -+ if (READ_ONCE(subflow->local_id) == local->id) -+ __set_bit(subflow->remote_id, unavail_id); -+ - mptcp_for_each_subflow(msk, subflow) { - ssk = mptcp_subflow_tcp_sock(subflow); - remote_address((struct sock_common *)ssk, &addrs[i]); -- addrs[i].id = subflow->remote_id; -+ addrs[i].id = READ_ONCE(subflow->remote_id); - if (deny_id0 && !addrs[i].id) - continue; - -- if (!lookup_address_in_vec(addrs, i, &addrs[i]) && -- msk->pm.subflows < subflows_max) { -+ if (msk->pm.subflows < subflows_max) { -+ /* forbid creating multiple address towards -+ * this id -+ */ -+ __set_bit(addrs[i].id, unavail_id); - msk->pm.subflows++; - i++; - } -@@ -603,7 +605,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) - fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); - - msk->pm.local_addr_used++; -- nr = fill_remote_addresses_vec(msk, fullmesh, addrs); -+ nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs); - if (nr) - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); - spin_unlock_bh(&msk->pm.lock); -@@ -798,18 +800,18 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, - - mptcp_for_each_subflow_safe(msk, subflow, tmp) { - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); -+ u8 remote_id = READ_ONCE(subflow->remote_id); - int how = RCV_SHUTDOWN | SEND_SHUTDOWN; -- u8 id = subflow->local_id; -+ u8 id = subflow_get_local_id(subflow); - -- if (rm_type == MPTCP_MIB_RMADDR && subflow->remote_id != rm_id) -+ if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id) - continue; - if (rm_type == MPTCP_MIB_RMSUBFLOW && !mptcp_local_id_match(msk, id, rm_id)) - continue; - - pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u", - rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow", -- i, rm_id, subflow->local_id, subflow->remote_id, -- msk->mpc_endpoint_id); -+ i, rm_id, id, remote_id, msk->mpc_endpoint_id); - spin_unlock_bh(&msk->pm.lock); - mptcp_subflow_shutdown(sk, ssk, how); - -@@ -2028,7 +2030,7 @@ static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk) - if (WARN_ON_ONCE(!sf)) - return -EINVAL; - -- if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, sf->local_id)) -+ if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf))) - return -EMSGSIZE; - - if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id)) -diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c -index 631fa104617c3..414ed70e7ba2e 100644 ---- a/net/mptcp/pm_userspace.c -+++ b/net/mptcp/pm_userspace.c -@@ -233,7 +233,7 @@ static int mptcp_userspace_pm_remove_id_zero_address(struct mptcp_sock *msk, - - lock_sock(sk); - mptcp_for_each_subflow(msk, subflow) { -- if (subflow->local_id == 0) { -+ if (READ_ONCE(subflow->local_id) == 0) { - has_id_0 = true; - break; - } -@@ -489,6 +489,16 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) - goto destroy_err; - } - -+#if IS_ENABLED(CONFIG_MPTCP_IPV6) -+ if (addr_l.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) { -+ ipv6_addr_set_v4mapped(addr_l.addr.s_addr, &addr_l.addr6); -+ addr_l.family = AF_INET6; -+ } -+ if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&addr_l.addr6)) { -+ ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &addr_r.addr6); -+ addr_r.family = AF_INET6; -+ } -+#endif - if (addr_l.family != addr_r.family) { - GENL_SET_ERR_MSG(info, "address families do not match"); - err = -EINVAL; -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 859b18cb8e4f6..3bc21581486ae 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -119,7 +119,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) - subflow->request_mptcp = 1; - - /* This is the first subflow, always with id 0 */ -- subflow->local_id_valid = 1; -+ WRITE_ONCE(subflow->local_id, 0); - mptcp_sock_graft(msk->first, sk->sk_socket); - - return 0; -@@ -1319,6 +1319,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, - mpext = skb_ext_find(skb, SKB_EXT_MPTCP); - if (!mptcp_skb_can_collapse_to(data_seq, skb, mpext)) { - TCP_SKB_CB(skb)->eor = 1; -+ tcp_mark_push(tcp_sk(ssk), skb); - goto alloc_skb; - } - -@@ -2440,6 +2441,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); - if (!dispose_it) { - __mptcp_subflow_disconnect(ssk, subflow, flags); -+ if (msk->subflow && ssk == msk->subflow->sk) -+ msk->subflow->state = SS_UNCONNECTED; - release_sock(ssk); - - goto out; -@@ -3166,8 +3169,50 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk) - - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } -+ -+static void mptcp_copy_ip6_options(struct sock *newsk, const struct sock *sk) -+{ -+ const struct ipv6_pinfo *np = inet6_sk(sk); -+ struct ipv6_txoptions *opt; -+ struct ipv6_pinfo *newnp; -+ -+ newnp = inet6_sk(newsk); -+ -+ rcu_read_lock(); -+ opt = rcu_dereference(np->opt); -+ if (opt) { -+ opt = ipv6_dup_options(newsk, opt); -+ if (!opt) -+ net_warn_ratelimited("%s: Failed to copy ip6 options\n", __func__); -+ } -+ RCU_INIT_POINTER(newnp->opt, opt); -+ rcu_read_unlock(); -+} - #endif - -+static void mptcp_copy_ip_options(struct sock *newsk, const struct sock *sk) -+{ -+ struct ip_options_rcu *inet_opt, *newopt = NULL; -+ const struct inet_sock *inet = inet_sk(sk); -+ struct inet_sock *newinet; -+ -+ newinet = inet_sk(newsk); -+ -+ rcu_read_lock(); -+ inet_opt = rcu_dereference(inet->inet_opt); -+ if (inet_opt) { -+ newopt = sock_kmalloc(newsk, sizeof(*inet_opt) + -+ inet_opt->opt.optlen, GFP_ATOMIC); -+ if (newopt) -+ memcpy(newopt, inet_opt, sizeof(*inet_opt) + -+ inet_opt->opt.optlen); -+ else -+ net_warn_ratelimited("%s: Failed to copy ip options\n", __func__); -+ } -+ RCU_INIT_POINTER(newinet->inet_opt, newopt); -+ rcu_read_unlock(); -+} -+ - struct sock *mptcp_sk_clone_init(const struct sock *sk, - const struct mptcp_options_received *mp_opt, - struct sock *ssk, -@@ -3188,6 +3233,13 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, - - __mptcp_init_sock(nsk); - -+#if IS_ENABLED(CONFIG_MPTCP_IPV6) -+ if (nsk->sk_family == AF_INET6) -+ mptcp_copy_ip6_options(nsk, sk); -+ else -+#endif -+ mptcp_copy_ip_options(nsk, sk); -+ - msk = mptcp_sk(nsk); - msk->local_key = subflow_req->local_key; - msk->token = subflow_req->token; -@@ -3200,7 +3252,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, - msk->write_seq = subflow_req->idsn + 1; - msk->snd_nxt = msk->write_seq; - msk->snd_una = msk->write_seq; -- msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd; -+ msk->wnd_end = msk->snd_nxt + tcp_sk(ssk)->snd_wnd; - msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq; - - if (mp_opt->suboptions & OPTIONS_MPTCP_MPC) { -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index b092205213234..2bc37773e7803 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -475,7 +475,6 @@ struct mptcp_subflow_context { - can_ack : 1, /* only after processing the remote a key */ - disposable : 1, /* ctx can be free at ulp release time */ - stale : 1, /* unable to snd/rcv data, do not use for xmit */ -- local_id_valid : 1, /* local_id is correctly initialized */ - valid_csum_seen : 1; /* at least one csum validated */ - enum mptcp_data_avail data_avail; - u32 remote_nonce; -@@ -483,7 +482,7 @@ struct mptcp_subflow_context { - u32 local_nonce; - u32 remote_token; - u8 hmac[MPTCPOPT_HMAC_LEN]; -- u8 local_id; -+ s16 local_id; /* if negative not initialized yet */ - u8 remote_id; - u8 reset_seen:1; - u8 reset_transient:1; -@@ -529,6 +528,7 @@ mptcp_subflow_ctx_reset(struct mptcp_subflow_context *subflow) - { - memset(&subflow->reset, 0, sizeof(subflow->reset)); - subflow->request_mptcp = 1; -+ WRITE_ONCE(subflow->local_id, -1); - } - - static inline u64 -@@ -909,6 +909,15 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, - int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); - int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); - -+static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow) -+{ -+ int local_id = READ_ONCE(subflow->local_id); -+ -+ if (local_id < 0) -+ return 0; -+ return local_id; -+} -+ - void __init mptcp_pm_nl_init(void); - void mptcp_pm_nl_work(struct mptcp_sock *msk); - void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index 45d20e20cfc00..891c2f4fed080 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -446,7 +446,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) - subflow->backup = mp_opt.backup; - subflow->thmac = mp_opt.thmac; - subflow->remote_nonce = mp_opt.nonce; -- subflow->remote_id = mp_opt.join_id; -+ WRITE_ONCE(subflow->remote_id, mp_opt.join_id); - pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u backup=%d", - subflow, subflow->thmac, subflow->remote_nonce, - subflow->backup); -@@ -489,8 +489,8 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) - - static void subflow_set_local_id(struct mptcp_subflow_context *subflow, int local_id) - { -- subflow->local_id = local_id; -- subflow->local_id_valid = 1; -+ WARN_ON_ONCE(local_id < 0 || local_id > 255); -+ WRITE_ONCE(subflow->local_id, local_id); - } - - static int subflow_chk_local_id(struct sock *sk) -@@ -499,7 +499,7 @@ static int subflow_chk_local_id(struct sock *sk) - struct mptcp_sock *msk = mptcp_sk(subflow->conn); - int err; - -- if (likely(subflow->local_id_valid)) -+ if (likely(subflow->local_id >= 0)) - return 0; - - err = mptcp_pm_get_local_id(msk, (struct sock_common *)sk); -@@ -1477,7 +1477,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, - pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk, - remote_token, local_id, remote_id); - subflow->remote_token = remote_token; -- subflow->remote_id = remote_id; -+ WRITE_ONCE(subflow->remote_id, remote_id); - subflow->request_join = 1; - subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP); - mptcp_info2sockaddr(remote, &addr, ssk->sk_family); -@@ -1630,6 +1630,7 @@ static struct mptcp_subflow_context *subflow_create_ctx(struct sock *sk, - pr_debug("subflow=%p", ctx); - - ctx->tcp_sock = sk; -+ WRITE_ONCE(ctx->local_id, -1); - - return ctx; - } -@@ -1867,13 +1868,13 @@ static void subflow_ulp_clone(const struct request_sock *req, - new_ctx->idsn = subflow_req->idsn; - - /* this is the first subflow, id is always 0 */ -- new_ctx->local_id_valid = 1; -+ subflow_set_local_id(new_ctx, 0); - } else if (subflow_req->mp_join) { - new_ctx->ssn_offset = subflow_req->ssn_offset; - new_ctx->mp_join = 1; - new_ctx->fully_established = 1; - new_ctx->backup = subflow_req->backup; -- new_ctx->remote_id = subflow_req->remote_id; -+ WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); - new_ctx->token = subflow_req->token; - new_ctx->thmac = subflow_req->thmac; - -diff --git a/net/netfilter/core.c b/net/netfilter/core.c -index 55a7f72d547cd..edf92074221e2 100644 ---- a/net/netfilter/core.c -+++ b/net/netfilter/core.c -@@ -707,6 +707,22 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct) - } - EXPORT_SYMBOL(nf_conntrack_destroy); - -+void nf_ct_set_closing(struct nf_conntrack *nfct) -+{ -+ const struct nf_ct_hook *ct_hook; -+ -+ if (!nfct) -+ return; -+ -+ rcu_read_lock(); -+ ct_hook = rcu_dereference(nf_ct_hook); -+ if (ct_hook) -+ ct_hook->set_closing(nfct); -+ -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL_GPL(nf_ct_set_closing); -+ - bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple, - const struct sk_buff *skb) - { -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 7960262966094..024f93fc8c0bb 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -2772,11 +2772,24 @@ int nf_conntrack_init_start(void) - return ret; - } - -+static void nf_conntrack_set_closing(struct nf_conntrack *nfct) -+{ -+ struct nf_conn *ct = nf_ct_to_nf_conn(nfct); -+ -+ switch (nf_ct_protonum(ct)) { -+ case IPPROTO_TCP: -+ nf_conntrack_tcp_set_closing(ct); -+ break; -+ } -+} -+ - static const struct nf_ct_hook nf_conntrack_hook = { - .update = nf_conntrack_update, - .destroy = nf_ct_destroy, - .get_tuple_skb = nf_conntrack_get_tuple_skb, - .attach = nf_conntrack_attach, -+ .set_closing = nf_conntrack_set_closing, -+ .confirm = __nf_conntrack_confirm, - }; - - void nf_conntrack_init_end(void) -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index e0092bf273fd0..9480e638e5d15 100644 ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -913,6 +913,41 @@ static bool tcp_can_early_drop(const struct nf_conn *ct) - return false; - } - -+void nf_conntrack_tcp_set_closing(struct nf_conn *ct) -+{ -+ enum tcp_conntrack old_state; -+ const unsigned int *timeouts; -+ u32 timeout; -+ -+ if (!nf_ct_is_confirmed(ct)) -+ return; -+ -+ spin_lock_bh(&ct->lock); -+ old_state = ct->proto.tcp.state; -+ ct->proto.tcp.state = TCP_CONNTRACK_CLOSE; -+ -+ if (old_state == TCP_CONNTRACK_CLOSE || -+ test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { -+ spin_unlock_bh(&ct->lock); -+ return; -+ } -+ -+ timeouts = nf_ct_timeout_lookup(ct); -+ if (!timeouts) { -+ const struct nf_tcp_net *tn; -+ -+ tn = nf_tcp_pernet(nf_ct_net(ct)); -+ timeouts = tn->timeouts; -+ } -+ -+ timeout = timeouts[TCP_CONNTRACK_CLOSE]; -+ WRITE_ONCE(ct->timeout, timeout + nfct_time_stamp); -+ -+ spin_unlock_bh(&ct->lock); -+ -+ nf_conntrack_event_cache(IPCT_PROTOINFO, ct); -+} -+ - static void nf_ct_tcp_state_reset(struct ip_ct_tcp_state *state) - { - state->td_end = 0; -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index e21ec3ad80939..d3ba947f43761 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -4752,6 +4752,9 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, - if (!(flags & NFT_SET_TIMEOUT)) - return -EINVAL; - -+ if (flags & NFT_SET_ANONYMOUS) -+ return -EOPNOTSUPP; -+ - err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &desc.timeout); - if (err) - return err; -@@ -4760,6 +4763,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, - if (nla[NFTA_SET_GC_INTERVAL] != NULL) { - if (!(flags & NFT_SET_TIMEOUT)) - return -EINVAL; -+ -+ if (flags & NFT_SET_ANONYMOUS) -+ return -EOPNOTSUPP; -+ - desc.gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL])); - } - -diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c -index e1623fbf36548..e4b8c02c5e6ae 100644 ---- a/net/netfilter/nft_compat.c -+++ b/net/netfilter/nft_compat.c -@@ -358,10 +358,20 @@ static int nft_target_validate(const struct nft_ctx *ctx, - - if (ctx->family != NFPROTO_IPV4 && - ctx->family != NFPROTO_IPV6 && -+ ctx->family != NFPROTO_INET && - ctx->family != NFPROTO_BRIDGE && - ctx->family != NFPROTO_ARP) - return -EOPNOTSUPP; - -+ ret = nft_chain_validate_hooks(ctx->chain, -+ (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_LOCAL_IN) | -+ (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_LOCAL_OUT) | -+ (1 << NF_INET_POST_ROUTING)); -+ if (ret) -+ return ret; -+ - if (nft_is_base_chain(ctx->chain)) { - const struct nft_base_chain *basechain = - nft_base_chain(ctx->chain); -@@ -607,10 +617,20 @@ static int nft_match_validate(const struct nft_ctx *ctx, - - if (ctx->family != NFPROTO_IPV4 && - ctx->family != NFPROTO_IPV6 && -+ ctx->family != NFPROTO_INET && - ctx->family != NFPROTO_BRIDGE && - ctx->family != NFPROTO_ARP) - return -EOPNOTSUPP; - -+ ret = nft_chain_validate_hooks(ctx->chain, -+ (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_LOCAL_IN) | -+ (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_LOCAL_OUT) | -+ (1 << NF_INET_POST_ROUTING)); -+ if (ret) -+ return ret; -+ - if (nft_is_base_chain(ctx->chain)) { - const struct nft_base_chain *basechain = - nft_base_chain(ctx->chain); -diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 6857a4965fe87..e9b81cba1e2b4 100644 ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -167,7 +167,7 @@ static inline u32 netlink_group_mask(u32 group) - static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb, - gfp_t gfp_mask) - { -- unsigned int len = skb_end_offset(skb); -+ unsigned int len = skb->len; - struct sk_buff *new; - - new = alloc_skb(len, gfp_mask); -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 93e1bfa72d791..2bd27b77769cb 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -273,6 +273,8 @@ static int tls_do_decryption(struct sock *sk, - return 0; - - ret = crypto_wait_req(ret, &ctx->async_wait); -+ } else if (darg->async) { -+ atomic_dec(&ctx->decrypt_pending); - } - darg->async = false; - -@@ -2021,6 +2023,7 @@ int tls_sw_recvmsg(struct sock *sk, - struct strp_msg *rxm; - struct tls_msg *tlm; - ssize_t copied = 0; -+ ssize_t peeked = 0; - bool async = false; - int target, err; - bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); -@@ -2168,8 +2171,10 @@ int tls_sw_recvmsg(struct sock *sk, - if (err < 0) - goto put_on_rx_list_err; - -- if (is_peek) -+ if (is_peek) { -+ peeked += chunk; - goto put_on_rx_list; -+ } - - if (partially_consumed) { - rxm->offset += chunk; -@@ -2208,8 +2213,8 @@ int tls_sw_recvmsg(struct sock *sk, - - /* Drain records from the rx_list & copy if required */ - if (is_peek || is_kvec) -- err = process_rx_list(ctx, msg, &control, copied, -- decrypted, is_peek, NULL); -+ err = process_rx_list(ctx, msg, &control, copied + peeked, -+ decrypted - peeked, is_peek, NULL); - else - err = process_rx_list(ctx, msg, &control, 0, - async_copy_bytes, is_peek, NULL); -diff --git a/net/unix/garbage.c b/net/unix/garbage.c -index 767b338a7a2d4..ab2c83d58b62a 100644 ---- a/net/unix/garbage.c -+++ b/net/unix/garbage.c -@@ -284,9 +284,17 @@ void unix_gc(void) - * which are creating the cycle(s). - */ - skb_queue_head_init(&hitlist); -- list_for_each_entry(u, &gc_candidates, link) -+ list_for_each_entry(u, &gc_candidates, link) { - scan_children(&u->sk, inc_inflight, &hitlist); - -+#if IS_ENABLED(CONFIG_AF_UNIX_OOB) -+ if (u->oob_skb) { -+ kfree_skb(u->oob_skb); -+ u->oob_skb = NULL; -+ } -+#endif -+ } -+ - /* not_cycle_list contains those sockets which do not make up a - * cycle. Restore these to the inflight list. - */ -@@ -314,17 +322,6 @@ void unix_gc(void) - /* Here we are. Hitlist is filled. Die. */ - __skb_queue_purge(&hitlist); - --#if IS_ENABLED(CONFIG_AF_UNIX_OOB) -- list_for_each_entry_safe(u, next, &gc_candidates, link) { -- struct sk_buff *skb = u->oob_skb; -- -- if (skb) { -- u->oob_skb = NULL; -- kfree_skb(skb); -- } -- } --#endif -- - spin_lock(&unix_gc_lock); - - /* There could be io_uring registered files, just push them back to -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index c259d3227a9e2..1a3bd554e2586 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -4137,6 +4137,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) - - if (ntype != NL80211_IFTYPE_MESH_POINT) - return -EINVAL; -+ if (otype != NL80211_IFTYPE_MESH_POINT) -+ return -EINVAL; - if (netif_running(dev)) - return -EBUSY; - -diff --git a/security/landlock/fs.c b/security/landlock/fs.c -index 64ed7665455fe..d328965f32f7f 100644 ---- a/security/landlock/fs.c -+++ b/security/landlock/fs.c -@@ -824,8 +824,8 @@ static int current_check_refer_path(struct dentry *const old_dentry, - bool allow_parent1, allow_parent2; - access_mask_t access_request_parent1, access_request_parent2; - struct path mnt_dir; -- layer_mask_t layer_masks_parent1[LANDLOCK_NUM_ACCESS_FS], -- layer_masks_parent2[LANDLOCK_NUM_ACCESS_FS]; -+ layer_mask_t layer_masks_parent1[LANDLOCK_NUM_ACCESS_FS] = {}, -+ layer_masks_parent2[LANDLOCK_NUM_ACCESS_FS] = {}; - - if (!dom) - return 0; -diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c -index f4cd9b58b2054..a7af085550b2d 100644 ---- a/security/tomoyo/common.c -+++ b/security/tomoyo/common.c -@@ -2648,13 +2648,14 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, - { - int error = buffer_len; - size_t avail_len = buffer_len; -- char *cp0 = head->write_buf; -+ char *cp0; - int idx; - - if (!head->write) - return -EINVAL; - if (mutex_lock_interruptible(&head->io_sem)) - return -EINTR; -+ cp0 = head->write_buf; - head->read_user_buf_avail = 0; - idx = tomoyo_read_lock(); - /* Read a line and dispatch it to the policy handler. */ -diff --git a/sound/core/Makefile b/sound/core/Makefile -index 2762f03d9b7bc..a7a1590b29526 100644 ---- a/sound/core/Makefile -+++ b/sound/core/Makefile -@@ -30,7 +30,6 @@ snd-ctl-led-objs := control_led.o - snd-rawmidi-objs := rawmidi.o - snd-timer-objs := timer.o - snd-hrtimer-objs := hrtimer.o --snd-rtctimer-objs := rtctimer.o - snd-hwdep-objs := hwdep.o - snd-seq-device-objs := seq_device.o - -diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c -index 9be2260e4ca2d..f8b644cb9157a 100644 ---- a/sound/firewire/amdtp-stream.c -+++ b/sound/firewire/amdtp-stream.c -@@ -934,7 +934,7 @@ static int generate_device_pkt_descs(struct amdtp_stream *s, - // to the reason. - unsigned int safe_cycle = increment_ohci_cycle_count(next_cycle, - IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES); -- lost = (compare_ohci_cycle_count(safe_cycle, cycle) > 0); -+ lost = (compare_ohci_cycle_count(safe_cycle, cycle) < 0); - } - if (lost) { - dev_err(&s->unit->device, "Detect discontinuity of cycle: %d %d\n", -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 92a656fb53212..75bd7b2fa4ee6 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9662,6 +9662,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8973, "HP EliteBook 860 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8974, "HP EliteBook 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8975, "HP EliteBook x360 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x897d, "HP mt440 Mobile Thin Client U74", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8981, "HP Elite Dragonfly G3", ALC245_FIXUP_CS35L41_SPI_4), - SND_PCI_QUIRK(0x103c, 0x898e, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x103c, 0x898f, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2), -@@ -9687,11 +9688,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8ab9, "HP EliteBook 840 G8 (MB 8AB8)", ALC285_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), -+ SND_PCI_QUIRK(0x103c, 0x8b3f, "HP mt440 Mobile Thin Client U91", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b44, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 201dc77ebbd77..d5d2183730b9f 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -3109,6 +3109,10 @@ union bpf_attr { - * **BPF_FIB_LOOKUP_DIRECT** - * Do a direct table lookup vs full lookup using FIB - * rules. -+ * **BPF_FIB_LOOKUP_TBID** -+ * Used with BPF_FIB_LOOKUP_DIRECT. -+ * Use the routing table ID present in *params*->tbid -+ * for the fib lookup. - * **BPF_FIB_LOOKUP_OUTPUT** - * Perform lookup from an egress perspective (default is - * ingress). -@@ -3117,6 +3121,11 @@ union bpf_attr { - * and *params*->smac will not be set as output. A common - * use case is to call **bpf_redirect_neigh**\ () after - * doing **bpf_fib_lookup**\ (). -+ * **BPF_FIB_LOOKUP_SRC** -+ * Derive and set source IP addr in *params*->ipv{4,6}_src -+ * for the nexthop. If the src addr cannot be derived, -+ * **BPF_FIB_LKUP_RET_NO_SRC_ADDR** is returned. In this -+ * case, *params*->dmac and *params*->smac are not set either. - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct sk_buff** tc cls_act programs. -@@ -6687,6 +6696,8 @@ enum { - BPF_FIB_LOOKUP_DIRECT = (1U << 0), - BPF_FIB_LOOKUP_OUTPUT = (1U << 1), - BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), -+ BPF_FIB_LOOKUP_TBID = (1U << 3), -+ BPF_FIB_LOOKUP_SRC = (1U << 4), - }; - - enum { -@@ -6699,6 +6710,7 @@ enum { - BPF_FIB_LKUP_RET_UNSUPP_LWT, /* fwd requires encapsulation */ - BPF_FIB_LKUP_RET_NO_NEIGH, /* no neighbor entry for nh */ - BPF_FIB_LKUP_RET_FRAG_NEEDED, /* fragmentation required to fwd */ -+ BPF_FIB_LKUP_RET_NO_SRC_ADDR, /* failed to derive IP src addr */ - }; - - struct bpf_fib_lookup { -@@ -6733,6 +6745,9 @@ struct bpf_fib_lookup { - __u32 rt_metric; - }; - -+ /* input: source address to consider for lookup -+ * output: source address result from lookup -+ */ - union { - __be32 ipv4_src; - __u32 ipv6_src[4]; /* in6_addr; network order */ -@@ -6747,9 +6762,19 @@ struct bpf_fib_lookup { - __u32 ipv6_dst[4]; /* in6_addr; network order */ - }; - -- /* output */ -- __be16 h_vlan_proto; -- __be16 h_vlan_TCI; -+ union { -+ struct { -+ /* output */ -+ __be16 h_vlan_proto; -+ __be16 h_vlan_TCI; -+ }; -+ /* input: when accompanied with the -+ * 'BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID` flags, a -+ * specific routing table to use for the fib lookup. -+ */ -+ __u32 tbid; -+ }; -+ - __u8 smac[6]; /* ETH_ALEN */ - __u8 dmac[6]; /* ETH_ALEN */ - }; -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index 2107579e2939d..a20dca9d26d68 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -144,6 +144,11 @@ check_tools() - exit $ksft_skip - fi - -+ if ! ss -h | grep -q MPTCP; then -+ echo "SKIP: ss tool does not support MPTCP" -+ exit $ksft_skip -+ fi -+ - # Use the legacy version if available to support old kernel versions - if iptables-legacy -V &> /dev/null; then - iptables="iptables-legacy" diff --git a/patch/kernel/odroidxu4-current/patch-6.1.82-83.patch b/patch/kernel/odroidxu4-current/patch-6.1.82-83.patch deleted file mode 100644 index 328cd4b8ca..0000000000 --- a/patch/kernel/odroidxu4-current/patch-6.1.82-83.patch +++ /dev/null @@ -1,19133 +0,0 @@ -diff --git a/Makefile b/Makefile -index c5345f3ebed0d..38657b3dda2cd 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 82 -+SUBLEVEL = 83 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts -index efed325af88d2..d99bac02232b3 100644 ---- a/arch/arm/boot/dts/arm-realview-pb1176.dts -+++ b/arch/arm/boot/dts/arm-realview-pb1176.dts -@@ -451,7 +451,7 @@ pb1176_serial3: serial@1010f000 { - - /* Direct-mapped development chip ROM */ - pb1176_rom@10200000 { -- compatible = "direct-mapped"; -+ compatible = "mtd-rom"; - reg = <0x10200000 0x4000>; - bank-width = <1>; - }; -diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -index aacbf317feea6..4b7aee8958923 100644 ---- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -+++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -@@ -106,8 +106,6 @@ &fec { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet>; - phy-mode = "rgmii-id"; -- phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; -- phy-reset-duration = <20>; - phy-supply = <&sw2_reg>; - status = "okay"; - -@@ -120,17 +118,10 @@ mdio { - #address-cells = <1>; - #size-cells = <0>; - -- phy_port2: phy@1 { -- reg = <1>; -- }; -- -- phy_port3: phy@2 { -- reg = <2>; -- }; -- - switch@10 { - compatible = "qca,qca8334"; -- reg = <10>; -+ reg = <0x10>; -+ reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; - - switch_ports: ports { - #address-cells = <1>; -@@ -151,15 +142,30 @@ fixed-link { - eth2: port@2 { - reg = <2>; - label = "eth2"; -+ phy-mode = "internal"; - phy-handle = <&phy_port2>; - }; - - eth1: port@3 { - reg = <3>; - label = "eth1"; -+ phy-mode = "internal"; - phy-handle = <&phy_port3>; - }; - }; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ phy_port2: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ -+ phy_port3: ethernet-phy@2 { -+ reg = <2>; -+ }; -+ }; - }; - }; - }; -diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi -index c4b2e9ac24940..5ea45e486ed54 100644 ---- a/arch/arm/boot/dts/qcom-msm8974.dtsi -+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi -@@ -1134,7 +1134,7 @@ restart@fc4ab000 { - - qfprom: qfprom@fc4bc000 { - compatible = "qcom,msm8974-qfprom", "qcom,qfprom"; -- reg = <0xfc4bc000 0x1000>; -+ reg = <0xfc4bc000 0x2100>; - #address-cells = <1>; - #size-cells = <1>; - tsens_calib: calib@d0 { -diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts -index e81a7213d3047..4282bafbb5043 100644 ---- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts -+++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts -@@ -209,6 +209,18 @@ &cmt1 { - status = "okay"; - }; - -+&extal1_clk { -+ clock-frequency = <26000000>; -+}; -+ -+&extal2_clk { -+ clock-frequency = <48000000>; -+}; -+ -+&extalr_clk { -+ clock-frequency = <32768>; -+}; -+ - &pfc { - scifa0_pins: scifa0 { - groups = "scifa0_data"; -diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi -index c39066967053f..d1f4cbd099efb 100644 ---- a/arch/arm/boot/dts/r8a73a4.dtsi -+++ b/arch/arm/boot/dts/r8a73a4.dtsi -@@ -450,17 +450,20 @@ clocks { - extalr_clk: extalr { - compatible = "fixed-clock"; - #clock-cells = <0>; -- clock-frequency = <32768>; -+ /* This value must be overridden by the board. */ -+ clock-frequency = <0>; - }; - extal1_clk: extal1 { - compatible = "fixed-clock"; - #clock-cells = <0>; -- clock-frequency = <25000000>; -+ /* This value must be overridden by the board. */ -+ clock-frequency = <0>; - }; - extal2_clk: extal2 { - compatible = "fixed-clock"; - #clock-cells = <0>; -- clock-frequency = <48000000>; -+ /* This value must be overridden by the board. */ -+ clock-frequency = <0>; - }; - fsiack_clk: fsiack { - compatible = "fixed-clock"; -diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c -index 433ee4ddce6c8..f85933fdec75f 100644 ---- a/arch/arm/crypto/sha256_glue.c -+++ b/arch/arm/crypto/sha256_glue.c -@@ -24,8 +24,8 @@ - - #include "sha256_glue.h" - --asmlinkage void sha256_block_data_order(u32 *digest, const void *data, -- unsigned int num_blks); -+asmlinkage void sha256_block_data_order(struct sha256_state *state, -+ const u8 *data, int num_blks); - - int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data, - unsigned int len) -@@ -33,23 +33,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data, - /* make sure casting to sha256_block_fn() is safe */ - BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0); - -- return sha256_base_do_update(desc, data, len, -- (sha256_block_fn *)sha256_block_data_order); -+ return sha256_base_do_update(desc, data, len, sha256_block_data_order); - } - EXPORT_SYMBOL(crypto_sha256_arm_update); - - static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out) - { -- sha256_base_do_finalize(desc, -- (sha256_block_fn *)sha256_block_data_order); -+ sha256_base_do_finalize(desc, sha256_block_data_order); - return sha256_base_finish(desc, out); - } - - int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) - { -- sha256_base_do_update(desc, data, len, -- (sha256_block_fn *)sha256_block_data_order); -+ sha256_base_do_update(desc, data, len, sha256_block_data_order); - return crypto_sha256_arm_final(desc, out); - } - EXPORT_SYMBOL(crypto_sha256_arm_finup); -diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c -index 0635a65aa488b..1be5bd498af36 100644 ---- a/arch/arm/crypto/sha512-glue.c -+++ b/arch/arm/crypto/sha512-glue.c -@@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha512"); - MODULE_ALIAS_CRYPTO("sha384-arm"); - MODULE_ALIAS_CRYPTO("sha512-arm"); - --asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks); -+asmlinkage void sha512_block_data_order(struct sha512_state *state, -+ u8 const *src, int blocks); - - int sha512_arm_update(struct shash_desc *desc, const u8 *data, - unsigned int len) - { -- return sha512_base_do_update(desc, data, len, -- (sha512_block_fn *)sha512_block_data_order); -+ return sha512_base_do_update(desc, data, len, sha512_block_data_order); - } - - static int sha512_arm_final(struct shash_desc *desc, u8 *out) - { -- sha512_base_do_finalize(desc, -- (sha512_block_fn *)sha512_block_data_order); -+ sha512_base_do_finalize(desc, sha512_block_data_order); - return sha512_base_finish(desc, out); - } - - int sha512_arm_finup(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) - { -- sha512_base_do_update(desc, data, len, -- (sha512_block_fn *)sha512_block_data_order); -+ sha512_base_do_update(desc, data, len, sha512_block_data_order); - return sha512_arm_final(desc, out); - } - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -index 9ec49ac2f6fd5..381d58cea092d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -@@ -291,6 +291,8 @@ sw { - }; - - &spdif { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pin>; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi -index 4903d6358112d..855b7d43bc503 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi -@@ -166,6 +166,8 @@ &r_ir { - }; - - &spdif { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pin>; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index ca1d287a0a01d..d11e5041bae9a 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -406,6 +406,7 @@ spi1_cs_pin: spi1-cs-pin { - function = "spi1"; - }; - -+ /omit-if-no-ref/ - spdif_tx_pin: spdif-tx-pin { - pins = "PH7"; - function = "spdif"; -@@ -655,10 +656,8 @@ spdif: spdif@5093000 { - clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; - clock-names = "apb", "spdif"; - resets = <&ccu RST_BUS_SPDIF>; -- dmas = <&dma 2>; -- dma-names = "tx"; -- pinctrl-names = "default"; -- pinctrl-0 = <&spdif_tx_pin>; -+ dmas = <&dma 2>, <&dma 2>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi -index 4eb2cd14e00b0..9b6da84deae7a 100644 ---- a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi -+++ b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi -@@ -145,7 +145,6 @@ pci@fbc00000 { - msix: msix@fbe00000 { - compatible = "al,alpine-msix"; - reg = <0x0 0xfbe00000 0x0 0x100000>; -- interrupt-controller; - msi-controller; - al,msi-base-spi = <160>; - al,msi-num-spis = <160>; -diff --git a/arch/arm64/boot/dts/amazon/alpine-v3.dtsi b/arch/arm64/boot/dts/amazon/alpine-v3.dtsi -index 73a352ea8fd5c..b30014d4dc29c 100644 ---- a/arch/arm64/boot/dts/amazon/alpine-v3.dtsi -+++ b/arch/arm64/boot/dts/amazon/alpine-v3.dtsi -@@ -351,7 +351,6 @@ pcie@fbd00000 { - msix: msix@fbe00000 { - compatible = "al,alpine-msix"; - reg = <0x0 0xfbe00000 0x0 0x100000>; -- interrupt-controller; - msi-controller; - al,msi-base-spi = <336>; - al,msi-num-spis = <959>; -diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi -index df71348542064..a4c5a38905b03 100644 ---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi -+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi -@@ -180,9 +180,6 @@ ethernet-switch@0 { - brcm,num-gphy = <5>; - brcm,num-rgmii-ports = <2>; - -- #address-cells = <1>; -- #size-cells = <0>; -- - ports: ports { - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi -index fda97c47f4e97..d5778417455c0 100644 ---- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi -+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi -@@ -584,6 +584,7 @@ gpio_g: gpio@660a0000 { - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupts = ; - }; - -diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi -index 8f8c25e51194d..473d7d0ddf369 100644 ---- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi -+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi -@@ -442,6 +442,7 @@ gpio_hsls: gpio@d0000 { - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupts = ; - gpio-ranges = <&pinmux 0 0 16>, - <&pinmux 16 71 2>, -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts -index 8b16bd68576c0..d9fa0deea7002 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts -@@ -294,8 +294,8 @@ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 - - pinctrl_i2c4: i2c4grp { - fsl,pins = < -- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 -- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 -+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083 -+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083 - >; - }; - -@@ -313,19 +313,19 @@ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x19 - - pinctrl_uart1: uart1grp { - fsl,pins = < -- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140 -- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140 -- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140 -- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140 -+ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0 -+ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0 -+ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0 -+ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0 - >; - }; - - pinctrl_uart2: uart2grp { - fsl,pins = < -- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 -- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 -- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 -- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 -+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 -+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 -+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 -+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0 - >; - }; - -@@ -337,40 +337,40 @@ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 - - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - - pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - - pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - }; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts -index a079322a37931..d54cddd65b526 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts -@@ -277,8 +277,8 @@ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 - - pinctrl_i2c4: i2c4grp { - fsl,pins = < -- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 -- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 -+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083 -+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083 - >; - }; - -@@ -290,19 +290,19 @@ MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19 - - pinctrl_uart1: uart1grp { - fsl,pins = < -- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140 -- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140 -- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140 -- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140 -+ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0 -+ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0 -+ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0 -+ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0 - >; - }; - - pinctrl_uart2: uart2grp { - fsl,pins = < -- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 -- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 -- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 -- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 -+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 -+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 -+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 -+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0 - >; - }; - -@@ -314,40 +314,40 @@ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 - - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - - pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - - pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { - fsl,pins = < -- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 -+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 -- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 -- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 -+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 -+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 - >; - }; - }; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi -index 8d10f5b412978..d5199ecb3f6c1 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi -@@ -205,7 +205,7 @@ rtc@52 { - reg = <0x52>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_rtc>; -- interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_HIGH>; -+ interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_LOW>; - trickle-diode-disable; - }; - }; -@@ -247,8 +247,8 @@ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 - - pinctrl_i2c1: i2c1grp { - fsl,pins = < -- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 -- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 -+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083 -+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083 - >; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi -index 0679728d24899..884ae2ad35114 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi -@@ -237,8 +237,8 @@ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 - - pinctrl_i2c1: i2c1grp { - fsl,pins = < -- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 -- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 -+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083 -+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083 - >; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi -index c557dbf4dcd60..2e90466db89a0 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi -@@ -47,17 +47,6 @@ pps { - gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; -- -- reg_usb_otg1_vbus: regulator-usb-otg1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_reg_usb1_en>; -- compatible = "regulator-fixed"; -- regulator-name = "usb_otg1_vbus"; -- gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -- }; - }; - - /* off-board header */ -@@ -146,9 +135,10 @@ &uart3 { - }; - - &usbotg1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usbotg1>; - dr_mode = "otg"; - over-current-active-low; -- vbus-supply = <®_usb_otg1_vbus>; - status = "okay"; - }; - -@@ -206,14 +196,6 @@ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41 - >; - }; - -- pinctrl_reg_usb1_en: regusb1grp { -- fsl,pins = < -- MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41 -- MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141 -- MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41 -- >; -- }; -- - pinctrl_spi2: spi2grp { - fsl,pins = < - MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 -@@ -236,4 +218,11 @@ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 - MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 - >; - }; -+ -+ pinctrl_usbotg1: usbotg1grp { -+ fsl,pins = < -+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141 -+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41 -+ >; -+ }; - }; -diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi -index 78ae73d0cf365..98ff17b14b2a5 100644 ---- a/arch/arm64/boot/dts/lg/lg1312.dtsi -+++ b/arch/arm64/boot/dts/lg/lg1312.dtsi -@@ -124,7 +124,6 @@ eth0: ethernet@c1b00000 { - amba { - #address-cells = <2>; - #size-cells = <1>; -- #interrupt-cells = <3>; - - compatible = "simple-bus"; - interrupt-parent = <&gic>; -diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi -index 2173316573bee..8e9410d8f46c0 100644 ---- a/arch/arm64/boot/dts/lg/lg1313.dtsi -+++ b/arch/arm64/boot/dts/lg/lg1313.dtsi -@@ -124,7 +124,6 @@ eth0: ethernet@c3700000 { - amba { - #address-cells = <2>; - #size-cells = <1>; -- #interrupt-cells = <3>; - - compatible = "simple-bus"; - interrupt-parent = <&gic>; -diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -index df152c72276b8..cd28e1c45b70a 100644 ---- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -@@ -426,14 +426,14 @@ xor11 { - crypto: crypto@90000 { - compatible = "inside-secure,safexcel-eip97ies"; - reg = <0x90000 0x20000>; -- interrupts = , -- , -+ interrupts = , - , - , - , -- ; -- interrupt-names = "mem", "ring0", "ring1", -- "ring2", "ring3", "eip"; -+ , -+ ; -+ interrupt-names = "ring0", "ring1", "ring2", -+ "ring3", "eip", "mem"; - clocks = <&nb_periph_clk 15>; - }; - -diff --git a/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi b/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi -index a06a0a889c43f..73d8803b54d8b 100644 ---- a/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi -+++ b/arch/arm64/boot/dts/marvell/armada-ap80x.dtsi -@@ -133,7 +133,6 @@ pmu { - - odmi: odmi@300000 { - compatible = "marvell,odmi-controller"; -- interrupt-controller; - msi-controller; - marvell,odmi-frames = <4>; - reg = <0x300000 0x4000>, -diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi -index d6c0990a267d9..218c059b16d9c 100644 ---- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi -+++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi -@@ -506,14 +506,14 @@ CP11X_LABEL(sdhci0): mmc@780000 { - CP11X_LABEL(crypto): crypto@800000 { - compatible = "inside-secure,safexcel-eip197b"; - reg = <0x800000 0x200000>; -- interrupts = <87 IRQ_TYPE_LEVEL_HIGH>, -- <88 IRQ_TYPE_LEVEL_HIGH>, -+ interrupts = <88 IRQ_TYPE_LEVEL_HIGH>, - <89 IRQ_TYPE_LEVEL_HIGH>, - <90 IRQ_TYPE_LEVEL_HIGH>, - <91 IRQ_TYPE_LEVEL_HIGH>, -- <92 IRQ_TYPE_LEVEL_HIGH>; -- interrupt-names = "mem", "ring0", "ring1", -- "ring2", "ring3", "eip"; -+ <92 IRQ_TYPE_LEVEL_HIGH>, -+ <87 IRQ_TYPE_LEVEL_HIGH>; -+ interrupt-names = "ring0", "ring1", "ring2", "ring3", -+ "eip", "mem"; - clock-names = "core", "reg"; - clocks = <&CP11X_LABEL(clk) 1 26>, - <&CP11X_LABEL(clk) 1 17>; -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 2c35ed0734a47..b1ddc491d2936 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -74,6 +74,7 @@ led-1 { - - memory@40000000 { - reg = <0 0x40000000 0 0x40000000>; -+ device_type = "memory"; - }; - - reg_1p8v: regulator-1p8v { -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index f9313b697ac12..527dcb279ba52 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -56,6 +56,7 @@ key-wps { - - memory@40000000 { - reg = <0 0x40000000 0 0x20000000>; -+ device_type = "memory"; - }; - - reg_1p8v: regulator-1p8v { -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index fc338bd497f51..108931e796465 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -110,6 +110,7 @@ infracfg: infracfg@10001000 { - compatible = "mediatek,mt7986-infracfg", "syscon"; - reg = <0 0x10001000 0 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; - }; - - wed_pcie: wed-pcie@10003000 { -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -index dccf367c7ec6c..3d95625f1b0b4 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -@@ -4,6 +4,8 @@ - */ - - #include "mt8183-kukui.dtsi" -+/* Must come after mt8183-kukui.dtsi to modify cros_ec */ -+#include - - / { - panel: panel { -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi -index 50a0dd36b5fb3..0d3c7b8162ff0 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi -@@ -372,6 +372,16 @@ pen_eject { - }; - }; - -+&cros_ec { -+ cbas { -+ compatible = "google,cros-cbas"; -+ }; -+ -+ keyboard-controller { -+ compatible = "google,cros-ec-keyb-switches"; -+ }; -+}; -+ - &qca_wifi { - qcom,ath10k-calibration-variant = "GO_KAKADU"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi -index 06f8c80bf5536..e73113cb51f53 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi -@@ -339,6 +339,16 @@ touch_pin_reset: pin_reset { - }; - }; - -+&cros_ec { -+ cbas { -+ compatible = "google,cros-cbas"; -+ }; -+ -+ keyboard-controller { -+ compatible = "google,cros-ec-keyb-switches"; -+ }; -+}; -+ - &qca_wifi { - qcom,ath10k-calibration-variant = "GO_KODAMA"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi -index a7b0cb3ff7b0a..181da69d18f46 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi -@@ -343,6 +343,16 @@ rst_pin { - }; - }; - -+&cros_ec { -+ cbas { -+ compatible = "google,cros-cbas"; -+ }; -+ -+ keyboard-controller { -+ compatible = "google,cros-ec-keyb-switches"; -+ }; -+}; -+ - &qca_wifi { - qcom,ath10k-calibration-variant = "LE_Krane"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -index a428a581c93a8..1db97d94658b9 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -@@ -896,10 +896,6 @@ usbc_extcon: extcon0 { - google,usb-port-id = <0>; - }; - -- cbas { -- compatible = "google,cros-cbas"; -- }; -- - typec { - compatible = "google,cros-ec-typec"; - #address-cells = <1>; -@@ -999,5 +995,4 @@ hub@1 { - }; - }; - --#include - #include -diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi -index 50367da93cd79..c6080af1e4a30 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi -@@ -819,10 +819,6 @@ cros_ec: ec@0 { - #address-cells = <1>; - #size-cells = <0>; - -- base_detection: cbas { -- compatible = "google,cros-cbas"; -- }; -- - cros_ec_pwm: pwm { - compatible = "google,cros-ec-pwm"; - #pwm-cells = <1>; -diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi -index 2f40c6cc407c1..4ed8a0f187583 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi -@@ -1539,7 +1539,7 @@ vcodec_enc: vcodec@17020000 { - mediatek,scp = <&scp>; - power-domains = <&spm MT8192_POWER_DOMAIN_VENC>; - clocks = <&vencsys CLK_VENC_SET1_VENC>; -- clock-names = "venc-set1"; -+ clock-names = "venc_sel"; - assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>; - assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts -index 3348ba69ff6cf..d86d193e5a75e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts -@@ -13,3 +13,7 @@ / { - &ts_10 { - status = "okay"; - }; -+ -+&watchdog { -+ /delete-property/ mediatek,disable-extrst; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts -index 4669e9d917f8c..5356f53308e24 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts -@@ -33,3 +33,7 @@ pins-low-power-pcie0-disable { - &ts_10 { - status = "okay"; - }; -+ -+&watchdog { -+ /delete-property/ mediatek,disable-extrst; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts -index 5021edd02f7c1..fca3606cb951e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts -@@ -34,3 +34,7 @@ pins-low-power-pcie0-disable { - &ts_10 { - status = "okay"; - }; -+ -+&watchdog { -+ /delete-property/ mediatek,disable-extrst; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -index 5117b2e7985af..998c2e78168a6 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -@@ -111,6 +111,7 @@ mt6360: pmic@34 { - compatible = "mediatek,mt6360"; - reg = <0x34>; - interrupt-controller; -+ #interrupt-cells = <1>; - interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>; - interrupt-names = "IRQB"; - -diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -index f094011be9ed9..8099dc04ed2e1 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -@@ -2024,7 +2024,7 @@ ethernet@6800000 { - status = "okay"; - - phy-handle = <&mgbe0_phy>; -- phy-mode = "usxgmii"; -+ phy-mode = "10gbase-r"; - - mdio { - #address-cells = <1>; -diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -index 135ff4368c4a6..5c04c91b0ee2b 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -@@ -532,7 +532,7 @@ &mss_pil { - &pcie0 { - status = "okay"; - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; -- enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>; -+ wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>; - - vddpe-3v3-supply = <&pcie0_3p3v_dual>; - -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index eb1a9369926d2..9dccecd9fcaef 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -1822,8 +1822,8 @@ pcie0: pci@1c00000 { - phys = <&pcie0_lane>; - phy-names = "pciephy"; - -- perst-gpio = <&tlmm 35 GPIO_ACTIVE_HIGH>; -- enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>; -+ perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>; -+ wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; - - pinctrl-names = "default"; - pinctrl-0 = <&pcie0_default_state>; -@@ -1925,7 +1925,7 @@ pcie1: pci@1c08000 { - phys = <&pcie1_lane>; - phy-names = "pciephy"; - -- perst-gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; -+ perst-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>; - enable-gpio = <&tlmm 104 GPIO_ACTIVE_HIGH>; - - pinctrl-names = "default"; -diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -index ed9400f903c9e..b677ef6705d94 100644 ---- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi -@@ -656,8 +656,8 @@ channel7 { - - avb0: ethernet@e6800000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -- reg = <0 0xe6800000 0 0x800>; -+ "renesas,etheravb-rcar-gen4"; -+ reg = <0 0xe6800000 0 0x1000>; - interrupts = , - , - , -@@ -704,8 +704,8 @@ avb0: ethernet@e6800000 { - - avb1: ethernet@e6810000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -- reg = <0 0xe6810000 0 0x800>; -+ "renesas,etheravb-rcar-gen4"; -+ reg = <0 0xe6810000 0 0x1000>; - interrupts = , - , - , -@@ -752,7 +752,7 @@ avb1: ethernet@e6810000 { - - avb2: ethernet@e6820000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -+ "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6820000 0 0x1000>; - interrupts = , - , -@@ -800,7 +800,7 @@ avb2: ethernet@e6820000 { - - avb3: ethernet@e6830000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -+ "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6830000 0 0x1000>; - interrupts = , - , -@@ -848,7 +848,7 @@ avb3: ethernet@e6830000 { - - avb4: ethernet@e6840000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -+ "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6840000 0 0x1000>; - interrupts = , - , -@@ -896,7 +896,7 @@ avb4: ethernet@e6840000 { - - avb5: ethernet@e6850000 { - compatible = "renesas,etheravb-r8a779a0", -- "renesas,etheravb-rcar-gen3"; -+ "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6850000 0 0x1000>; - interrupts = , - , -@@ -1019,7 +1019,7 @@ tpu: pwm@e6e80000 { - - msiof0: spi@e6e90000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6e90000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 618>; -@@ -1034,7 +1034,7 @@ msiof0: spi@e6e90000 { - - msiof1: spi@e6ea0000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6ea0000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 619>; -@@ -1049,7 +1049,7 @@ msiof1: spi@e6ea0000 { - - msiof2: spi@e6c00000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6c00000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 620>; -@@ -1064,7 +1064,7 @@ msiof2: spi@e6c00000 { - - msiof3: spi@e6c10000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6c10000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 621>; -@@ -1079,7 +1079,7 @@ msiof3: spi@e6c10000 { - - msiof4: spi@e6c20000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6c20000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 622>; -@@ -1094,7 +1094,7 @@ msiof4: spi@e6c20000 { - - msiof5: spi@e6c28000 { - compatible = "renesas,msiof-r8a779a0", -- "renesas,rcar-gen3-msiof"; -+ "renesas,rcar-gen4-msiof"; - reg = <0 0xe6c28000 0 0x0064>; - interrupts = ; - clocks = <&cpg CPG_MOD 623>; -diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi -index d58b18802cb01..868d1a3cbdf61 100644 ---- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi -@@ -337,7 +337,7 @@ hscif0: serial@e6540000 { - avb0: ethernet@e6800000 { - compatible = "renesas,etheravb-r8a779g0", - "renesas,etheravb-rcar-gen4"; -- reg = <0 0xe6800000 0 0x800>; -+ reg = <0 0xe6800000 0 0x1000>; - interrupts = , - , - , -@@ -384,7 +384,7 @@ avb0: ethernet@e6800000 { - avb1: ethernet@e6810000 { - compatible = "renesas,etheravb-r8a779g0", - "renesas,etheravb-rcar-gen4"; -- reg = <0 0xe6810000 0 0x800>; -+ reg = <0 0xe6810000 0 0x1000>; - interrupts = , - , - , -diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi -index a4738842f0646..7f88395ff7997 100644 ---- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi -+++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) - /* -- * Device Tree Source for the RZ/G2UL SoC -+ * Device Tree Source for the RZ/Five and RZ/G2UL SoCs - * - * Copyright (C) 2022 Renesas Electronics Corp. - */ -@@ -68,36 +68,8 @@ opp-1000000000 { - }; - }; - -- cpus { -- #address-cells = <1>; -- #size-cells = <0>; -- -- cpu0: cpu@0 { -- compatible = "arm,cortex-a55"; -- reg = <0>; -- device_type = "cpu"; -- #cooling-cells = <2>; -- next-level-cache = <&L3_CA55>; -- enable-method = "psci"; -- clocks = <&cpg CPG_CORE R9A07G043_CLK_I>; -- operating-points-v2 = <&cluster0_opp>; -- }; -- -- L3_CA55: cache-controller-0 { -- compatible = "cache"; -- cache-unified; -- cache-size = <0x40000>; -- }; -- }; -- -- psci { -- compatible = "arm,psci-1.0", "arm,psci-0.2"; -- method = "smc"; -- }; -- - soc: soc { - compatible = "simple-bus"; -- interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - ranges; -@@ -545,12 +517,6 @@ cpg: clock-controller@11010000 { - sysc: system-controller@11020000 { - compatible = "renesas,r9a07g043-sysc"; - reg = <0 0x11020000 0 0x10000>; -- interrupts = , -- , -- , -- ; -- interrupt-names = "lpm_int", "ca55stbydone_int", -- "cm33stbyr_int", "ca55_deny"; - status = "disabled"; - }; - -@@ -603,16 +569,6 @@ dmac: dma-controller@11820000 { - dma-channels = <16>; - }; - -- gic: interrupt-controller@11900000 { -- compatible = "arm,gic-v3"; -- #interrupt-cells = <3>; -- #address-cells = <0>; -- interrupt-controller; -- reg = <0x0 0x11900000 0 0x40000>, -- <0x0 0x11940000 0 0x60000>; -- interrupts = ; -- }; -- - sdhi0: mmc@11c00000 { - compatible = "renesas,sdhi-r9a07g043", - "renesas,rcar-gen3-sdhi"; -@@ -893,12 +849,4 @@ target: trip-point { - }; - }; - }; -- -- timer { -- compatible = "arm,armv8-timer"; -- interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -- <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -- <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -- <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; -- }; - }; -diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi -index 96f935bc2d4d1..011d4c88f4ed9 100644 ---- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi -+++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi -@@ -10,3 +10,139 @@ - #define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr - - #include "r9a07g043.dtsi" -+ -+/ { -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: cpu@0 { -+ compatible = "arm,cortex-a55"; -+ reg = <0>; -+ device_type = "cpu"; -+ #cooling-cells = <2>; -+ next-level-cache = <&L3_CA55>; -+ enable-method = "psci"; -+ clocks = <&cpg CPG_CORE R9A07G043_CLK_I>; -+ operating-points-v2 = <&cluster0_opp>; -+ }; -+ -+ L3_CA55: cache-controller-0 { -+ compatible = "cache"; -+ cache-unified; -+ cache-size = <0x40000>; -+ }; -+ }; -+ -+ psci { -+ compatible = "arm,psci-1.0", "arm,psci-0.2"; -+ method = "smc"; -+ }; -+ -+ timer { -+ compatible = "arm,armv8-timer"; -+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, -+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; -+ }; -+}; -+ -+&soc { -+ interrupt-parent = <&gic>; -+ -+ irqc: interrupt-controller@110a0000 { -+ compatible = "renesas,r9a07g043u-irqc", -+ "renesas,rzg2l-irqc"; -+ reg = <0 0x110a0000 0 0x10000>; -+ #interrupt-cells = <2>; -+ #address-cells = <0>; -+ interrupt-controller; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "nmi", -+ "irq0", "irq1", "irq2", "irq3", -+ "irq4", "irq5", "irq6", "irq7", -+ "tint0", "tint1", "tint2", "tint3", -+ "tint4", "tint5", "tint6", "tint7", -+ "tint8", "tint9", "tint10", "tint11", -+ "tint12", "tint13", "tint14", "tint15", -+ "tint16", "tint17", "tint18", "tint19", -+ "tint20", "tint21", "tint22", "tint23", -+ "tint24", "tint25", "tint26", "tint27", -+ "tint28", "tint29", "tint30", "tint31", -+ "bus-err", "ec7tie1-0", "ec7tie2-0", -+ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", -+ "ec7tiovf-1"; -+ clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>, -+ <&cpg CPG_MOD R9A07G043_IA55_PCLK>; -+ clock-names = "clk", "pclk"; -+ power-domains = <&cpg>; -+ resets = <&cpg R9A07G043_IA55_RESETN>; -+ }; -+ -+ gic: interrupt-controller@11900000 { -+ compatible = "arm,gic-v3"; -+ #interrupt-cells = <3>; -+ #address-cells = <0>; -+ interrupt-controller; -+ reg = <0x0 0x11900000 0 0x40000>, -+ <0x0 0x11940000 0 0x60000>; -+ interrupts = ; -+ }; -+}; -+ -+&sysc { -+ interrupts = , -+ , -+ , -+ ; -+ interrupt-names = "lpm_int", "ca55stbydone_int", -+ "cm33stbyr_int", "ca55_deny"; -+}; -diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi -index 7dbf6a6292f49..d26488b5a82df 100644 ---- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi -+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi -@@ -698,7 +698,27 @@ irqc: interrupt-controller@110a0000 { - , - , - , -- ; -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", -+ "irq4", "irq5", "irq6", "irq7", -+ "tint0", "tint1", "tint2", "tint3", -+ "tint4", "tint5", "tint6", "tint7", -+ "tint8", "tint9", "tint10", "tint11", -+ "tint12", "tint13", "tint14", "tint15", -+ "tint16", "tint17", "tint18", "tint19", -+ "tint20", "tint21", "tint22", "tint23", -+ "tint24", "tint25", "tint26", "tint27", -+ "tint28", "tint29", "tint30", "tint31", -+ "bus-err", "ec7tie1-0", "ec7tie2-0", -+ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", -+ "ec7tiovf-1"; - clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>, - <&cpg CPG_MOD R9A07G044_IA55_PCLK>; - clock-names = "clk", "pclk"; -diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi -index e000510b90a42..b3d37ca942ee3 100644 ---- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi -+++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi -@@ -704,7 +704,27 @@ irqc: interrupt-controller@110a0000 { - , - , - , -- ; -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", -+ "irq4", "irq5", "irq6", "irq7", -+ "tint0", "tint1", "tint2", "tint3", -+ "tint4", "tint5", "tint6", "tint7", -+ "tint8", "tint9", "tint10", "tint11", -+ "tint12", "tint13", "tint14", "tint15", -+ "tint16", "tint17", "tint18", "tint19", -+ "tint20", "tint21", "tint22", "tint23", -+ "tint24", "tint25", "tint26", "tint27", -+ "tint28", "tint29", "tint30", "tint31", -+ "bus-err", "ec7tie1-0", "ec7tie2-0", -+ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", -+ "ec7tiovf-1"; - clocks = <&cpg CPG_MOD R9A07G054_IA55_CLK>, - <&cpg CPG_MOD R9A07G054_IA55_PCLK>; - clock-names = "clk", "pclk"; -diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi -index 588b14b66b6fb..f37abfc13fe59 100644 ---- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi -+++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi -@@ -251,6 +251,7 @@ gpio_exp_74: gpio@74 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupt-parent = <&gpio6>; - interrupts = <8 IRQ_TYPE_EDGE_FALLING>; - -@@ -311,6 +312,7 @@ gpio_exp_75: gpio@75 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupt-parent = <&gpio6>; - interrupts = <4 IRQ_TYPE_EDGE_FALLING>; - }; -@@ -331,6 +333,7 @@ gpio_exp_76: gpio@76 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupt-parent = <&gpio7>; - interrupts = <3 IRQ_TYPE_EDGE_FALLING>; - }; -@@ -341,6 +344,7 @@ gpio_exp_77: gpio@77 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -+ #interrupt-cells = <2>; - interrupt-parent = <&gpio5>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -index f4d6dbbbddcd4..99ad6fc51b584 100644 ---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -@@ -596,6 +596,7 @@ vpu: video-codec@fdea0400 { - compatible = "rockchip,rk3568-vpu"; - reg = <0x0 0xfdea0000 0x0 0x800>; - interrupts = ; -+ interrupt-names = "vdpu"; - clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; - clock-names = "aclk", "hclk"; - iommus = <&vdpu_mmu>; -diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h -index da18413712c04..930b0e6c94622 100644 ---- a/arch/arm64/include/asm/fpsimd.h -+++ b/arch/arm64/include/asm/fpsimd.h -@@ -36,13 +36,13 @@ - * When we defined the maximum SVE vector length we defined the ABI so - * that the maximum vector length included all the reserved for future - * expansion bits in ZCR rather than those just currently defined by -- * the architecture. While SME follows a similar pattern the fact that -- * it includes a square matrix means that any allocations that attempt -- * to cover the maximum potential vector length (such as happen with -- * the regset used for ptrace) end up being extremely large. Define -- * the much lower actual limit for use in such situations. -+ * the architecture. Using this length to allocate worst size buffers -+ * results in excessively large allocations, and this effect is even -+ * more pronounced for SME due to ZA. Define more suitable VLs for -+ * these situations. - */ --#define SME_VQ_MAX 16 -+#define ARCH_SVE_VQ_MAX ((ZCR_ELx_LEN_MASK >> ZCR_ELx_LEN_SHIFT) + 1) -+#define SME_VQ_MAX ((SMCR_ELx_LEN_MASK >> SMCR_ELx_LEN_SHIFT) + 1) - - struct task_struct; - -diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c -index e1f6366b7ccdf..d02dd2be17b3b 100644 ---- a/arch/arm64/kernel/ptrace.c -+++ b/arch/arm64/kernel/ptrace.c -@@ -1450,7 +1450,8 @@ static const struct user_regset aarch64_regsets[] = { - #ifdef CONFIG_ARM64_SVE - [REGSET_SVE] = { /* Scalable Vector Extension */ - .core_note_type = NT_ARM_SVE, -- .n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE), -+ .n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX, -+ SVE_PT_REGS_SVE), - SVE_VQ_BYTES), - .size = SVE_VQ_BYTES, - .align = SVE_VQ_BYTES, -diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h -index daf3cf244ea97..b3e4dd6be7e20 100644 ---- a/arch/mips/include/asm/ptrace.h -+++ b/arch/mips/include/asm/ptrace.h -@@ -60,6 +60,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, - unsigned long val) - { - regs->cp0_epc = val; -+ regs->cp0_cause &= ~CAUSEF_BD; - } - - /* Query offset/name of register from its name/offset */ -diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c -index 4d392e4ed3584..ac7253891d5ed 100644 ---- a/arch/parisc/kernel/ftrace.c -+++ b/arch/parisc/kernel/ftrace.c -@@ -78,7 +78,7 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent, - #endif - } - --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -+#if defined(CONFIG_DYNAMIC_FTRACE) && defined(CONFIG_FUNCTION_GRAPH_TRACER) - int ftrace_enable_ftrace_graph_caller(void) - { - static_key_enable(&ftrace_graph_enable.key); -diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h -index 4c69ece52a31e..59ed89890c902 100644 ---- a/arch/powerpc/include/asm/vmalloc.h -+++ b/arch/powerpc/include/asm/vmalloc.h -@@ -7,14 +7,14 @@ - #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP - - #define arch_vmap_pud_supported arch_vmap_pud_supported --static inline bool arch_vmap_pud_supported(pgprot_t prot) -+static __always_inline bool arch_vmap_pud_supported(pgprot_t prot) - { - /* HPT does not cope with large pages in the vmalloc area */ - return radix_enabled(); - } - - #define arch_vmap_pmd_supported arch_vmap_pmd_supported --static inline bool arch_vmap_pmd_supported(pgprot_t prot) -+static __always_inline bool arch_vmap_pmd_supported(pgprot_t prot) - { - return radix_enabled(); - } -diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c -index 7ff8ff3509f5f..943248a0e9a9d 100644 ---- a/arch/powerpc/perf/hv-gpci.c -+++ b/arch/powerpc/perf/hv-gpci.c -@@ -164,6 +164,20 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, - - ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, - virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); -+ -+ /* -+ * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL', -+ * specifies that the current buffer size cannot accommodate -+ * all the information and a partial buffer returned. -+ * Since in this function we are only accessing data for a given starting index, -+ * we don't need to accommodate whole data and can get required count by -+ * accessing first entry data. -+ * Hence hcall fails only incase the ret value is other than H_SUCCESS or -+ * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B). -+ */ -+ if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B) -+ ret = 0; -+ - if (ret) { - pr_devel("hcall failed: 0x%lx\n", ret); - goto out; -@@ -228,6 +242,7 @@ static int h_gpci_event_init(struct perf_event *event) - { - u64 count; - u8 length; -+ unsigned long ret; - - /* Not our event */ - if (event->attr.type != event->pmu->type) -@@ -258,13 +273,23 @@ static int h_gpci_event_init(struct perf_event *event) - } - - /* check if the request works... */ -- if (single_gpci_request(event_get_request(event), -+ ret = single_gpci_request(event_get_request(event), - event_get_starting_index(event), - event_get_secondary_index(event), - event_get_counter_info_version(event), - event_get_offset(event), - length, -- &count)) { -+ &count); -+ -+ /* -+ * ret value as H_AUTHORITY implies that partition is not permitted to retrieve -+ * performance information, and required to set -+ * "Enable Performance Information Collection" option. -+ */ -+ if (ret == H_AUTHORITY) -+ return -EPERM; -+ -+ if (ret) { - pr_devel("gpci hcall failed\n"); - return -EINVAL; - } -diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c -index 1830e1ac1f8f0..107a8b60ad0c9 100644 ---- a/arch/powerpc/platforms/embedded6xx/linkstation.c -+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c -@@ -99,9 +99,6 @@ static void __init linkstation_init_IRQ(void) - mpic_init(mpic); - } - --extern void avr_uart_configure(void); --extern void avr_uart_send(const char); -- - static void __noreturn linkstation_restart(char *cmd) - { - local_irq_disable(); -diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h -index 5ad12023e5628..ebc258fa4858d 100644 ---- a/arch/powerpc/platforms/embedded6xx/mpc10x.h -+++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h -@@ -156,4 +156,7 @@ int mpc10x_disable_store_gathering(struct pci_controller *hose); - /* For MPC107 boards that use the built-in openpic */ - void mpc10x_set_openpic(void); - -+void avr_uart_configure(void); -+void avr_uart_send(const char c); -+ - #endif /* __PPC_KERNEL_MPC10X_H */ -diff --git a/arch/powerpc/platforms/pseries/papr_platform_attributes.c b/arch/powerpc/platforms/pseries/papr_platform_attributes.c -index 526c621b098be..eea2041b270b5 100644 ---- a/arch/powerpc/platforms/pseries/papr_platform_attributes.c -+++ b/arch/powerpc/platforms/pseries/papr_platform_attributes.c -@@ -101,10 +101,12 @@ static int papr_get_attr(u64 id, struct energy_scale_attribute *esi) - esi_buf_size = ESI_HDR_SIZE + (CURR_MAX_ESI_ATTRS * max_esi_attrs); - - temp_buf = krealloc(buf, esi_buf_size, GFP_KERNEL); -- if (temp_buf) -+ if (temp_buf) { - buf = temp_buf; -- else -- return -ENOMEM; -+ } else { -+ ret = -ENOMEM; -+ goto out_buf; -+ } - - goto retry; - } -diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -index 07387f9c135ca..72b87b08ab444 100644 ---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -@@ -123,6 +123,7 @@ pmic@58 { - interrupt-parent = <&gpio>; - interrupts = <1 IRQ_TYPE_LEVEL_LOW>; - interrupt-controller; -+ #interrupt-cells = <2>; - - onkey { - compatible = "dlg,da9063-onkey"; -diff --git a/arch/s390/include/uapi/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h -index 93d1ccd3304c7..9c49c3d67cd56 100644 ---- a/arch/s390/include/uapi/asm/dasd.h -+++ b/arch/s390/include/uapi/asm/dasd.h -@@ -78,6 +78,7 @@ typedef struct dasd_information2_t { - * 0x040: give access to raw eckd data - * 0x080: enable discard support - * 0x100: enable autodisable for IFCC errors (default) -+ * 0x200: enable requeue of all requests on autoquiesce - */ - #define DASD_FEATURE_READONLY 0x001 - #define DASD_FEATURE_USEDIAG 0x002 -@@ -88,6 +89,7 @@ typedef struct dasd_information2_t { - #define DASD_FEATURE_USERAW 0x040 - #define DASD_FEATURE_DISCARD 0x080 - #define DASD_FEATURE_PATH_AUTODISABLE 0x100 -+#define DASD_FEATURE_REQUEUEQUIESCE 0x200 - #define DASD_FEATURE_DEFAULT DASD_FEATURE_PATH_AUTODISABLE - - #define DASD_PARTN_BITS 2 -diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c -index 7ee3651d00abe..732024ca005ad 100644 ---- a/arch/s390/kernel/cache.c -+++ b/arch/s390/kernel/cache.c -@@ -166,5 +166,6 @@ int populate_cache_leaves(unsigned int cpu) - ci_leaf_init(this_leaf++, pvt, ctype, level, cpu); - } - } -+ this_cpu_ci->cpu_map_populated = true; - return 0; - } -diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c -index 6826e2a69a216..f61a652046cfb 100644 ---- a/arch/s390/kernel/perf_pai_crypto.c -+++ b/arch/s390/kernel/perf_pai_crypto.c -@@ -647,7 +647,7 @@ static int __init attr_event_init(void) - for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) { - ret = attr_event_init_one(attrs, i); - if (ret) { -- attr_event_free(attrs, i - 1); -+ attr_event_free(attrs, i); - return ret; - } - } -diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c -index 74b53c531e0cd..b4d89654183a2 100644 ---- a/arch/s390/kernel/perf_pai_ext.c -+++ b/arch/s390/kernel/perf_pai_ext.c -@@ -612,7 +612,7 @@ static int __init attr_event_init(void) - for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) { - ret = attr_event_init_one(attrs, i); - if (ret) { -- attr_event_free(attrs, i - 1); -+ attr_event_free(attrs, i); - return ret; - } - } -diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile -index 245bddfe9bc0e..cc513add48eb5 100644 ---- a/arch/s390/kernel/vdso32/Makefile -+++ b/arch/s390/kernel/vdso32/Makefile -@@ -22,7 +22,7 @@ KBUILD_AFLAGS_32 += -m31 -s - KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) - KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin - --LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \ -+LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \ - --hash-style=both --build-id=sha1 -melf_s390 -T - - $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) -diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile -index 1605ba45ac4c0..42d918d50a1ff 100644 ---- a/arch/s390/kernel/vdso64/Makefile -+++ b/arch/s390/kernel/vdso64/Makefile -@@ -26,7 +26,7 @@ KBUILD_AFLAGS_64 += -m64 -s - - KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) - KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin --ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \ -+ldflags-y := -shared -soname=linux-vdso64.so.1 \ - --hash-style=both --build-id=sha1 -T - - $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) -diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c -index 9436f3053b88c..003c926a0f4de 100644 ---- a/arch/s390/kernel/vtime.c -+++ b/arch/s390/kernel/vtime.c -@@ -210,13 +210,13 @@ void vtime_flush(struct task_struct *tsk) - virt_timer_expire(); - - steal = S390_lowcore.steal_timer; -- avg_steal = S390_lowcore.avg_steal_timer / 2; -+ avg_steal = S390_lowcore.avg_steal_timer; - if ((s64) steal > 0) { - S390_lowcore.steal_timer = 0; - account_steal_time(cputime_to_nsecs(steal)); - avg_steal += steal; - } -- S390_lowcore.avg_steal_timer = avg_steal; -+ S390_lowcore.avg_steal_timer = avg_steal / 2; - } - - static u64 vtime_delta(void) -diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c -index e6935d0ac1ec9..c32590bdd3120 100644 ---- a/arch/sparc/kernel/leon_pci_grpci1.c -+++ b/arch/sparc/kernel/leon_pci_grpci1.c -@@ -696,7 +696,7 @@ static int grpci1_of_probe(struct platform_device *ofdev) - return err; - } - --static const struct of_device_id grpci1_of_match[] __initconst = { -+static const struct of_device_id grpci1_of_match[] = { - { - .name = "GAISLER_PCIFBRG", - }, -diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c -index ca22f93d90454..dd06abc61657f 100644 ---- a/arch/sparc/kernel/leon_pci_grpci2.c -+++ b/arch/sparc/kernel/leon_pci_grpci2.c -@@ -887,7 +887,7 @@ static int grpci2_of_probe(struct platform_device *ofdev) - return err; - } - --static const struct of_device_id grpci2_of_match[] __initconst = { -+static const struct of_device_id grpci2_of_match[] = { - { - .name = "GAISLER_GRPCI2", - }, -diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c -index 04f4b96dec6df..fd091b9dd7067 100644 ---- a/arch/x86/events/amd/core.c -+++ b/arch/x86/events/amd/core.c -@@ -604,7 +604,6 @@ static void amd_pmu_cpu_dead(int cpu) - - kfree(cpuhw->lbr_sel); - cpuhw->lbr_sel = NULL; -- amd_pmu_cpu_reset(cpu); - - if (!x86_pmu.amd_nb_constraints) - return; -diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h -index ab60a71a8dcb9..472f0263dbc61 100644 ---- a/arch/x86/include/asm/vsyscall.h -+++ b/arch/x86/include/asm/vsyscall.h -@@ -4,6 +4,7 @@ - - #include - #include -+#include - - #ifdef CONFIG_X86_VSYSCALL_EMULATION - extern void map_vsyscall(void); -@@ -24,4 +25,13 @@ static inline bool emulate_vsyscall(unsigned long error_code, - } - #endif - -+/* -+ * The (legacy) vsyscall page is the long page in the kernel portion -+ * of the address space that has user-accessible permissions. -+ */ -+static inline bool is_vsyscall_vaddr(unsigned long vaddr) -+{ -+ return unlikely((vaddr & PAGE_MASK) == VSYSCALL_ADDR); -+} -+ - #endif /* _ASM_X86_VSYSCALL_H */ -diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c -index 8d8752b44f113..ff8f25faca3dd 100644 ---- a/arch/x86/kernel/acpi/cppc.c -+++ b/arch/x86/kernel/acpi/cppc.c -@@ -20,7 +20,7 @@ bool cpc_supported_by_cpu(void) - (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f))) - return true; - else if (boot_cpu_data.x86 == 0x17 && -- boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f) -+ boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f) - return true; - return boot_cpu_has(X86_FEATURE_CPPC); - } -diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h -index 0b5c6c76f6f7b..4761d489a117a 100644 ---- a/arch/x86/kernel/cpu/resctrl/internal.h -+++ b/arch/x86/kernel/cpu/resctrl/internal.h -@@ -281,14 +281,10 @@ struct rftype { - * struct mbm_state - status for each MBM counter in each domain - * @prev_bw_bytes: Previous bytes value read for bandwidth calculation - * @prev_bw: The most recent bandwidth in MBps -- * @delta_bw: Difference between the current and previous bandwidth -- * @delta_comp: Indicates whether to compute the delta_bw - */ - struct mbm_state { - u64 prev_bw_bytes; - u32 prev_bw; -- u32 delta_bw; -- bool delta_comp; - }; - - /** -diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c -index 77538abeb72af..b9adb707750c6 100644 ---- a/arch/x86/kernel/cpu/resctrl/monitor.c -+++ b/arch/x86/kernel/cpu/resctrl/monitor.c -@@ -428,9 +428,6 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr) - - cur_bw = bytes / SZ_1M; - -- if (m->delta_comp) -- m->delta_bw = abs(cur_bw - m->prev_bw); -- m->delta_comp = false; - m->prev_bw = cur_bw; - } - -@@ -508,11 +505,11 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) - { - u32 closid, rmid, cur_msr_val, new_msr_val; - struct mbm_state *pmbm_data, *cmbm_data; -- u32 cur_bw, delta_bw, user_bw; - struct rdt_resource *r_mba; - struct rdt_domain *dom_mba; - struct list_head *head; - struct rdtgroup *entry; -+ u32 cur_bw, user_bw; - - if (!is_mbm_local_enabled()) - return; -@@ -531,7 +528,6 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) - - cur_bw = pmbm_data->prev_bw; - user_bw = dom_mba->mbps_val[closid]; -- delta_bw = pmbm_data->delta_bw; - - /* MBA resource doesn't support CDP */ - cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE); -@@ -543,49 +539,31 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) - list_for_each_entry(entry, head, mon.crdtgrp_list) { - cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid]; - cur_bw += cmbm_data->prev_bw; -- delta_bw += cmbm_data->delta_bw; - } - - /* - * Scale up/down the bandwidth linearly for the ctrl group. The - * bandwidth step is the bandwidth granularity specified by the - * hardware. -- * -- * The delta_bw is used when increasing the bandwidth so that we -- * dont alternately increase and decrease the control values -- * continuously. -- * -- * For ex: consider cur_bw = 90MBps, user_bw = 100MBps and if -- * bandwidth step is 20MBps(> user_bw - cur_bw), we would keep -- * switching between 90 and 110 continuously if we only check -- * cur_bw < user_bw. -+ * Always increase throttling if current bandwidth is above the -+ * target set by user. -+ * But avoid thrashing up and down on every poll by checking -+ * whether a decrease in throttling is likely to push the group -+ * back over target. E.g. if currently throttling to 30% of bandwidth -+ * on a system with 10% granularity steps, check whether moving to -+ * 40% would go past the limit by multiplying current bandwidth by -+ * "(30 + 10) / 30". - */ - if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) { - new_msr_val = cur_msr_val - r_mba->membw.bw_gran; - } else if (cur_msr_val < MAX_MBA_BW && -- (user_bw > (cur_bw + delta_bw))) { -+ (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) { - new_msr_val = cur_msr_val + r_mba->membw.bw_gran; - } else { - return; - } - - resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val); -- -- /* -- * Delta values are updated dynamically package wise for each -- * rdtgrp every time the throttle MSR changes value. -- * -- * This is because (1)the increase in bandwidth is not perfectly -- * linear and only "approximately" linear even when the hardware -- * says it is linear.(2)Also since MBA is a core specific -- * mechanism, the delta values vary based on number of cores used -- * by the rdtgrp. -- */ -- pmbm_data->delta_comp = true; -- list_for_each_entry(entry, head, mon.crdtgrp_list) { -- cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid]; -- cmbm_data->delta_comp = true; -- } - } - - static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid) -diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c -index 1dbbad73192a1..f20636510eb1e 100644 ---- a/arch/x86/mm/fault.c -+++ b/arch/x86/mm/fault.c -@@ -818,15 +818,6 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, - show_opcodes(regs, loglvl); - } - --/* -- * The (legacy) vsyscall page is the long page in the kernel portion -- * of the address space that has user-accessible permissions. -- */ --static bool is_vsyscall_vaddr(unsigned long vaddr) --{ -- return unlikely((vaddr & PAGE_MASK) == VSYSCALL_ADDR); --} -- - static void - __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, - unsigned long address, u32 pkey, int si_code) -diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c -index 6993f026adec9..42115ac079cfe 100644 ---- a/arch/x86/mm/maccess.c -+++ b/arch/x86/mm/maccess.c -@@ -3,6 +3,8 @@ - #include - #include - -+#include -+ - #ifdef CONFIG_X86_64 - bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) - { -@@ -15,6 +17,14 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) - if (vaddr < TASK_SIZE_MAX + PAGE_SIZE) - return false; - -+ /* -+ * Reading from the vsyscall page may cause an unhandled fault in -+ * certain cases. Though it is at an address above TASK_SIZE_MAX, it is -+ * usually considered as a user space address. -+ */ -+ if (is_vsyscall_vaddr(vaddr)) -+ return false; -+ - /* - * Allow everything during early boot before 'x86_virt_bits' - * is initialized. Needed for instruction decoding in early -diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c -index d94ebd8acdfde..a11a6ebbf5ecf 100644 ---- a/arch/x86/mm/mem_encrypt_identity.c -+++ b/arch/x86/mm/mem_encrypt_identity.c -@@ -507,7 +507,6 @@ void __init sme_enable(struct boot_params *bp) - const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off; - unsigned int eax, ebx, ecx, edx; - unsigned long feature_mask; -- bool active_by_default; - unsigned long me_mask; - char buffer[16]; - bool snp; -@@ -593,22 +592,19 @@ void __init sme_enable(struct boot_params *bp) - : "p" (sme_cmdline_off)); - - if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT)) -- active_by_default = true; -- else -- active_by_default = false; -+ sme_me_mask = me_mask; - - cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr | - ((u64)bp->ext_cmd_line_ptr << 32)); - - if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0) -- return; -+ goto out; - - if (!strncmp(buffer, cmdline_on, sizeof(buffer))) - sme_me_mask = me_mask; - else if (!strncmp(buffer, cmdline_off, sizeof(buffer))) - sme_me_mask = 0; -- else -- sme_me_mask = active_by_default ? me_mask : 0; -+ - out: - if (sme_me_mask) { - physical_mask &= ~sme_me_mask; -diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c -index 2925074b9a588..9a5b101c45023 100644 ---- a/arch/x86/tools/relocs.c -+++ b/arch/x86/tools/relocs.c -@@ -653,6 +653,14 @@ static void print_absolute_relocs(void) - if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { - continue; - } -+ /* -+ * Do not perform relocations in .notes section; any -+ * values there are meant for pre-boot consumption (e.g. -+ * startup_xen). -+ */ -+ if (sec_applies->shdr.sh_type == SHT_NOTE) { -+ continue; -+ } - sh_symtab = sec_symtab->symtab; - sym_strtab = sec_symtab->link->strtab; - for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { -diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c -index 4b0d6fff88de5..1fb9a1644d944 100644 ---- a/arch/x86/xen/smp.c -+++ b/arch/x86/xen/smp.c -@@ -65,6 +65,8 @@ int xen_smp_intr_init(unsigned int cpu) - char *resched_name, *callfunc_name, *debug_name; - - resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu); -+ if (!resched_name) -+ goto fail_mem; - per_cpu(xen_resched_irq, cpu).name = resched_name; - rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, - cpu, -@@ -77,6 +79,8 @@ int xen_smp_intr_init(unsigned int cpu) - per_cpu(xen_resched_irq, cpu).irq = rc; - - callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu); -+ if (!callfunc_name) -+ goto fail_mem; - per_cpu(xen_callfunc_irq, cpu).name = callfunc_name; - rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR, - cpu, -@@ -90,6 +94,9 @@ int xen_smp_intr_init(unsigned int cpu) - - if (!xen_fifo_events) { - debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); -+ if (!debug_name) -+ goto fail_mem; -+ - per_cpu(xen_debug_irq, cpu).name = debug_name; - rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, - xen_debug_interrupt, -@@ -101,6 +108,9 @@ int xen_smp_intr_init(unsigned int cpu) - } - - callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu); -+ if (!callfunc_name) -+ goto fail_mem; -+ - per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name; - rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR, - cpu, -@@ -114,6 +124,8 @@ int xen_smp_intr_init(unsigned int cpu) - - return 0; - -+ fail_mem: -+ rc = -ENOMEM; - fail: - xen_smp_intr_free(cpu); - return rc; -diff --git a/block/opal_proto.h b/block/opal_proto.h -index 7152aa1f1a49e..7f306b08a0fe7 100644 ---- a/block/opal_proto.h -+++ b/block/opal_proto.h -@@ -71,6 +71,7 @@ enum opal_response_token { - #define SHORT_ATOM_BYTE 0xBF - #define MEDIUM_ATOM_BYTE 0xDF - #define LONG_ATOM_BYTE 0xE3 -+#define EMPTY_ATOM_BYTE 0xFF - - #define OPAL_INVAL_PARAM 12 - #define OPAL_MANUFACTURED_INACTIVE 0x08 -diff --git a/block/sed-opal.c b/block/sed-opal.c -index 9bdb833e5817d..25e4ce452c1d3 100644 ---- a/block/sed-opal.c -+++ b/block/sed-opal.c -@@ -935,16 +935,20 @@ static int response_parse(const u8 *buf, size_t length, - token_length = response_parse_medium(iter, pos); - else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */ - token_length = response_parse_long(iter, pos); -+ else if (pos[0] == EMPTY_ATOM_BYTE) /* empty atom */ -+ token_length = 1; - else /* TOKEN */ - token_length = response_parse_token(iter, pos); - - if (token_length < 0) - return token_length; - -+ if (pos[0] != EMPTY_ATOM_BYTE) -+ num_entries++; -+ - pos += token_length; - total -= token_length; - iter++; -- num_entries++; - } - - resp->num = num_entries; -diff --git a/crypto/Kconfig b/crypto/Kconfig -index d779667671b23..edf193aff23e7 100644 ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -1285,10 +1285,11 @@ config CRYPTO_JITTERENTROPY - - A non-physical non-deterministic ("true") RNG (e.g., an entropy source - compliant with NIST SP800-90B) intended to provide a seed to a -- deterministic RNG (e.g. per NIST SP800-90C). -+ deterministic RNG (e.g., per NIST SP800-90C). - This RNG does not perform any cryptographic whitening of the generated -+ random numbers. - -- See https://www.chronox.de/jent.html -+ See https://www.chronox.de/jent/ - - config CRYPTO_KDF800108_CTR - tristate -diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c -index fc5b5b2c9e819..6f613eef28879 100644 ---- a/drivers/acpi/processor_idle.c -+++ b/drivers/acpi/processor_idle.c -@@ -1431,6 +1431,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr) - acpi_processor_registered--; - if (acpi_processor_registered == 0) - cpuidle_unregister_driver(&acpi_idle_driver); -+ -+ kfree(dev); - } - - pr->flags.power_setup_done = 0; -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index 5ebeb0d7b6be0..1c5c1a269fbee 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -543,6 +543,39 @@ static const struct dmi_system_id lg_laptop[] = { - DMI_MATCH(DMI_BOARD_NAME, "17U70P"), - }, - }, -+ { -+ /* Infinity E15-5A165-BM */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "GM5RG1E0009COM"), -+ }, -+ }, -+ { -+ /* Infinity E15-5A305-1M */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"), -+ }, -+ }, -+ { -+ /* Lunnen Ground 15 / AMD Ryzen 5 5500U */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"), -+ DMI_MATCH(DMI_BOARD_NAME, "LLL5DAW"), -+ }, -+ }, -+ { -+ /* Lunnen Ground 16 / AMD Ryzen 7 5800U */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"), -+ DMI_MATCH(DMI_BOARD_NAME, "LL6FA"), -+ }, -+ }, -+ { -+ /* MAIBENBEN X577 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"), -+ DMI_MATCH(DMI_BOARD_NAME, "X577"), -+ }, -+ }, - { } - }; - -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 94154a849a3ea..293cdf486fd81 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -315,18 +315,14 @@ static int acpi_scan_device_check(struct acpi_device *adev) - * again). - */ - if (adev->handler) { -- dev_warn(&adev->dev, "Already enumerated\n"); -- return -EALREADY; -+ dev_dbg(&adev->dev, "Already enumerated\n"); -+ return 0; - } - error = acpi_bus_scan(adev->handle); - if (error) { - dev_warn(&adev->dev, "Namespace scan failure\n"); - return error; - } -- if (!adev->handler) { -- dev_warn(&adev->dev, "Enumeration failure\n"); -- error = -ENODEV; -- } - } else { - error = acpi_scan_device_not_present(adev); - } -diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c -index d7317425be510..cc9077b588d7e 100644 ---- a/drivers/block/aoe/aoecmd.c -+++ b/drivers/block/aoe/aoecmd.c -@@ -419,13 +419,16 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu - rcu_read_lock(); - for_each_netdev_rcu(&init_net, ifp) { - dev_hold(ifp); -- if (!is_aoe_netif(ifp)) -- goto cont; -+ if (!is_aoe_netif(ifp)) { -+ dev_put(ifp); -+ continue; -+ } - - skb = new_skb(sizeof *h + sizeof *ch); - if (skb == NULL) { - printk(KERN_INFO "aoe: skb alloc failure\n"); -- goto cont; -+ dev_put(ifp); -+ continue; - } - skb_put(skb, sizeof *h + sizeof *ch); - skb->dev = ifp; -@@ -440,9 +443,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu - h->major = cpu_to_be16(aoemajor); - h->minor = aoeminor; - h->cmd = AOECMD_CFG; -- --cont: -- dev_put(ifp); - } - rcu_read_unlock(); - } -diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c -index 63773a90581dd..1e66c7a188a12 100644 ---- a/drivers/block/aoe/aoenet.c -+++ b/drivers/block/aoe/aoenet.c -@@ -64,6 +64,7 @@ tx(int id) __must_hold(&txlock) - pr_warn("aoe: packet could not be sent on %s. %s\n", - ifp ? ifp->name : "netif", - "consider increasing tx_queue_len"); -+ dev_put(ifp); - spin_lock_irq(&txlock); - } - return 0; -diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c -index 9a53165de4cef..5c4be8dda253c 100644 ---- a/drivers/block/nbd.c -+++ b/drivers/block/nbd.c -@@ -2408,6 +2408,12 @@ static int nbd_genl_status(struct sk_buff *skb, struct genl_info *info) - } - - dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST); -+ if (!dev_list) { -+ nlmsg_free(reply); -+ ret = -EMSGSIZE; -+ goto out; -+ } -+ - if (index == -1) { - ret = idr_for_each(&nbd_index_idr, &status_cb, reply); - if (ret) { -diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c -index 8bfef7f81b417..2acda547f4f3e 100644 ---- a/drivers/bluetooth/hci_qca.c -+++ b/drivers/bluetooth/hci_qca.c -@@ -2254,7 +2254,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) - - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); -- if (IS_ERR_OR_NULL(qcadev->bt_en) && -+ if (IS_ERR(qcadev->bt_en) && - (data->soc_type == QCA_WCN6750 || - data->soc_type == QCA_WCN6855)) { - dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); -@@ -2263,7 +2263,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) - - qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", - GPIOD_IN); -- if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && -+ if (IS_ERR(qcadev->sw_ctrl) && - (data->soc_type == QCA_WCN6750 || - data->soc_type == QCA_WCN6855 || - data->soc_type == QCA_WCN7850)) -@@ -2285,7 +2285,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) - default: - qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", - GPIOD_OUT_LOW); -- if (IS_ERR_OR_NULL(qcadev->bt_en)) { -+ if (IS_ERR(qcadev->bt_en)) { - dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); - power_ctrl_enabled = false; - } -diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig -index 7bfe998f3514a..bdc7633905504 100644 ---- a/drivers/bus/Kconfig -+++ b/drivers/bus/Kconfig -@@ -186,11 +186,12 @@ config SUNXI_RSB - - config TEGRA_ACONNECT - tristate "Tegra ACONNECT Bus Driver" -- depends on ARCH_TEGRA_210_SOC -+ depends on ARCH_TEGRA - depends on OF && PM - help - Driver for the Tegra ACONNECT bus which is used to interface with -- the devices inside the Audio Processing Engine (APE) for Tegra210. -+ the devices inside the Audio Processing Engine (APE) for -+ Tegra210 and later. - - config TEGRA_GMI - tristate "Tegra Generic Memory Interface bus driver" -diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c -index 33fedbd096f33..9004e07182259 100644 ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -407,6 +407,9 @@ static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index) - if (IS_ERR(hw)) - return ERR_CAST(hw); - -+ if (!hw) -+ return NULL; -+ - return hw->core; - } - -diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c -index ad0c7f350cf03..60d8a27a90824 100644 ---- a/drivers/clk/hisilicon/clk-hi3519.c -+++ b/drivers/clk/hisilicon/clk-hi3519.c -@@ -130,7 +130,7 @@ static void hi3519_clk_unregister(struct platform_device *pdev) - of_clk_del_provider(pdev->dev.of_node); - - hisi_clk_unregister_gate(hi3519_gate_clks, -- ARRAY_SIZE(hi3519_mux_clks), -+ ARRAY_SIZE(hi3519_gate_clks), - crg->clk_data); - hisi_clk_unregister_mux(hi3519_mux_clks, - ARRAY_SIZE(hi3519_mux_clks), -diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c -index 9ea1a80acbe8b..0272276550ff1 100644 ---- a/drivers/clk/hisilicon/clk-hi3559a.c -+++ b/drivers/clk/hisilicon/clk-hi3559a.c -@@ -491,7 +491,6 @@ static void hisi_clk_register_pll(struct hi3559av100_pll_clock *clks, - - clk = clk_register(NULL, &p_clk->hw); - if (IS_ERR(clk)) { -- devm_kfree(dev, p_clk); - dev_err(dev, "%s: failed to register clock %s\n", - __func__, clks[i].name); - continue; -diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c -index 2ad3801398dc1..7802dabb26f6d 100644 ---- a/drivers/clk/meson/axg.c -+++ b/drivers/clk/meson/axg.c -@@ -2144,7 +2144,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = { - &axg_vclk_input, - &axg_vclk2_input, - &axg_vclk_div, -+ &axg_vclk_div1, - &axg_vclk2_div, -+ &axg_vclk2_div1, - &axg_vclk_div2_en, - &axg_vclk_div4_en, - &axg_vclk_div6_en, -diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c -index 735adfefc3798..e792e0b130d33 100644 ---- a/drivers/clk/qcom/dispcc-sdm845.c -+++ b/drivers/clk/qcom/dispcc-sdm845.c -@@ -759,6 +759,8 @@ static struct clk_branch disp_cc_mdss_vsync_clk = { - - static struct gdsc mdss_gdsc = { - .gdscr = 0x3000, -+ .en_few_wait_val = 0x6, -+ .en_rest_wait_val = 0x5, - .pd = { - .name = "mdss_gdsc", - }, -diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c -index e45e32804d2c7..d96c96a9089f4 100644 ---- a/drivers/clk/qcom/reset.c -+++ b/drivers/clk/qcom/reset.c -@@ -22,8 +22,8 @@ static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) - return 0; - } - --static int --qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) -+static int qcom_reset_set_assert(struct reset_controller_dev *rcdev, -+ unsigned long id, bool assert) - { - struct qcom_reset_controller *rst; - const struct qcom_reset_map *map; -@@ -33,21 +33,22 @@ qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) - map = &rst->reset_map[id]; - mask = map->bitmask ? map->bitmask : BIT(map->bit); - -- return regmap_update_bits(rst->regmap, map->reg, mask, mask); -+ regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0); -+ -+ /* Read back the register to ensure write completion, ignore the value */ -+ regmap_read(rst->regmap, map->reg, &mask); -+ -+ return 0; - } - --static int --qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) -+static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) - { -- struct qcom_reset_controller *rst; -- const struct qcom_reset_map *map; -- u32 mask; -- -- rst = to_qcom_reset_controller(rcdev); -- map = &rst->reset_map[id]; -- mask = map->bitmask ? map->bitmask : BIT(map->bit); -+ return qcom_reset_set_assert(rcdev, id, true); -+} - -- return regmap_update_bits(rst->regmap, map->reg, mask, 0); -+static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) -+{ -+ return qcom_reset_set_assert(rcdev, id, false); - } - - const struct reset_control_ops qcom_reset_ops = { -diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c -index 27b668def357f..7a49b91c93710 100644 ---- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c -+++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c -@@ -159,7 +159,7 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = { - DEF_MOD("cmt1", 911, R8A779F0_CLK_R), - DEF_MOD("cmt2", 912, R8A779F0_CLK_R), - DEF_MOD("cmt3", 913, R8A779F0_CLK_R), -- DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M), -+ DEF_MOD("pfc0", 915, R8A779F0_CLK_CPEX), - DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M), - DEF_MOD("ufs", 1514, R8A779F0_CLK_S0D4_HSC), - }; -diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c -index d5b325e3c5398..e4c616921e5ea 100644 ---- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c -+++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c -@@ -22,7 +22,7 @@ - - enum clk_ids { - /* Core Clock Outputs exported to DT */ -- LAST_DT_CORE_CLK = R8A779G0_CLK_R, -+ LAST_DT_CORE_CLK = R8A779G0_CLK_CP, - - /* External Input Clocks */ - CLK_EXTAL, -@@ -139,6 +139,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = { - DEF_FIXED("svd2_vip", R8A779G0_CLK_SVD2_VIP, CLK_SV_VIP, 2, 1), - DEF_FIXED("cbfusa", R8A779G0_CLK_CBFUSA, CLK_EXTAL, 2, 1), - DEF_FIXED("cpex", R8A779G0_CLK_CPEX, CLK_EXTAL, 2, 1), -+ DEF_FIXED("cp", R8A779G0_CLK_CP, CLK_EXTAL, 2, 1), - DEF_FIXED("viobus", R8A779G0_CLK_VIOBUS, CLK_VIO, 1, 1), - DEF_FIXED("viobusd2", R8A779G0_CLK_VIOBUSD2, CLK_VIO, 2, 1), - DEF_FIXED("vcbus", R8A779G0_CLK_VCBUS, CLK_VC, 1, 1), -@@ -169,10 +170,17 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = { - DEF_MOD("i2c4", 522, R8A779G0_CLK_S0D6_PER), - DEF_MOD("i2c5", 523, R8A779G0_CLK_S0D6_PER), - DEF_MOD("wdt1:wdt0", 907, R8A779G0_CLK_R), -- DEF_MOD("pfc0", 915, R8A779G0_CLK_CL16M), -- DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M), -- DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M), -- DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M), -+ DEF_MOD("cmt0", 910, R8A779G0_CLK_R), -+ DEF_MOD("cmt1", 911, R8A779G0_CLK_R), -+ DEF_MOD("cmt2", 912, R8A779G0_CLK_R), -+ DEF_MOD("cmt3", 913, R8A779G0_CLK_R), -+ DEF_MOD("pfc0", 915, R8A779G0_CLK_CP), -+ DEF_MOD("pfc1", 916, R8A779G0_CLK_CP), -+ DEF_MOD("pfc2", 917, R8A779G0_CLK_CP), -+ DEF_MOD("pfc3", 918, R8A779G0_CLK_CP), -+ DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M), -+ DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER), -+ DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER), - }; - - /* -diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c -index 541761e96aeb6..87e463ad42741 100644 ---- a/drivers/clk/samsung/clk-exynos850.c -+++ b/drivers/clk/samsung/clk-exynos850.c -@@ -572,7 +572,7 @@ static const struct samsung_div_clock apm_div_clks[] __initconst = { - - static const struct samsung_gate_clock apm_gate_clks[] __initconst = { - GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus", -- CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0), -+ CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, CLK_SET_RATE_PARENT, 0), - GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus", - "mout_clkcmu_chub_bus", - CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0), -@@ -936,19 +936,19 @@ static const struct samsung_fixed_rate_clock cmgp_fixed_clks[] __initconst = { - static const struct samsung_mux_clock cmgp_mux_clks[] __initconst = { - MUX(CLK_MOUT_CMGP_ADC, "mout_cmgp_adc", mout_cmgp_adc_p, - CLK_CON_MUX_CLK_CMGP_ADC, 0, 1), -- MUX(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p, -- CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1), -- MUX(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p, -- CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1), -+ MUX_F(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p, -+ CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1, CLK_SET_RATE_PARENT, 0), -+ MUX_F(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p, -+ CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1, CLK_SET_RATE_PARENT, 0), - }; - - static const struct samsung_div_clock cmgp_div_clks[] __initconst = { - DIV(CLK_DOUT_CMGP_ADC, "dout_cmgp_adc", "gout_clkcmu_cmgp_bus", - CLK_CON_DIV_DIV_CLK_CMGP_ADC, 0, 4), -- DIV(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0", -- CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5), -- DIV(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1", -- CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5), -+ DIV_F(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0", -+ CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5, CLK_SET_RATE_PARENT, 0), -+ DIV_F(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1", -+ CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5, CLK_SET_RATE_PARENT, 0), - }; - - static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = { -@@ -963,12 +963,12 @@ static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = { - "gout_clkcmu_cmgp_bus", - CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(CLK_GOUT_CMGP_USI0_IPCLK, "gout_cmgp_usi0_ipclk", "dout_cmgp_usi0", -- CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, 0, 0), -+ CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, CLK_SET_RATE_PARENT, 0), - GATE(CLK_GOUT_CMGP_USI0_PCLK, "gout_cmgp_usi0_pclk", - "gout_clkcmu_cmgp_bus", - CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK, 21, 0, 0), - GATE(CLK_GOUT_CMGP_USI1_IPCLK, "gout_cmgp_usi1_ipclk", "dout_cmgp_usi1", -- CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, 0, 0), -+ CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, CLK_SET_RATE_PARENT, 0), - GATE(CLK_GOUT_CMGP_USI1_PCLK, "gout_cmgp_usi1_pclk", - "gout_clkcmu_cmgp_bus", - CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK, 21, 0, 0), -@@ -1409,8 +1409,9 @@ static const struct samsung_mux_clock peri_mux_clks[] __initconst = { - mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1), - MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user", - mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1), -- MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p, -- PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1), -+ MUX_F(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", -+ mout_peri_spi_user_p, PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1, -+ CLK_SET_RATE_PARENT, 0), - }; - - static const struct samsung_div_clock peri_div_clks[] __initconst = { -@@ -1420,8 +1421,8 @@ static const struct samsung_div_clock peri_div_clks[] __initconst = { - CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5), - DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2", - CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5), -- DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", -- CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5), -+ DIV_F(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", -+ CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5, CLK_SET_RATE_PARENT, 0), - }; - - static const struct samsung_gate_clock peri_gate_clks[] __initconst = { -@@ -1463,7 +1464,7 @@ static const struct samsung_gate_clock peri_gate_clks[] __initconst = { - "mout_peri_bus_user", - CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0), - GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0", -- CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0), -+ CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, CLK_SET_RATE_PARENT, 0), - GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user", - CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0), - GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk", -diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c -index 7bdeaff2bfd68..c28d3dacf0fb2 100644 ---- a/drivers/clk/zynq/clkc.c -+++ b/drivers/clk/zynq/clkc.c -@@ -42,6 +42,7 @@ static void __iomem *zynq_clkc_base; - #define SLCR_SWDT_CLK_SEL (zynq_clkc_base + 0x204) - - #define NUM_MIO_PINS 54 -+#define CLK_NAME_LEN 16 - - #define DBG_CLK_CTRL_CLKACT_TRC BIT(0) - #define DBG_CLK_CTRL_CPU_1XCLKACT BIT(1) -@@ -215,7 +216,7 @@ static void __init zynq_clk_setup(struct device_node *np) - int i; - u32 tmp; - int ret; -- char *clk_name; -+ char clk_name[CLK_NAME_LEN]; - unsigned int fclk_enable = 0; - const char *clk_output_name[clk_max]; - const char *cpu_parents[4]; -@@ -426,12 +427,10 @@ static void __init zynq_clk_setup(struct device_node *np) - "gem1_emio_mux", CLK_SET_RATE_PARENT, - SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); - -- tmp = strlen("mio_clk_00x"); -- clk_name = kmalloc(tmp, GFP_KERNEL); - for (i = 0; i < NUM_MIO_PINS; i++) { - int idx; - -- snprintf(clk_name, tmp, "mio_clk_%2.2d", i); -+ snprintf(clk_name, CLK_NAME_LEN, "mio_clk_%2.2d", i); - idx = of_property_match_string(np, "clock-names", clk_name); - if (idx >= 0) - can_mio_mux_parents[i] = of_clk_get_parent_name(np, -@@ -439,7 +438,6 @@ static void __init zynq_clk_setup(struct device_node *np) - else - can_mio_mux_parents[i] = dummy_nm; - } -- kfree(clk_name); - clk_register_mux(NULL, "can_mux", periph_parents, 4, - CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0, - &canclk_lock); -diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c -index 0b5c0af1cebf0..626d53bf9146a 100644 ---- a/drivers/comedi/drivers/comedi_test.c -+++ b/drivers/comedi/drivers/comedi_test.c -@@ -85,6 +85,8 @@ struct waveform_private { - struct comedi_device *dev; /* parent comedi device */ - u64 ao_last_scan_time; /* time of previous AO scan in usec */ - unsigned int ao_scan_period; /* AO scan period in usec */ -+ bool ai_timer_enable:1; /* should AI timer be running? */ -+ bool ao_timer_enable:1; /* should AO timer be running? */ - unsigned short ao_loopbacks[N_CHANS]; - }; - -@@ -234,8 +236,12 @@ static void waveform_ai_timer(struct timer_list *t) - time_increment = devpriv->ai_convert_time - now; - else - time_increment = 1; -- mod_timer(&devpriv->ai_timer, -- jiffies + usecs_to_jiffies(time_increment)); -+ spin_lock(&dev->spinlock); -+ if (devpriv->ai_timer_enable) { -+ mod_timer(&devpriv->ai_timer, -+ jiffies + usecs_to_jiffies(time_increment)); -+ } -+ spin_unlock(&dev->spinlock); - } - - overrun: -@@ -391,9 +397,12 @@ static int waveform_ai_cmd(struct comedi_device *dev, - * Seem to need an extra jiffy here, otherwise timer expires slightly - * early! - */ -+ spin_lock_bh(&dev->spinlock); -+ devpriv->ai_timer_enable = true; - devpriv->ai_timer.expires = - jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; - add_timer(&devpriv->ai_timer); -+ spin_unlock_bh(&dev->spinlock); - return 0; - } - -@@ -402,6 +411,9 @@ static int waveform_ai_cancel(struct comedi_device *dev, - { - struct waveform_private *devpriv = dev->private; - -+ spin_lock_bh(&dev->spinlock); -+ devpriv->ai_timer_enable = false; -+ spin_unlock_bh(&dev->spinlock); - if (in_softirq()) { - /* Assume we were called from the timer routine itself. */ - del_timer(&devpriv->ai_timer); -@@ -493,8 +505,12 @@ static void waveform_ao_timer(struct timer_list *t) - unsigned int time_inc = devpriv->ao_last_scan_time + - devpriv->ao_scan_period - now; - -- mod_timer(&devpriv->ao_timer, -- jiffies + usecs_to_jiffies(time_inc)); -+ spin_lock(&dev->spinlock); -+ if (devpriv->ao_timer_enable) { -+ mod_timer(&devpriv->ao_timer, -+ jiffies + usecs_to_jiffies(time_inc)); -+ } -+ spin_unlock(&dev->spinlock); - } - - underrun: -@@ -515,9 +531,12 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev, - async->inttrig = NULL; - - devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); -+ spin_lock_bh(&dev->spinlock); -+ devpriv->ao_timer_enable = true; - devpriv->ao_timer.expires = - jiffies + usecs_to_jiffies(devpriv->ao_scan_period); - add_timer(&devpriv->ao_timer); -+ spin_unlock_bh(&dev->spinlock); - - return 1; - } -@@ -602,6 +621,9 @@ static int waveform_ao_cancel(struct comedi_device *dev, - struct waveform_private *devpriv = dev->private; - - s->async->inttrig = NULL; -+ spin_lock_bh(&dev->spinlock); -+ devpriv->ao_timer_enable = false; -+ spin_unlock_bh(&dev->spinlock); - if (in_softirq()) { - /* Assume we were called from the timer routine itself. */ - del_timer(&devpriv->ao_timer); -diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c -index b74289a95a171..bea41ccabf1f0 100644 ---- a/drivers/cpufreq/armada-37xx-cpufreq.c -+++ b/drivers/cpufreq/armada-37xx-cpufreq.c -@@ -14,10 +14,8 @@ - #include - #include - #include -+#include - #include --#include --#include --#include - #include - #include - #include -diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c -index f644c5e325fb2..38ec0fedb247f 100644 ---- a/drivers/cpufreq/brcmstb-avs-cpufreq.c -+++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c -@@ -481,6 +481,8 @@ static bool brcm_avs_is_firmware_loaded(struct private_data *priv) - static unsigned int brcm_avs_cpufreq_get(unsigned int cpu) - { - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); -+ if (!policy) -+ return 0; - struct private_data *priv = policy->driver_data; - - cpufreq_cpu_put(policy); -diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c -index f0e0a35c7f217..7f326bb5fd8de 100644 ---- a/drivers/cpufreq/mediatek-cpufreq-hw.c -+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c -@@ -10,8 +10,10 @@ - #include - #include - #include --#include -+#include - #include -+#include -+#include - #include - - #define LUT_MAX_ENTRIES 32U -@@ -295,7 +297,23 @@ static struct cpufreq_driver cpufreq_mtk_hw_driver = { - static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev) - { - const void *data; -- int ret; -+ int ret, cpu; -+ struct device *cpu_dev; -+ struct regulator *cpu_reg; -+ -+ /* Make sure that all CPU supplies are available before proceeding. */ -+ for_each_possible_cpu(cpu) { -+ cpu_dev = get_cpu_device(cpu); -+ if (!cpu_dev) -+ return dev_err_probe(&pdev->dev, -EPROBE_DEFER, -+ "Failed to get cpu%d device\n", cpu); -+ -+ cpu_reg = devm_regulator_get(cpu_dev, "cpu"); -+ if (IS_ERR(cpu_reg)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg), -+ "CPU%d regulator get failed\n", cpu); -+ } -+ - - data = of_device_get_match_data(&pdev->dev); - if (!data) -diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c -index e3313ce63b388..88afc49941b71 100644 ---- a/drivers/cpufreq/ppc_cbe_cpufreq.c -+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c -@@ -9,7 +9,7 @@ - - #include - #include --#include -+#include - - #include - #include -diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c -index 4fba3637b115c..6f0c32592416d 100644 ---- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c -+++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c -@@ -11,7 +11,6 @@ - #include - #include - #include --#include - #include - #include - -diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c -index a577586b23be2..cb03bfb0435ea 100644 ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -22,7 +22,6 @@ - #include - #include - #include --#include - #include - #include - #include -diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c -index fd2c16821d54c..ac719aca49b75 100644 ---- a/drivers/cpufreq/scpi-cpufreq.c -+++ b/drivers/cpufreq/scpi-cpufreq.c -@@ -14,7 +14,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -diff --git a/drivers/cpufreq/sti-cpufreq.c b/drivers/cpufreq/sti-cpufreq.c -index 1a63aeea87112..9c542e723a157 100644 ---- a/drivers/cpufreq/sti-cpufreq.c -+++ b/drivers/cpufreq/sti-cpufreq.c -@@ -13,7 +13,7 @@ - #include - #include - #include --#include -+#include - #include - #include - -diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c -index f64180dd2005b..61ef653bcf56f 100644 ---- a/drivers/cpufreq/ti-cpufreq.c -+++ b/drivers/cpufreq/ti-cpufreq.c -@@ -12,7 +12,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c -index d295f405c4bb0..865e501648034 100644 ---- a/drivers/cpufreq/vexpress-spc-cpufreq.c -+++ b/drivers/cpufreq/vexpress-spc-cpufreq.c -@@ -18,7 +18,6 @@ - #include - #include - #include --#include - #include - #include - #include -diff --git a/drivers/crypto/xilinx/zynqmp-aes-gcm.c b/drivers/crypto/xilinx/zynqmp-aes-gcm.c -index bf1f421e05f25..74bd3eb63734d 100644 ---- a/drivers/crypto/xilinx/zynqmp-aes-gcm.c -+++ b/drivers/crypto/xilinx/zynqmp-aes-gcm.c -@@ -231,7 +231,10 @@ static int zynqmp_handle_aes_req(struct crypto_engine *engine, - err = zynqmp_aes_aead_cipher(areq); - } - -+ local_bh_disable(); - crypto_finalize_aead_request(engine, areq, err); -+ local_bh_enable(); -+ - return 0; - } - -diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index 81de833ccd041..66ef0a1114845 100644 ---- a/drivers/dma/Kconfig -+++ b/drivers/dma/Kconfig -@@ -665,16 +665,16 @@ config TEGRA20_APB_DMA - - config TEGRA210_ADMA - tristate "NVIDIA Tegra210 ADMA support" -- depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST) -+ depends on (ARCH_TEGRA || COMPILE_TEST) - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - help -- Support for the NVIDIA Tegra210 ADMA controller driver. The -- DMA controller has multiple DMA channels and is used to service -- various audio clients in the Tegra210 audio processing engine -- (APE). This DMA controller transfers data from memory to -- peripheral and vice versa. It does not support memory to -- memory data transfer. -+ Support for the NVIDIA Tegra210/Tegra186/Tegra194/Tegra234 ADMA -+ controller driver. The DMA controller has multiple DMA channels -+ and is used to service various audio clients in the Tegra210 -+ audio processing engine (APE). This DMA controller transfers -+ data from memory to peripheral and vice versa. It does not -+ support memory to memory data transfer. - - config TIMB_DMA - tristate "Timberdale FPGA DMA support" -diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c -index 8aaa7fcb2630d..401a77e3b5fa8 100644 ---- a/drivers/firewire/core-card.c -+++ b/drivers/firewire/core-card.c -@@ -500,7 +500,19 @@ static void bm_work(struct work_struct *work) - fw_notice(card, "phy config: new root=%x, gap_count=%d\n", - new_root_id, gap_count); - fw_send_phy_config(card, new_root_id, generation, gap_count); -- reset_bus(card, true); -+ /* -+ * Where possible, use a short bus reset to minimize -+ * disruption to isochronous transfers. But in the event -+ * of a gap count inconsistency, use a long bus reset. -+ * -+ * As noted in 1394a 8.4.6.2, nodes on a mixed 1394/1394a bus -+ * may set different gap counts after a bus reset. On a mixed -+ * 1394/1394a bus, a short bus reset can get doubled. Some -+ * nodes may treat the double reset as one bus reset and others -+ * may treat it as two, causing a gap count inconsistency -+ * again. Using a long bus reset prevents this. -+ */ -+ reset_bus(card, card->gap_count != 0); - /* Will allocate broadcast channel after the reset. */ - goto out; - } -diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c -index ac0bd51ef16a2..42ea308a2c1d5 100644 ---- a/drivers/firmware/arm_scmi/smc.c -+++ b/drivers/firmware/arm_scmi/smc.c -@@ -171,6 +171,13 @@ static int smc_chan_free(int id, void *p, void *data) - struct scmi_chan_info *cinfo = p; - struct scmi_smc *scmi_info = cinfo->transport_info; - -+ /* -+ * Different protocols might share the same chan info, so a previous -+ * smc_chan_free call might have already freed the structure. -+ */ -+ if (!scmi_info) -+ return 0; -+ - /* Ignore any possible further reception on the IRQ path */ - if (scmi_info->irq > 0) - free_irq(scmi_info->irq, scmi_info); -diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c -index 784e1b2ae5ccd..dc50dda40239e 100644 ---- a/drivers/firmware/efi/libstub/x86-stub.c -+++ b/drivers/firmware/efi/libstub/x86-stub.c -@@ -21,6 +21,8 @@ - #include "efistub.h" - #include "x86-stub.h" - -+extern char _bss[], _ebss[]; -+ - const efi_system_table_t *efi_system_table; - const efi_dxe_services_table_t *efi_dxe_table; - static efi_loaded_image_t *image = NULL; -@@ -432,6 +434,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, - efi_status_t status; - char *cmdline_ptr; - -+ if (efi_is_native()) -+ memset(_bss, 0, _ebss - _bss); -+ - efi_system_table = sys_table_arg; - - /* Check if we were booted by the EFI firmware */ -@@ -950,8 +955,6 @@ void __noreturn efi_stub_entry(efi_handle_t handle, - void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, - struct boot_params *boot_params) - { -- extern char _bss[], _ebss[]; -- - memset(_bss, 0, _ebss - _bss); - efi_stub_entry(handle, sys_table_arg, boot_params); - } -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index 3e8e5f4ffa59f..700f71c954956 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -679,7 +679,8 @@ config GPIO_UNIPHIER - Say yes here to support UniPhier GPIOs. - - config GPIO_VF610 -- def_bool y -+ bool "VF610 GPIO support" -+ default y if SOC_VF610 - depends on ARCH_MXC - select GPIOLIB_IRQCHIP - help -diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c -index 1c5d9388ad0bb..cb6eb47aab65b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/atom.c -+++ b/drivers/gpu/drm/amd/amdgpu/atom.c -@@ -313,7 +313,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, - DEBUG("IMM 0x%02X\n", val); - return val; - } -- return 0; -+ break; - case ATOM_ARG_PLL: - idx = U8(*ptr); - (*ptr)++; -diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c -index 489c89465c78b..c373a2a3248eb 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc15.c -+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c -@@ -584,11 +584,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev) - return AMD_RESET_METHOD_MODE1; - } - -+static bool soc15_need_reset_on_resume(struct amdgpu_device *adev) -+{ -+ u32 sol_reg; -+ -+ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); -+ -+ /* Will reset for the following suspend abort cases. -+ * 1) Only reset limit on APU side, dGPU hasn't checked yet. -+ * 2) S3 suspend abort and TOS already launched. -+ */ -+ if (adev->flags & AMD_IS_APU && adev->in_s3 && -+ !adev->suspend_complete && -+ sol_reg) -+ return true; -+ -+ return false; -+} -+ - static int soc15_asic_reset(struct amdgpu_device *adev) - { - /* original raven doesn't have full asic reset */ -- if ((adev->apu_flags & AMD_APU_IS_RAVEN) || -- (adev->apu_flags & AMD_APU_IS_RAVEN2)) -+ /* On the latest Raven, the GPU reset can be performed -+ * successfully. So now, temporarily enable it for the -+ * S3 suspend abort case. -+ */ -+ if (((adev->apu_flags & AMD_APU_IS_RAVEN) || -+ (adev->apu_flags & AMD_APU_IS_RAVEN2)) && -+ !soc15_need_reset_on_resume(adev)) - return 0; - - switch (soc15_asic_reset_method(adev)) { -@@ -1285,24 +1308,6 @@ static int soc15_common_suspend(void *handle) - return soc15_common_hw_fini(adev); - } - --static bool soc15_need_reset_on_resume(struct amdgpu_device *adev) --{ -- u32 sol_reg; -- -- sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); -- -- /* Will reset for the following suspend abort cases. -- * 1) Only reset limit on APU side, dGPU hasn't checked yet. -- * 2) S3 suspend abort and TOS already launched. -- */ -- if (adev->flags & AMD_IS_APU && adev->in_s3 && -- !adev->suspend_complete && -- sol_reg) -- return true; -- -- return false; --} -- - static int soc15_common_resume(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -index ee242d9d8b060..ff7dd17ad0763 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -@@ -1358,7 +1358,7 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, - const uint32_t rd_buf_size = 10; - struct pipe_ctx *pipe_ctx; - ssize_t result = 0; -- int i, r, str_len = 30; -+ int i, r, str_len = 10; - - rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -index 009b5861a3fec..d6c5d48c878ec 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -@@ -1854,6 +1854,9 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, - { - struct dpp *dpp = pipe_ctx->plane_res.dpp; - -+ if (!stream) -+ return false; -+ - if (dpp == NULL) - return false; - -@@ -1876,8 +1879,8 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, - } else - dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS); - -- if (stream != NULL && stream->ctx != NULL && -- stream->out_transfer_func != NULL) { -+ if (stream->ctx && -+ stream->out_transfer_func) { - log_tf(stream->ctx, - stream->out_transfer_func, - dpp->regamma_params.hw_points_num); -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -index 0f1ca0b0db495..d72c5bf4e5ac1 100644 ---- a/drivers/gpu/drm/lima/lima_gem.c -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -75,29 +75,34 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) - } else { - bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); - if (!bo->base.sgt) { -- sg_free_table(&sgt); -- return -ENOMEM; -+ ret = -ENOMEM; -+ goto err_out0; - } - } - - ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); -- if (ret) { -- sg_free_table(&sgt); -- kfree(bo->base.sgt); -- bo->base.sgt = NULL; -- return ret; -- } -+ if (ret) -+ goto err_out1; - - *bo->base.sgt = sgt; - - if (vm) { - ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); - if (ret) -- return ret; -+ goto err_out2; - } - - bo->heap_size = new_size; - return 0; -+ -+err_out2: -+ dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); -+err_out1: -+ kfree(bo->base.sgt); -+ bo->base.sgt = NULL; -+err_out0: -+ sg_free_table(&sgt); -+ return ret; - } - - int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -index 558000db4a100..beaaf44004cfd 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -@@ -91,11 +91,13 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) - struct drm_crtc *crtc = &mtk_crtc->base; - unsigned long flags; - -- spin_lock_irqsave(&crtc->dev->event_lock, flags); -- drm_crtc_send_vblank_event(crtc, mtk_crtc->event); -- drm_crtc_vblank_put(crtc); -- mtk_crtc->event = NULL; -- spin_unlock_irqrestore(&crtc->dev->event_lock, flags); -+ if (mtk_crtc->event) { -+ spin_lock_irqsave(&crtc->dev->event_lock, flags); -+ drm_crtc_send_vblank_event(crtc, mtk_crtc->event); -+ drm_crtc_vblank_put(crtc); -+ mtk_crtc->event = NULL; -+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); -+ } - } - - static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) -diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c -index 3e74c7c1b89fa..d871b1dba083d 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dsi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c -@@ -70,8 +70,8 @@ - #define DSI_PS_WC 0x3fff - #define DSI_PS_SEL (3 << 16) - #define PACKED_PS_16BIT_RGB565 (0 << 16) --#define LOOSELY_PS_18BIT_RGB666 (1 << 16) --#define PACKED_PS_18BIT_RGB666 (2 << 16) -+#define PACKED_PS_18BIT_RGB666 (1 << 16) -+#define LOOSELY_PS_24BIT_RGB666 (2 << 16) - #define PACKED_PS_24BIT_RGB888 (3 << 16) - - #define DSI_VSA_NL 0x20 -@@ -366,10 +366,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi) - ps_bpp_mode |= PACKED_PS_24BIT_RGB888; - break; - case MIPI_DSI_FMT_RGB666: -- ps_bpp_mode |= PACKED_PS_18BIT_RGB666; -+ ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB666_PACKED: -- ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666; -+ ps_bpp_mode |= PACKED_PS_18BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB565: - ps_bpp_mode |= PACKED_PS_16BIT_RGB565; -@@ -423,7 +423,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi) - dsi_tmp_buf_bpp = 3; - break; - case MIPI_DSI_FMT_RGB666: -- tmp_reg = LOOSELY_PS_18BIT_RGB666; -+ tmp_reg = LOOSELY_PS_24BIT_RGB666; - dsi_tmp_buf_bpp = 3; - break; - case MIPI_DSI_FMT_RGB666_PACKED: -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -index 25245ef386db6..3632f0768aa9e 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -@@ -228,6 +228,13 @@ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc) - return dpu_enc->wide_bus_en; - } - -+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc) -+{ -+ const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); -+ -+ return dpu_enc->dsc ? true : false; -+} -+ - int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc) - { - struct dpu_encoder_virt *dpu_enc; -@@ -1864,7 +1871,9 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, - dsc_common_mode = 0; - pic_width = dsc->pic_width; - -- dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; -+ dsc_common_mode = DSC_MODE_SPLIT_PANEL; -+ if (dpu_encoder_use_dsc_merge(enc_master->parent)) -+ dsc_common_mode |= DSC_MODE_MULTIPLEX; - if (enc_master->intf_mode == INTF_MODE_VIDEO) - dsc_common_mode |= DSC_MODE_VIDEO; - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h -index 9e7236ef34e6d..a71efa2b9e508 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h -@@ -175,6 +175,13 @@ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc); - - bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc); - -+/** -+ * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled -+ * for the encoder. -+ * @drm_enc: Pointer to previously created drm encoder structure -+ */ -+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc); -+ - /** - * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained - * in virtual encoder that can collect CRC values -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -index 2c14646661b77..2baade1cd4876 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c -@@ -100,6 +100,7 @@ static void drm_mode_to_intf_timing_params( - } - - timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); -+ timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); - - /* - * for DP, divide the horizonal parameters by 2 when -@@ -256,12 +257,14 @@ static void dpu_encoder_phys_vid_setup_timing_engine( - mode.htotal >>= 1; - mode.hsync_start >>= 1; - mode.hsync_end >>= 1; -+ mode.hskew >>= 1; - - DPU_DEBUG_VIDENC(phys_enc, -- "split_role %d, halve horizontal %d %d %d %d\n", -+ "split_role %d, halve horizontal %d %d %d %d %d\n", - phys_enc->split_role, - mode.hdisplay, mode.htotal, -- mode.hsync_start, mode.hsync_end); -+ mode.hsync_start, mode.hsync_end, -+ mode.hskew); - } - - drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params); -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -index 384558d2f9602..1debac4fcc3eb 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -@@ -154,13 +154,8 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, - hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width; - display_hctl = (hsync_end_x << 16) | hsync_start_x; - -- /* -- * DATA_HCTL_EN controls data timing which can be different from -- * video timing. It is recommended to enable it for all cases, except -- * if compression is enabled in 1 pixel per clock mode -- */ - if (p->wide_bus_en) -- intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN; -+ intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; - - data_width = p->width; - -@@ -230,6 +225,14 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, - DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg); - DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format); - if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) { -+ /* -+ * DATA_HCTL_EN controls data timing which can be different from -+ * video timing. It is recommended to enable it for all cases, except -+ * if compression is enabled in 1 pixel per clock mode -+ */ -+ if (!(p->compression_en && !p->wide_bus_en)) -+ intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN; -+ - DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2); - DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl); - DPU_REG_WRITE(c, INTF_ACTIVE_DATA_HCTL, active_data_hctl); -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -index e75339b96a1d2..7f502c8bee1d4 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -@@ -33,6 +33,7 @@ struct intf_timing_params { - u32 hsync_skew; - - bool wide_bus_en; -+ bool compression_en; - }; - - struct intf_prog_fetch { -diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c -index 126b3c6e12f99..f2dca41e46c5f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_bo.c -+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c -@@ -1194,6 +1194,8 @@ nouveau_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *reg) - drm_vma_node_unmap(&nvbo->bo.base.vma_node, - bdev->dev_mapping); - nouveau_ttm_io_mem_free_locked(drm, nvbo->bo.resource); -+ nvbo->bo.resource->bus.offset = 0; -+ nvbo->bo.resource->bus.addr = NULL; - goto retry; - } - -diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c -index 42584d8a9aeb6..bfcddd4aa9322 100644 ---- a/drivers/gpu/drm/panel/panel-edp.c -+++ b/drivers/gpu/drm/panel/panel-edp.c -@@ -413,8 +413,7 @@ static int panel_edp_unprepare(struct drm_panel *panel) - if (!p->prepared) - return 0; - -- pm_runtime_mark_last_busy(panel->dev); -- ret = pm_runtime_put_autosuspend(panel->dev); -+ ret = pm_runtime_put_sync_suspend(panel->dev); - if (ret < 0) - return ret; - p->prepared = false; -diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c -index 927e5f42e97d0..3e48cbb522a1c 100644 ---- a/drivers/gpu/drm/radeon/ni.c -+++ b/drivers/gpu/drm/radeon/ni.c -@@ -813,7 +813,7 @@ int ni_init_microcode(struct radeon_device *rdev) - err = 0; - } else if (rdev->smc_fw->size != smc_req_size) { - pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n", -- rdev->mc_fw->size, fw_name); -+ rdev->smc_fw->size, fw_name); - err = -EINVAL; - } - } -diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c -index f51774866f412..8f230f4c01bc3 100644 ---- a/drivers/gpu/drm/rockchip/inno_hdmi.c -+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c -@@ -411,7 +411,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - -- value = mode->hsync_start - mode->hdisplay; -+ value = mode->htotal - mode->hsync_start; - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); - -@@ -426,7 +426,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, - value = mode->vtotal - mode->vdisplay; - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); - -- value = mode->vsync_start - mode->vdisplay; -+ value = mode->vtotal - mode->vsync_start; - hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); - - value = mode->vsync_end - mode->vsync_start; -diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c -index 68f6ebb33460b..eb4a108c5bd2a 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_lvds.c -+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c -@@ -577,8 +577,7 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master, - ret = -EINVAL; - goto err_put_port; - } else if (ret) { -- DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); -- ret = -EPROBE_DEFER; -+ dev_err_probe(dev, ret, "failed to find panel and bridge node\n"); - goto err_put_port; - } - if (lvds->panel) -diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c -index d773ef4854188..b563988fb6848 100644 ---- a/drivers/gpu/drm/tegra/dpaux.c -+++ b/drivers/gpu/drm/tegra/dpaux.c -@@ -524,7 +524,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev) - if (err < 0) { - dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n", - dpaux->irq, err); -- return err; -+ goto err_pm_disable; - } - - disable_irq(dpaux->irq); -@@ -544,7 +544,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev) - */ - err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C); - if (err < 0) -- return err; -+ goto err_pm_disable; - - #ifdef CONFIG_GENERIC_PINCONF - dpaux->desc.name = dev_name(&pdev->dev); -@@ -557,7 +557,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev) - dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux); - if (IS_ERR(dpaux->pinctrl)) { - dev_err(&pdev->dev, "failed to register pincontrol\n"); -- return PTR_ERR(dpaux->pinctrl); -+ err = PTR_ERR(dpaux->pinctrl); -+ goto err_pm_disable; - } - #endif - /* enable and clear all interrupts */ -@@ -573,10 +574,15 @@ static int tegra_dpaux_probe(struct platform_device *pdev) - err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux); - if (err < 0) { - dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err); -- return err; -+ goto err_pm_disable; - } - - return 0; -+ -+err_pm_disable: -+ pm_runtime_put_sync(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ return err; - } - - static int tegra_dpaux_remove(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c -index de1333dc0d867..7bb26655cb3cc 100644 ---- a/drivers/gpu/drm/tegra/dsi.c -+++ b/drivers/gpu/drm/tegra/dsi.c -@@ -1534,9 +1534,11 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) - np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0); - if (np) { - struct platform_device *gangster = of_find_device_by_node(np); -+ of_node_put(np); -+ if (!gangster) -+ return -EPROBE_DEFER; - - dsi->slave = platform_get_drvdata(gangster); -- of_node_put(np); - - if (!dsi->slave) { - put_device(&gangster->dev); -@@ -1584,48 +1586,58 @@ static int tegra_dsi_probe(struct platform_device *pdev) - - if (!pdev->dev.pm_domain) { - dsi->rst = devm_reset_control_get(&pdev->dev, "dsi"); -- if (IS_ERR(dsi->rst)) -- return PTR_ERR(dsi->rst); -+ if (IS_ERR(dsi->rst)) { -+ err = PTR_ERR(dsi->rst); -+ goto remove; -+ } - } - - dsi->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dsi->clk)) { -- dev_err(&pdev->dev, "cannot get DSI clock\n"); -- return PTR_ERR(dsi->clk); -+ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk), -+ "cannot get DSI clock\n"); -+ goto remove; - } - - dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); - if (IS_ERR(dsi->clk_lp)) { -- dev_err(&pdev->dev, "cannot get low-power clock\n"); -- return PTR_ERR(dsi->clk_lp); -+ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp), -+ "cannot get low-power clock\n"); -+ goto remove; - } - - dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); - if (IS_ERR(dsi->clk_parent)) { -- dev_err(&pdev->dev, "cannot get parent clock\n"); -- return PTR_ERR(dsi->clk_parent); -+ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent), -+ "cannot get parent clock\n"); -+ goto remove; - } - - dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); - if (IS_ERR(dsi->vdd)) { -- dev_err(&pdev->dev, "cannot get VDD supply\n"); -- return PTR_ERR(dsi->vdd); -+ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd), -+ "cannot get VDD supply\n"); -+ goto remove; - } - - err = tegra_dsi_setup_clocks(dsi); - if (err < 0) { - dev_err(&pdev->dev, "cannot setup clocks\n"); -- return err; -+ goto remove; - } - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dsi->regs = devm_ioremap_resource(&pdev->dev, regs); -- if (IS_ERR(dsi->regs)) -- return PTR_ERR(dsi->regs); -+ if (IS_ERR(dsi->regs)) { -+ err = PTR_ERR(dsi->regs); -+ goto remove; -+ } - - dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node); -- if (IS_ERR(dsi->mipi)) -- return PTR_ERR(dsi->mipi); -+ if (IS_ERR(dsi->mipi)) { -+ err = PTR_ERR(dsi->mipi); -+ goto remove; -+ } - - dsi->host.ops = &tegra_dsi_host_ops; - dsi->host.dev = &pdev->dev; -@@ -1653,9 +1665,12 @@ static int tegra_dsi_probe(struct platform_device *pdev) - return 0; - - unregister: -+ pm_runtime_disable(&pdev->dev); - mipi_dsi_host_unregister(&dsi->host); - mipi_free: - tegra_mipi_free(dsi->mipi); -+remove: -+ tegra_output_remove(&dsi->output); - return err; - } - -diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c -index 9291209154a7a..a688ecf08451e 100644 ---- a/drivers/gpu/drm/tegra/fb.c -+++ b/drivers/gpu/drm/tegra/fb.c -@@ -166,6 +166,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, - - if (gem->size < size) { - err = -EINVAL; -+ drm_gem_object_put(gem); - goto unreference; - } - -diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c -index bf240767dad9f..c66764c0bd250 100644 ---- a/drivers/gpu/drm/tegra/hdmi.c -+++ b/drivers/gpu/drm/tegra/hdmi.c -@@ -1776,7 +1776,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data) - static int tegra_hdmi_probe(struct platform_device *pdev) - { - struct tegra_hdmi *hdmi; -- struct resource *regs; - int err; - - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -@@ -1838,14 +1837,15 @@ static int tegra_hdmi_probe(struct platform_device *pdev) - if (err < 0) - return err; - -- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- hdmi->regs = devm_ioremap_resource(&pdev->dev, regs); -- if (IS_ERR(hdmi->regs)) -- return PTR_ERR(hdmi->regs); -+ hdmi->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(hdmi->regs)) { -+ err = PTR_ERR(hdmi->regs); -+ goto remove; -+ } - - err = platform_get_irq(pdev, 0); - if (err < 0) -- return err; -+ goto remove; - - hdmi->irq = err; - -@@ -1854,18 +1854,18 @@ static int tegra_hdmi_probe(struct platform_device *pdev) - if (err < 0) { - dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", - hdmi->irq, err); -- return err; -+ goto remove; - } - - platform_set_drvdata(pdev, hdmi); - - err = devm_pm_runtime_enable(&pdev->dev); - if (err) -- return err; -+ goto remove; - - err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); - if (err) -- return err; -+ goto remove; - - INIT_LIST_HEAD(&hdmi->client.list); - hdmi->client.ops = &hdmi_client_ops; -@@ -1875,10 +1875,14 @@ static int tegra_hdmi_probe(struct platform_device *pdev) - if (err < 0) { - dev_err(&pdev->dev, "failed to register host1x client: %d\n", - err); -- return err; -+ goto remove; - } - - return 0; -+ -+remove: -+ tegra_output_remove(&hdmi->output); -+ return err; - } - - static int tegra_hdmi_remove(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c -index 47d26b5d99456..7ccd010a821b7 100644 ---- a/drivers/gpu/drm/tegra/output.c -+++ b/drivers/gpu/drm/tegra/output.c -@@ -139,8 +139,10 @@ int tegra_output_probe(struct tegra_output *output) - GPIOD_IN, - "HDMI hotplug detect"); - if (IS_ERR(output->hpd_gpio)) { -- if (PTR_ERR(output->hpd_gpio) != -ENOENT) -- return PTR_ERR(output->hpd_gpio); -+ if (PTR_ERR(output->hpd_gpio) != -ENOENT) { -+ err = PTR_ERR(output->hpd_gpio); -+ goto put_i2c; -+ } - - output->hpd_gpio = NULL; - } -@@ -149,7 +151,7 @@ int tegra_output_probe(struct tegra_output *output) - err = gpiod_to_irq(output->hpd_gpio); - if (err < 0) { - dev_err(output->dev, "gpiod_to_irq(): %d\n", err); -- return err; -+ goto put_i2c; - } - - output->hpd_irq = err; -@@ -162,7 +164,7 @@ int tegra_output_probe(struct tegra_output *output) - if (err < 0) { - dev_err(output->dev, "failed to request IRQ#%u: %d\n", - output->hpd_irq, err); -- return err; -+ goto put_i2c; - } - - output->connector.polled = DRM_CONNECTOR_POLL_HPD; -@@ -176,6 +178,12 @@ int tegra_output_probe(struct tegra_output *output) - } - - return 0; -+ -+put_i2c: -+ if (output->ddc) -+ i2c_put_adapter(output->ddc); -+ -+ return err; - } - - void tegra_output_remove(struct tegra_output *output) -diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c -index ff8fce36d2aa1..86e55e5d12b39 100644 ---- a/drivers/gpu/drm/tegra/rgb.c -+++ b/drivers/gpu/drm/tegra/rgb.c -@@ -214,26 +214,28 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) - rgb->clk = devm_clk_get(dc->dev, NULL); - if (IS_ERR(rgb->clk)) { - dev_err(dc->dev, "failed to get clock\n"); -- return PTR_ERR(rgb->clk); -+ err = PTR_ERR(rgb->clk); -+ goto remove; - } - - rgb->clk_parent = devm_clk_get(dc->dev, "parent"); - if (IS_ERR(rgb->clk_parent)) { - dev_err(dc->dev, "failed to get parent clock\n"); -- return PTR_ERR(rgb->clk_parent); -+ err = PTR_ERR(rgb->clk_parent); -+ goto remove; - } - - err = clk_set_parent(rgb->clk, rgb->clk_parent); - if (err < 0) { - dev_err(dc->dev, "failed to set parent clock: %d\n", err); -- return err; -+ goto remove; - } - - rgb->pll_d_out0 = clk_get_sys(NULL, "pll_d_out0"); - if (IS_ERR(rgb->pll_d_out0)) { - err = PTR_ERR(rgb->pll_d_out0); - dev_err(dc->dev, "failed to get pll_d_out0: %d\n", err); -- return err; -+ goto remove; - } - - if (dc->soc->has_pll_d2_out0) { -@@ -241,13 +243,19 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) - if (IS_ERR(rgb->pll_d2_out0)) { - err = PTR_ERR(rgb->pll_d2_out0); - dev_err(dc->dev, "failed to get pll_d2_out0: %d\n", err); -- return err; -+ goto put_pll; - } - } - - dc->rgb = &rgb->output; - - return 0; -+ -+put_pll: -+ clk_put(rgb->pll_d_out0); -+remove: -+ tegra_output_remove(&rgb->output); -+ return err; - } - - int tegra_dc_rgb_remove(struct tegra_dc *dc) -diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c -index cb66a425dd200..896a77853ebc5 100644 ---- a/drivers/gpu/drm/tidss/tidss_crtc.c -+++ b/drivers/gpu/drm/tidss/tidss_crtc.c -@@ -270,6 +270,16 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, - - reinit_completion(&tcrtc->framedone_completion); - -+ /* -+ * If a layer is left enabled when the videoport is disabled, and the -+ * vid pipeline that was used for the layer is taken into use on -+ * another videoport, the DSS will report sync lost issues. Disable all -+ * the layers here as a work-around. -+ */ -+ for (u32 layer = 0; layer < tidss->feat->num_planes; layer++) -+ dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer, -+ false); -+ - dispc_vp_disable(tidss->dispc, tcrtc->hw_videoport); - - if (!wait_for_completion_timeout(&tcrtc->framedone_completion, -diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c -index 42d50ec5526d7..435b3b66ae632 100644 ---- a/drivers/gpu/drm/tidss/tidss_plane.c -+++ b/drivers/gpu/drm/tidss/tidss_plane.c -@@ -211,7 +211,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss, - - drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs); - -- drm_plane_create_zpos_property(&tplane->plane, hw_plane_id, 0, -+ drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0, - num_planes - 1); - - ret = drm_plane_create_color_properties(&tplane->plane, -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c -index 60e3cc537f365..b9e5c8cd31001 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c -@@ -65,8 +65,11 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man, - ttm_resource_init(bo, place, *res); - - id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL); -- if (id < 0) -+ if (id < 0) { -+ ttm_resource_fini(man, *res); -+ kfree(*res); - return id; -+ } - - spin_lock(&gman->lock); - -diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -index c936d6a51c0cd..9c963ad27f9d1 100644 ---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -@@ -34,6 +34,8 @@ static int sensor_mask_override = -1; - module_param_named(sensor_mask, sensor_mask_override, int, 0444); - MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask"); - -+static bool intr_disable = true; -+ - static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts) - { - union cmd_response cmd_resp; -@@ -54,7 +56,7 @@ static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sen - - cmd_base.ul = 0; - cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR; -- cmd_base.cmd_v2.intr_disable = 1; -+ cmd_base.cmd_v2.intr_disable = intr_disable; - cmd_base.cmd_v2.period = info.period; - cmd_base.cmd_v2.sensor_id = info.sensor_idx; - cmd_base.cmd_v2.length = 16; -@@ -72,7 +74,7 @@ static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx) - - cmd_base.ul = 0; - cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR; -- cmd_base.cmd_v2.intr_disable = 1; -+ cmd_base.cmd_v2.intr_disable = intr_disable; - cmd_base.cmd_v2.period = 0; - cmd_base.cmd_v2.sensor_id = sensor_idx; - cmd_base.cmd_v2.length = 16; -@@ -86,7 +88,7 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata) - union sfh_cmd_base cmd_base; - - cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS; -- cmd_base.cmd_v2.intr_disable = 1; -+ cmd_base.cmd_v2.intr_disable = intr_disable; - cmd_base.cmd_v2.period = 0; - cmd_base.cmd_v2.sensor_id = 0; - -@@ -288,6 +290,26 @@ int amd_sfh_irq_init(struct amd_mp2_dev *privdata) - return 0; - } - -+static int mp2_disable_intr(const struct dmi_system_id *id) -+{ -+ intr_disable = false; -+ return 0; -+} -+ -+static const struct dmi_system_id dmi_sfh_table[] = { -+ { -+ /* -+ * https://bugzilla.kernel.org/show_bug.cgi?id=218104 -+ */ -+ .callback = mp2_disable_intr, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "HP"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"), -+ }, -+ }, -+ {} -+}; -+ - static const struct dmi_system_id dmi_nodevs[] = { - { - /* -@@ -311,6 +333,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i - if (dmi_first_match(dmi_nodevs)) - return -ENODEV; - -+ dmi_check_system(dmi_sfh_table); -+ - privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL); - if (!privdata) - return -ENOMEM; -diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -index dfb7cabd82efe..2b125cd9742cb 100644 ---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -@@ -89,10 +89,10 @@ enum mem_use_type { - struct hpd_status { - union { - struct { -- u32 human_presence_report : 4; -- u32 human_presence_actual : 4; -- u32 probablity : 8; - u32 object_distance : 16; -+ u32 probablity : 8; -+ u32 human_presence_actual : 4; -+ u32 human_presence_report : 4; - } shpd; - u32 val; - }; -diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c -index 149a3c74346b4..f86c1ea83a037 100644 ---- a/drivers/hid/hid-lenovo.c -+++ b/drivers/hid/hid-lenovo.c -@@ -54,10 +54,10 @@ struct lenovo_drvdata { - /* 0: Up - * 1: Down (undecided) - * 2: Scrolling -- * 3: Patched firmware, disable workaround - */ - u8 middlebutton_state; - bool fn_lock; -+ bool middleclick_workaround_cptkbd; - }; - - #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) -@@ -621,6 +621,36 @@ static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, - return count; - } - -+static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct hid_device *hdev = to_hid_device(dev); -+ struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); -+ -+ return snprintf(buf, PAGE_SIZE, "%u\n", -+ cptkbd_data->middleclick_workaround_cptkbd); -+} -+ -+static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct hid_device *hdev = to_hid_device(dev); -+ struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); -+ int value; -+ -+ if (kstrtoint(buf, 10, &value)) -+ return -EINVAL; -+ if (value < 0 || value > 1) -+ return -EINVAL; -+ -+ cptkbd_data->middleclick_workaround_cptkbd = !!value; -+ -+ return count; -+} -+ - - static struct device_attribute dev_attr_fn_lock = - __ATTR(fn_lock, S_IWUSR | S_IRUGO, -@@ -632,10 +662,16 @@ static struct device_attribute dev_attr_sensitivity_cptkbd = - attr_sensitivity_show_cptkbd, - attr_sensitivity_store_cptkbd); - -+static struct device_attribute dev_attr_middleclick_workaround_cptkbd = -+ __ATTR(middleclick_workaround, S_IWUSR | S_IRUGO, -+ attr_middleclick_workaround_show_cptkbd, -+ attr_middleclick_workaround_store_cptkbd); -+ - - static struct attribute *lenovo_attributes_cptkbd[] = { - &dev_attr_fn_lock.attr, - &dev_attr_sensitivity_cptkbd.attr, -+ &dev_attr_middleclick_workaround_cptkbd.attr, - NULL - }; - -@@ -686,23 +722,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, - { - struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); - -- if (cptkbd_data->middlebutton_state != 3) { -- /* REL_X and REL_Y events during middle button pressed -- * are only possible on patched, bug-free firmware -- * so set middlebutton_state to 3 -- * to never apply workaround anymore -- */ -- if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && -- cptkbd_data->middlebutton_state == 1 && -- usage->type == EV_REL && -- (usage->code == REL_X || usage->code == REL_Y)) { -- cptkbd_data->middlebutton_state = 3; -- /* send middle button press which was hold before */ -- input_event(field->hidinput->input, -- EV_KEY, BTN_MIDDLE, 1); -- input_sync(field->hidinput->input); -- } -- -+ if (cptkbd_data->middleclick_workaround_cptkbd) { - /* "wheel" scroll events */ - if (usage->type == EV_REL && (usage->code == REL_WHEEL || - usage->code == REL_HWHEEL)) { -@@ -1166,6 +1186,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev) - cptkbd_data->middlebutton_state = 0; - cptkbd_data->fn_lock = true; - cptkbd_data->sensitivity = 0x05; -+ cptkbd_data->middleclick_workaround_cptkbd = true; - lenovo_features_set_cptkbd(hdev); - - ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index 5ec1f174127a3..3816fd06bc953 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -2153,6 +2153,10 @@ static const struct hid_device_id mt_devices[] = { - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, - -+ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, -+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, -+ USB_VENDOR_ID_SYNAPTICS, 0xcddc) }, -+ - { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_SYNAPTICS, 0xce08) }, -diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c -index 8d8fa8e8afe04..20a9cddb3723a 100644 ---- a/drivers/hwtracing/ptt/hisi_ptt.c -+++ b/drivers/hwtracing/ptt/hisi_ptt.c -@@ -654,6 +654,9 @@ static int hisi_ptt_pmu_event_init(struct perf_event *event) - int ret; - u32 val; - -+ if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) -+ return -ENOENT; -+ - if (event->cpu < 0) { - dev_dbg(event->pmu->dev, "Per-task mode not supported\n"); - return -EOPNOTSUPP; -@@ -662,9 +665,6 @@ static int hisi_ptt_pmu_event_init(struct perf_event *event) - if (event->attach_state & PERF_ATTACH_TASK) - return -EOPNOTSUPP; - -- if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) -- return -ENOENT; -- - ret = hisi_ptt_trace_valid_filter(hisi_ptt, event->attr.config); - if (ret < 0) - return ret; -diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c -index 3a9b9a28d858f..453188db39d83 100644 ---- a/drivers/infiniband/core/device.c -+++ b/drivers/infiniband/core/device.c -@@ -1730,7 +1730,7 @@ static int assign_client_id(struct ib_client *client) - { - int ret; - -- down_write(&clients_rwsem); -+ lockdep_assert_held(&clients_rwsem); - /* - * The add/remove callbacks must be called in FIFO/LIFO order. To - * achieve this we assign client_ids so they are sorted in -@@ -1739,14 +1739,11 @@ static int assign_client_id(struct ib_client *client) - client->client_id = highest_client_id; - ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL); - if (ret) -- goto out; -+ return ret; - - highest_client_id++; - xa_set_mark(&clients, client->client_id, CLIENT_REGISTERED); -- --out: -- up_write(&clients_rwsem); -- return ret; -+ return 0; - } - - static void remove_client_id(struct ib_client *client) -@@ -1776,25 +1773,35 @@ int ib_register_client(struct ib_client *client) - { - struct ib_device *device; - unsigned long index; -+ bool need_unreg = false; - int ret; - - refcount_set(&client->uses, 1); - init_completion(&client->uses_zero); -+ -+ /* -+ * The devices_rwsem is held in write mode to ensure that a racing -+ * ib_register_device() sees a consisent view of clients and devices. -+ */ -+ down_write(&devices_rwsem); -+ down_write(&clients_rwsem); - ret = assign_client_id(client); - if (ret) -- return ret; -+ goto out; - -- down_read(&devices_rwsem); -+ need_unreg = true; - xa_for_each_marked (&devices, index, device, DEVICE_REGISTERED) { - ret = add_client_context(device, client); -- if (ret) { -- up_read(&devices_rwsem); -- ib_unregister_client(client); -- return ret; -- } -+ if (ret) -+ goto out; - } -- up_read(&devices_rwsem); -- return 0; -+ ret = 0; -+out: -+ up_write(&clients_rwsem); -+ up_write(&devices_rwsem); -+ if (need_unreg && ret) -+ ib_unregister_client(client); -+ return ret; - } - EXPORT_SYMBOL(ib_register_client); - -diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h -index 1112afa0af552..8748b65c87ea7 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_device.h -+++ b/drivers/infiniband/hw/hns/hns_roce_device.h -@@ -595,6 +595,13 @@ struct hns_roce_work { - u32 queue_num; - }; - -+enum hns_roce_cong_type { -+ CONG_TYPE_DCQCN, -+ CONG_TYPE_LDCP, -+ CONG_TYPE_HC3, -+ CONG_TYPE_DIP, -+}; -+ - struct hns_roce_qp { - struct ib_qp ibqp; - struct hns_roce_wq rq; -@@ -639,6 +646,7 @@ struct hns_roce_qp { - struct list_head sq_node; /* all send qps are on a list */ - struct hns_user_mmap_entry *dwqe_mmap_entry; - u32 config; -+ enum hns_roce_cong_type cong_type; - }; - - struct hns_roce_ib_iboe { -@@ -710,13 +718,6 @@ struct hns_roce_eq_table { - struct hns_roce_eq *eq; - }; - --enum cong_type { -- CONG_TYPE_DCQCN, -- CONG_TYPE_LDCP, -- CONG_TYPE_HC3, -- CONG_TYPE_DIP, --}; -- - struct hns_roce_caps { - u64 fw_ver; - u8 num_ports; -@@ -847,7 +848,7 @@ struct hns_roce_caps { - u16 default_aeq_period; - u16 default_aeq_arm_st; - u16 default_ceq_arm_st; -- enum cong_type cong_type; -+ enum hns_roce_cong_type cong_type; - }; - - enum hns_roce_device_state { -diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -index 58fbb1d3b7f41..d06b19e69a151 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -@@ -4886,12 +4886,15 @@ static int check_cong_type(struct ib_qp *ibqp, - struct hns_roce_congestion_algorithm *cong_alg) - { - struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); -+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); - -- if (ibqp->qp_type == IB_QPT_UD) -- hr_dev->caps.cong_type = CONG_TYPE_DCQCN; -+ if (ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_GSI) -+ hr_qp->cong_type = CONG_TYPE_DCQCN; -+ else -+ hr_qp->cong_type = hr_dev->caps.cong_type; - - /* different congestion types match different configurations */ -- switch (hr_dev->caps.cong_type) { -+ switch (hr_qp->cong_type) { - case CONG_TYPE_DCQCN: - cong_alg->alg_sel = CONG_DCQCN; - cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; -@@ -4919,8 +4922,8 @@ static int check_cong_type(struct ib_qp *ibqp, - default: - ibdev_warn(&hr_dev->ib_dev, - "invalid type(%u) for congestion selection.\n", -- hr_dev->caps.cong_type); -- hr_dev->caps.cong_type = CONG_TYPE_DCQCN; -+ hr_qp->cong_type); -+ hr_qp->cong_type = CONG_TYPE_DCQCN; - cong_alg->alg_sel = CONG_DCQCN; - cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; - cong_alg->dip_vld = DIP_INVALID; -@@ -4939,6 +4942,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr, - struct hns_roce_congestion_algorithm cong_field; - struct ib_device *ibdev = ibqp->device; - struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); -+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); - u32 dip_idx = 0; - int ret; - -@@ -4951,7 +4955,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr, - return ret; - - hr_reg_write(context, QPC_CONG_ALGO_TMPL_ID, hr_dev->cong_algo_tmpl_id + -- hr_dev->caps.cong_type * HNS_ROCE_CONG_SIZE); -+ hr_qp->cong_type * HNS_ROCE_CONG_SIZE); - hr_reg_clear(qpc_mask, QPC_CONG_ALGO_TMPL_ID); - hr_reg_write(&context->ext, QPCEX_CONG_ALG_SEL, cong_field.alg_sel); - hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SEL); -diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c -index 280d633d4ec4f..d691cdef5e9a3 100644 ---- a/drivers/infiniband/hw/irdma/uk.c -+++ b/drivers/infiniband/hw/irdma/uk.c -@@ -1414,6 +1414,78 @@ static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp, - IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt); - } - -+/** -+ * irdma_uk_calc_shift_wq - calculate WQE shift for both SQ and RQ -+ * @ukinfo: qp initialization info -+ * @sq_shift: Returns shift of SQ -+ * @rq_shift: Returns shift of RQ -+ */ -+void irdma_uk_calc_shift_wq(struct irdma_qp_uk_init_info *ukinfo, u8 *sq_shift, -+ u8 *rq_shift) -+{ -+ bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2; -+ -+ irdma_get_wqe_shift(ukinfo->uk_attrs, -+ imm_support ? ukinfo->max_sq_frag_cnt + 1 : -+ ukinfo->max_sq_frag_cnt, -+ ukinfo->max_inline_data, sq_shift); -+ -+ irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0, -+ rq_shift); -+ -+ if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) { -+ if (ukinfo->abi_ver > 4) -+ *rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1; -+ } -+} -+ -+/** -+ * irdma_uk_calc_depth_shift_sq - calculate depth and shift for SQ size. -+ * @ukinfo: qp initialization info -+ * @sq_depth: Returns depth of SQ -+ * @sq_shift: Returns shift of SQ -+ */ -+int irdma_uk_calc_depth_shift_sq(struct irdma_qp_uk_init_info *ukinfo, -+ u32 *sq_depth, u8 *sq_shift) -+{ -+ bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2; -+ int status; -+ -+ irdma_get_wqe_shift(ukinfo->uk_attrs, -+ imm_support ? ukinfo->max_sq_frag_cnt + 1 : -+ ukinfo->max_sq_frag_cnt, -+ ukinfo->max_inline_data, sq_shift); -+ status = irdma_get_sqdepth(ukinfo->uk_attrs, ukinfo->sq_size, -+ *sq_shift, sq_depth); -+ -+ return status; -+} -+ -+/** -+ * irdma_uk_calc_depth_shift_rq - calculate depth and shift for RQ size. -+ * @ukinfo: qp initialization info -+ * @rq_depth: Returns depth of RQ -+ * @rq_shift: Returns shift of RQ -+ */ -+int irdma_uk_calc_depth_shift_rq(struct irdma_qp_uk_init_info *ukinfo, -+ u32 *rq_depth, u8 *rq_shift) -+{ -+ int status; -+ -+ irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0, -+ rq_shift); -+ -+ if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) { -+ if (ukinfo->abi_ver > 4) -+ *rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1; -+ } -+ -+ status = irdma_get_rqdepth(ukinfo->uk_attrs, ukinfo->rq_size, -+ *rq_shift, rq_depth); -+ -+ return status; -+} -+ - /** - * irdma_uk_qp_init - initialize shared qp - * @qp: hw qp (user and kernel) -@@ -1428,23 +1500,12 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info) - { - int ret_code = 0; - u32 sq_ring_size; -- u8 sqshift, rqshift; - - qp->uk_attrs = info->uk_attrs; - if (info->max_sq_frag_cnt > qp->uk_attrs->max_hw_wq_frags || - info->max_rq_frag_cnt > qp->uk_attrs->max_hw_wq_frags) - return -EINVAL; - -- irdma_get_wqe_shift(qp->uk_attrs, info->max_rq_frag_cnt, 0, &rqshift); -- if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) { -- irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt, -- info->max_inline_data, &sqshift); -- if (info->abi_ver > 4) -- rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1; -- } else { -- irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt + 1, -- info->max_inline_data, &sqshift); -- } - qp->qp_caps = info->qp_caps; - qp->sq_base = info->sq; - qp->rq_base = info->rq; -@@ -1458,7 +1519,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info) - qp->sq_size = info->sq_size; - qp->push_mode = false; - qp->max_sq_frag_cnt = info->max_sq_frag_cnt; -- sq_ring_size = qp->sq_size << sqshift; -+ sq_ring_size = qp->sq_size << info->sq_shift; - IRDMA_RING_INIT(qp->sq_ring, sq_ring_size); - IRDMA_RING_INIT(qp->initial_ring, sq_ring_size); - if (info->first_sq_wq) { -@@ -1473,9 +1534,9 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info) - qp->rq_size = info->rq_size; - qp->max_rq_frag_cnt = info->max_rq_frag_cnt; - qp->max_inline_data = info->max_inline_data; -- qp->rq_wqe_size = rqshift; -+ qp->rq_wqe_size = info->rq_shift; - IRDMA_RING_INIT(qp->rq_ring, qp->rq_size); -- qp->rq_wqe_size_multiplier = 1 << rqshift; -+ qp->rq_wqe_size_multiplier = 1 << info->rq_shift; - if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) - qp->wqe_ops = iw_wqe_uk_ops_gen_1; - else -diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h -index d0cdf609f5e06..1e0e1a71dbada 100644 ---- a/drivers/infiniband/hw/irdma/user.h -+++ b/drivers/infiniband/hw/irdma/user.h -@@ -295,6 +295,12 @@ void irdma_uk_cq_init(struct irdma_cq_uk *cq, - struct irdma_cq_uk_init_info *info); - int irdma_uk_qp_init(struct irdma_qp_uk *qp, - struct irdma_qp_uk_init_info *info); -+void irdma_uk_calc_shift_wq(struct irdma_qp_uk_init_info *ukinfo, u8 *sq_shift, -+ u8 *rq_shift); -+int irdma_uk_calc_depth_shift_sq(struct irdma_qp_uk_init_info *ukinfo, -+ u32 *sq_depth, u8 *sq_shift); -+int irdma_uk_calc_depth_shift_rq(struct irdma_qp_uk_init_info *ukinfo, -+ u32 *rq_depth, u8 *rq_shift); - struct irdma_sq_uk_wr_trk_info { - u64 wrid; - u32 wr_len; -@@ -374,8 +380,12 @@ struct irdma_qp_uk_init_info { - u32 max_sq_frag_cnt; - u32 max_rq_frag_cnt; - u32 max_inline_data; -+ u32 sq_depth; -+ u32 rq_depth; - u8 first_sq_wq; - u8 type; -+ u8 sq_shift; -+ u8 rq_shift; - int abi_ver; - bool legacy_mode; - }; -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 42c671f209233..76c5f461faca0 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -277,7 +277,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx, - struct irdma_alloc_ucontext_req req = {}; - struct irdma_alloc_ucontext_resp uresp = {}; - struct irdma_ucontext *ucontext = to_ucontext(uctx); -- struct irdma_uk_attrs *uk_attrs; -+ struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs; - - if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN || - udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN) -@@ -292,7 +292,9 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx, - ucontext->iwdev = iwdev; - ucontext->abi_ver = req.userspace_ver; - -- uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs; -+ if (req.comp_mask & IRDMA_ALLOC_UCTX_USE_RAW_ATTR) -+ ucontext->use_raw_attrs = true; -+ - /* GEN_1 legacy support with libi40iw */ - if (udata->outlen == IRDMA_ALLOC_UCTX_MIN_RESP_LEN) { - if (uk_attrs->hw_rev != IRDMA_GEN_1) -@@ -327,6 +329,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx, - uresp.max_hw_cq_size = uk_attrs->max_hw_cq_size; - uresp.min_hw_cq_size = uk_attrs->min_hw_cq_size; - uresp.hw_rev = uk_attrs->hw_rev; -+ uresp.comp_mask |= IRDMA_ALLOC_UCTX_USE_RAW_ATTR; - if (ib_copy_to_udata(udata, &uresp, - min(sizeof(uresp), udata->outlen))) { - rdma_user_mmap_entry_remove(ucontext->db_mmap_entry); -@@ -566,6 +569,86 @@ static void irdma_setup_virt_qp(struct irdma_device *iwdev, - } - } - -+/** -+ * irdma_setup_umode_qp - setup sq and rq size in user mode qp -+ * @iwdev: iwarp device -+ * @iwqp: qp ptr (user or kernel) -+ * @info: initialize info to return -+ * @init_attr: Initial QP create attributes -+ */ -+static int irdma_setup_umode_qp(struct ib_udata *udata, -+ struct irdma_device *iwdev, -+ struct irdma_qp *iwqp, -+ struct irdma_qp_init_info *info, -+ struct ib_qp_init_attr *init_attr) -+{ -+ struct irdma_ucontext *ucontext = rdma_udata_to_drv_context(udata, -+ struct irdma_ucontext, ibucontext); -+ struct irdma_qp_uk_init_info *ukinfo = &info->qp_uk_init_info; -+ struct irdma_create_qp_req req; -+ unsigned long flags; -+ int ret; -+ -+ ret = ib_copy_from_udata(&req, udata, -+ min(sizeof(req), udata->inlen)); -+ if (ret) { -+ ibdev_dbg(&iwdev->ibdev, "VERBS: ib_copy_from_data fail\n"); -+ return ret; -+ } -+ -+ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx; -+ iwqp->user_mode = 1; -+ if (req.user_wqe_bufs) { -+ info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode; -+ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags); -+ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs, -+ &ucontext->qp_reg_mem_list); -+ spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags); -+ -+ if (!iwqp->iwpbl) { -+ ret = -ENODATA; -+ ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n"); -+ return ret; -+ } -+ } -+ -+ if (!ucontext->use_raw_attrs) { -+ /** -+ * Maintain backward compat with older ABI which passes sq and -+ * rq depth in quanta in cap.max_send_wr and cap.max_recv_wr. -+ * There is no way to compute the correct value of -+ * iwqp->max_send_wr/max_recv_wr in the kernel. -+ */ -+ iwqp->max_send_wr = init_attr->cap.max_send_wr; -+ iwqp->max_recv_wr = init_attr->cap.max_recv_wr; -+ ukinfo->sq_size = init_attr->cap.max_send_wr; -+ ukinfo->rq_size = init_attr->cap.max_recv_wr; -+ irdma_uk_calc_shift_wq(ukinfo, &ukinfo->sq_shift, -+ &ukinfo->rq_shift); -+ } else { -+ ret = irdma_uk_calc_depth_shift_sq(ukinfo, &ukinfo->sq_depth, -+ &ukinfo->sq_shift); -+ if (ret) -+ return ret; -+ -+ ret = irdma_uk_calc_depth_shift_rq(ukinfo, &ukinfo->rq_depth, -+ &ukinfo->rq_shift); -+ if (ret) -+ return ret; -+ -+ iwqp->max_send_wr = -+ (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift; -+ iwqp->max_recv_wr = -+ (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift; -+ ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift; -+ ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift; -+ } -+ -+ irdma_setup_virt_qp(iwdev, iwqp, info); -+ -+ return 0; -+} -+ - /** - * irdma_setup_kmode_qp - setup initialization for kernel mode qp - * @iwdev: iwarp device -@@ -579,40 +662,28 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev, - struct ib_qp_init_attr *init_attr) - { - struct irdma_dma_mem *mem = &iwqp->kqp.dma_mem; -- u32 sqdepth, rqdepth; -- u8 sqshift, rqshift; - u32 size; - int status; - struct irdma_qp_uk_init_info *ukinfo = &info->qp_uk_init_info; -- struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs; - -- irdma_get_wqe_shift(uk_attrs, -- uk_attrs->hw_rev >= IRDMA_GEN_2 ? ukinfo->max_sq_frag_cnt + 1 : -- ukinfo->max_sq_frag_cnt, -- ukinfo->max_inline_data, &sqshift); -- status = irdma_get_sqdepth(uk_attrs, ukinfo->sq_size, sqshift, -- &sqdepth); -+ status = irdma_uk_calc_depth_shift_sq(ukinfo, &ukinfo->sq_depth, -+ &ukinfo->sq_shift); - if (status) - return status; - -- if (uk_attrs->hw_rev == IRDMA_GEN_1) -- rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1; -- else -- irdma_get_wqe_shift(uk_attrs, ukinfo->max_rq_frag_cnt, 0, -- &rqshift); -- -- status = irdma_get_rqdepth(uk_attrs, ukinfo->rq_size, rqshift, -- &rqdepth); -+ status = irdma_uk_calc_depth_shift_rq(ukinfo, &ukinfo->rq_depth, -+ &ukinfo->rq_shift); - if (status) - return status; - - iwqp->kqp.sq_wrid_mem = -- kcalloc(sqdepth, sizeof(*iwqp->kqp.sq_wrid_mem), GFP_KERNEL); -+ kcalloc(ukinfo->sq_depth, sizeof(*iwqp->kqp.sq_wrid_mem), GFP_KERNEL); - if (!iwqp->kqp.sq_wrid_mem) - return -ENOMEM; - - iwqp->kqp.rq_wrid_mem = -- kcalloc(rqdepth, sizeof(*iwqp->kqp.rq_wrid_mem), GFP_KERNEL); -+ kcalloc(ukinfo->rq_depth, sizeof(*iwqp->kqp.rq_wrid_mem), GFP_KERNEL); -+ - if (!iwqp->kqp.rq_wrid_mem) { - kfree(iwqp->kqp.sq_wrid_mem); - iwqp->kqp.sq_wrid_mem = NULL; -@@ -622,7 +693,7 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev, - ukinfo->sq_wrtrk_array = iwqp->kqp.sq_wrid_mem; - ukinfo->rq_wrid_array = iwqp->kqp.rq_wrid_mem; - -- size = (sqdepth + rqdepth) * IRDMA_QP_WQE_MIN_SIZE; -+ size = (ukinfo->sq_depth + ukinfo->rq_depth) * IRDMA_QP_WQE_MIN_SIZE; - size += (IRDMA_SHADOW_AREA_SIZE << 3); - - mem->size = ALIGN(size, 256); -@@ -638,16 +709,18 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev, - - ukinfo->sq = mem->va; - info->sq_pa = mem->pa; -- ukinfo->rq = &ukinfo->sq[sqdepth]; -- info->rq_pa = info->sq_pa + (sqdepth * IRDMA_QP_WQE_MIN_SIZE); -- ukinfo->shadow_area = ukinfo->rq[rqdepth].elem; -- info->shadow_area_pa = info->rq_pa + (rqdepth * IRDMA_QP_WQE_MIN_SIZE); -- ukinfo->sq_size = sqdepth >> sqshift; -- ukinfo->rq_size = rqdepth >> rqshift; -- ukinfo->qp_id = iwqp->ibqp.qp_num; -- -- init_attr->cap.max_send_wr = (sqdepth - IRDMA_SQ_RSVD) >> sqshift; -- init_attr->cap.max_recv_wr = (rqdepth - IRDMA_RQ_RSVD) >> rqshift; -+ ukinfo->rq = &ukinfo->sq[ukinfo->sq_depth]; -+ info->rq_pa = info->sq_pa + (ukinfo->sq_depth * IRDMA_QP_WQE_MIN_SIZE); -+ ukinfo->shadow_area = ukinfo->rq[ukinfo->rq_depth].elem; -+ info->shadow_area_pa = -+ info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE); -+ ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift; -+ ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift; -+ -+ iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift; -+ iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift; -+ init_attr->cap.max_send_wr = iwqp->max_send_wr; -+ init_attr->cap.max_recv_wr = iwqp->max_recv_wr; - - return 0; - } -@@ -805,18 +878,14 @@ static int irdma_create_qp(struct ib_qp *ibqp, - struct irdma_device *iwdev = to_iwdev(ibpd->device); - struct irdma_pci_f *rf = iwdev->rf; - struct irdma_qp *iwqp = to_iwqp(ibqp); -- struct irdma_create_qp_req req = {}; - struct irdma_create_qp_resp uresp = {}; - u32 qp_num = 0; - int err_code; -- int sq_size; -- int rq_size; - struct irdma_sc_qp *qp; - struct irdma_sc_dev *dev = &rf->sc_dev; - struct irdma_uk_attrs *uk_attrs = &dev->hw_attrs.uk_attrs; - struct irdma_qp_init_info init_info = {}; - struct irdma_qp_host_ctx_info *ctx_info; -- unsigned long flags; - - err_code = irdma_validate_qp_attrs(init_attr, iwdev); - if (err_code) -@@ -826,13 +895,10 @@ static int irdma_create_qp(struct ib_qp *ibqp, - udata->outlen < IRDMA_CREATE_QP_MIN_RESP_LEN)) - return -EINVAL; - -- sq_size = init_attr->cap.max_send_wr; -- rq_size = init_attr->cap.max_recv_wr; -- - init_info.vsi = &iwdev->vsi; - init_info.qp_uk_init_info.uk_attrs = uk_attrs; -- init_info.qp_uk_init_info.sq_size = sq_size; -- init_info.qp_uk_init_info.rq_size = rq_size; -+ init_info.qp_uk_init_info.sq_size = init_attr->cap.max_send_wr; -+ init_info.qp_uk_init_info.rq_size = init_attr->cap.max_recv_wr; - init_info.qp_uk_init_info.max_sq_frag_cnt = init_attr->cap.max_send_sge; - init_info.qp_uk_init_info.max_rq_frag_cnt = init_attr->cap.max_recv_sge; - init_info.qp_uk_init_info.max_inline_data = init_attr->cap.max_inline_data; -@@ -874,7 +940,7 @@ static int irdma_create_qp(struct ib_qp *ibqp, - iwqp->host_ctx.size = IRDMA_QP_CTX_SIZE; - - init_info.pd = &iwpd->sc_pd; -- init_info.qp_uk_init_info.qp_id = iwqp->ibqp.qp_num; -+ init_info.qp_uk_init_info.qp_id = qp_num; - if (!rdma_protocol_roce(&iwdev->ibdev, 1)) - init_info.qp_uk_init_info.first_sq_wq = 1; - iwqp->ctx_info.qp_compl_ctx = (uintptr_t)qp; -@@ -882,36 +948,9 @@ static int irdma_create_qp(struct ib_qp *ibqp, - init_waitqueue_head(&iwqp->mod_qp_waitq); - - if (udata) { -- err_code = ib_copy_from_udata(&req, udata, -- min(sizeof(req), udata->inlen)); -- if (err_code) { -- ibdev_dbg(&iwdev->ibdev, -- "VERBS: ib_copy_from_data fail\n"); -- goto error; -- } -- -- iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx; -- iwqp->user_mode = 1; -- if (req.user_wqe_bufs) { -- struct irdma_ucontext *ucontext = -- rdma_udata_to_drv_context(udata, -- struct irdma_ucontext, -- ibucontext); -- -- init_info.qp_uk_init_info.legacy_mode = ucontext->legacy_mode; -- spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags); -- iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs, -- &ucontext->qp_reg_mem_list); -- spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags); -- -- if (!iwqp->iwpbl) { -- err_code = -ENODATA; -- ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n"); -- goto error; -- } -- } - init_info.qp_uk_init_info.abi_ver = iwpd->sc_pd.abi_ver; -- irdma_setup_virt_qp(iwdev, iwqp, &init_info); -+ err_code = irdma_setup_umode_qp(udata, iwdev, iwqp, &init_info, -+ init_attr); - } else { - INIT_DELAYED_WORK(&iwqp->dwork_flush, irdma_flush_worker); - init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER; -@@ -966,8 +1005,6 @@ static int irdma_create_qp(struct ib_qp *ibqp, - spin_lock_init(&iwqp->sc_qp.pfpdu.lock); - iwqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0; - rf->qp_table[qp_num] = iwqp; -- iwqp->max_send_wr = sq_size; -- iwqp->max_recv_wr = rq_size; - - if (rdma_protocol_roce(&iwdev->ibdev, 1)) { - if (dev->ws_add(&iwdev->vsi, 0)) { -@@ -988,8 +1025,8 @@ static int irdma_create_qp(struct ib_qp *ibqp, - if (rdma_protocol_iwarp(&iwdev->ibdev, 1)) - uresp.lsmm = 1; - } -- uresp.actual_sq_size = sq_size; -- uresp.actual_rq_size = rq_size; -+ uresp.actual_sq_size = init_info.qp_uk_init_info.sq_size; -+ uresp.actual_rq_size = init_info.qp_uk_init_info.rq_size; - uresp.qp_id = qp_num; - uresp.qp_caps = qp->qp_uk.qp_caps; - -diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h -index 9f9e273bbff3e..0bc0d0faa0868 100644 ---- a/drivers/infiniband/hw/irdma/verbs.h -+++ b/drivers/infiniband/hw/irdma/verbs.h -@@ -18,7 +18,8 @@ struct irdma_ucontext { - struct list_head qp_reg_mem_list; - spinlock_t qp_reg_mem_list_lock; /* protect QP memory list */ - int abi_ver; -- bool legacy_mode; -+ u8 legacy_mode : 1; -+ u8 use_raw_attrs : 1; - }; - - struct irdma_pd { -diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c -index f8e2baed27a5c..7013ce20549bd 100644 ---- a/drivers/infiniband/hw/mlx5/devx.c -+++ b/drivers/infiniband/hw/mlx5/devx.c -@@ -2951,7 +2951,7 @@ DECLARE_UVERBS_NAMED_METHOD( - MLX5_IB_METHOD_DEVX_OBJ_MODIFY, - UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, - UVERBS_IDR_ANY_OBJECT, -- UVERBS_ACCESS_WRITE, -+ UVERBS_ACCESS_READ, - UA_MANDATORY), - UVERBS_ATTR_PTR_IN( - MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, -diff --git a/drivers/infiniband/hw/mlx5/wr.c b/drivers/infiniband/hw/mlx5/wr.c -index 855f3f4fefadd..737db67a9ce1d 100644 ---- a/drivers/infiniband/hw/mlx5/wr.c -+++ b/drivers/infiniband/hw/mlx5/wr.c -@@ -78,7 +78,7 @@ static void set_eth_seg(const struct ib_send_wr *wr, struct mlx5_ib_qp *qp, - */ - copysz = min_t(u64, *cur_edge - (void *)eseg->inline_hdr.start, - left); -- memcpy(eseg->inline_hdr.start, pdata, copysz); -+ memcpy(eseg->inline_hdr.data, pdata, copysz); - stride = ALIGN(sizeof(struct mlx5_wqe_eth_seg) - - sizeof(eseg->inline_hdr.start) + copysz, 16); - *size += stride / 16; -diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c -index d3c436ead6946..4aa80c9388f05 100644 ---- a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c -+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c -@@ -133,7 +133,7 @@ static ssize_t mpath_policy_store(struct device *dev, - - /* distinguish "mi" and "min-latency" with length */ - len = strnlen(buf, NAME_MAX); -- if (buf[len - 1] == '\n') -+ if (len && buf[len - 1] == '\n') - len--; - - if (!strncasecmp(buf, "round-robin", 11) || -diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c -index cffa93f114a73..fd6c260d5857d 100644 ---- a/drivers/infiniband/ulp/srpt/ib_srpt.c -+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c -@@ -3209,7 +3209,6 @@ static int srpt_add_one(struct ib_device *device) - - INIT_IB_EVENT_HANDLER(&sdev->event_handler, sdev->device, - srpt_event_handler); -- ib_register_event_handler(&sdev->event_handler); - - for (i = 1; i <= sdev->device->phys_port_cnt; i++) { - sport = &sdev->port[i - 1]; -@@ -3232,6 +3231,7 @@ static int srpt_add_one(struct ib_device *device) - } - } - -+ ib_register_event_handler(&sdev->event_handler); - spin_lock(&srpt_dev_lock); - list_add_tail(&sdev->list, &srpt_dev_list); - spin_unlock(&srpt_dev_lock); -@@ -3242,7 +3242,6 @@ static int srpt_add_one(struct ib_device *device) - - err_port: - srpt_unregister_mad_agent(sdev, i); -- ib_unregister_event_handler(&sdev->event_handler); - err_cm: - if (sdev->cm_id) - ib_destroy_cm_id(sdev->cm_id); -diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c -index c3937d2fc7446..a0f9978c68f55 100644 ---- a/drivers/input/keyboard/gpio_keys_polled.c -+++ b/drivers/input/keyboard/gpio_keys_polled.c -@@ -319,12 +319,10 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) - - error = devm_gpio_request_one(dev, button->gpio, - flags, button->desc ? : DRV_NAME); -- if (error) { -- dev_err(dev, -- "unable to claim gpio %u, err=%d\n", -- button->gpio, error); -- return error; -- } -+ if (error) -+ return dev_err_probe(dev, error, -+ "unable to claim gpio %u\n", -+ button->gpio); - - bdata->gpiod = gpio_to_desc(button->gpio); - if (!bdata->gpiod) { -diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig -index dc5f7a156ff5e..dc19e7fb07cfe 100644 ---- a/drivers/iommu/Kconfig -+++ b/drivers/iommu/Kconfig -@@ -192,7 +192,7 @@ source "drivers/iommu/intel/Kconfig" - config IRQ_REMAP - bool "Support for Interrupt Remapping" - depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI -- select DMAR_TABLE -+ select DMAR_TABLE if INTEL_IOMMU - help - Supports Interrupt remapping for IO-APIC and MSI devices. - To use x2apic mode in the CPU's which support x2APIC enhancements or -diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c -index f6e64c9858021..cc94ac6662339 100644 ---- a/drivers/iommu/amd/init.c -+++ b/drivers/iommu/amd/init.c -@@ -2047,6 +2047,9 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) - /* Prevent binding other PCI device drivers to IOMMU devices */ - iommu->dev->match_driver = false; - -+ /* ACPI _PRT won't have an IRQ for IOMMU */ -+ iommu->dev->irq_managed = 1; -+ - pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET, - &iommu->cap); - -diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig -index b7dff5092fd21..12e1e90fdae13 100644 ---- a/drivers/iommu/intel/Kconfig -+++ b/drivers/iommu/intel/Kconfig -@@ -96,4 +96,15 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON - passing intel_iommu=sm_on to the kernel. If not sure, please use - the default value. - -+config INTEL_IOMMU_PERF_EVENTS -+ def_bool y -+ bool "Intel IOMMU performance events" -+ depends on INTEL_IOMMU && PERF_EVENTS -+ help -+ Selecting this option will enable the performance monitoring -+ infrastructure in the Intel IOMMU. It collects information about -+ key events occurring during operation of the remapping hardware, -+ to aid performance tuning and debug. These are available on modern -+ processors which support Intel VT-d 4.0 and later. -+ - endif # INTEL_IOMMU -diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile -index fa0dae16441cb..29d26a4371327 100644 ---- a/drivers/iommu/intel/Makefile -+++ b/drivers/iommu/intel/Makefile -@@ -5,4 +5,7 @@ obj-$(CONFIG_DMAR_TABLE) += trace.o cap_audit.o - obj-$(CONFIG_DMAR_PERF) += perf.o - obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o - obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o -+ifdef CONFIG_INTEL_IOMMU - obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o -+endif -+obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o -diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c -index 418af1db0192d..4759f79ad7b94 100644 ---- a/drivers/iommu/intel/dmar.c -+++ b/drivers/iommu/intel/dmar.c -@@ -34,6 +34,7 @@ - #include "../irq_remapping.h" - #include "perf.h" - #include "trace.h" -+#include "perfmon.h" - - typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *); - struct dmar_res_callback { -@@ -1104,6 +1105,9 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) - if (sts & DMA_GSTS_QIES) - iommu->gcmd |= DMA_GCMD_QIE; - -+ if (alloc_iommu_pmu(iommu)) -+ pr_debug("Cannot alloc PMU for iommu (seq_id = %d)\n", iommu->seq_id); -+ - raw_spin_lock_init(&iommu->register_lock); - - /* -@@ -1131,6 +1135,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) - err_sysfs: - iommu_device_sysfs_remove(&iommu->iommu); - err_unmap: -+ free_iommu_pmu(iommu); - unmap_iommu(iommu); - error_free_seq_id: - ida_free(&dmar_seq_ids, iommu->seq_id); -@@ -1146,6 +1151,8 @@ static void free_iommu(struct intel_iommu *iommu) - iommu_device_sysfs_remove(&iommu->iommu); - } - -+ free_iommu_pmu(iommu); -+ - if (iommu->irq) { - if (iommu->pr_irq) { - free_irq(iommu->pr_irq, iommu); -diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h -index c99cb715bd9a2..c1348bedab3b3 100644 ---- a/drivers/iommu/intel/iommu.h -+++ b/drivers/iommu/intel/iommu.h -@@ -125,6 +125,11 @@ - #define DMAR_MTRR_PHYSMASK8_REG 0x208 - #define DMAR_MTRR_PHYSBASE9_REG 0x210 - #define DMAR_MTRR_PHYSMASK9_REG 0x218 -+#define DMAR_PERFCAP_REG 0x300 -+#define DMAR_PERFCFGOFF_REG 0x310 -+#define DMAR_PERFOVFOFF_REG 0x318 -+#define DMAR_PERFCNTROFF_REG 0x31c -+#define DMAR_PERFEVNTCAP_REG 0x380 - #define DMAR_VCCAP_REG 0xe30 /* Virtual command capability register */ - #define DMAR_VCMD_REG 0xe00 /* Virtual command register */ - #define DMAR_VCRSP_REG 0xe10 /* Virtual command response register */ -@@ -148,6 +153,7 @@ - */ - #define cap_esrtps(c) (((c) >> 63) & 1) - #define cap_esirtps(c) (((c) >> 62) & 1) -+#define cap_ecmds(c) (((c) >> 61) & 1) - #define cap_fl5lp_support(c) (((c) >> 60) & 1) - #define cap_pi_support(c) (((c) >> 59) & 1) - #define cap_fl1gp_support(c) (((c) >> 56) & 1) -@@ -179,7 +185,8 @@ - * Extended Capability Register - */ - --#define ecap_rps(e) (((e) >> 49) & 0x1) -+#define ecap_pms(e) (((e) >> 51) & 0x1) -+#define ecap_rps(e) (((e) >> 49) & 0x1) - #define ecap_smpwc(e) (((e) >> 48) & 0x1) - #define ecap_flts(e) (((e) >> 47) & 0x1) - #define ecap_slts(e) (((e) >> 46) & 0x1) -@@ -210,6 +217,22 @@ - #define ecap_max_handle_mask(e) (((e) >> 20) & 0xf) - #define ecap_sc_support(e) (((e) >> 7) & 0x1) /* Snooping Control */ - -+/* -+ * Decoding Perf Capability Register -+ */ -+#define pcap_num_cntr(p) ((p) & 0xffff) -+#define pcap_cntr_width(p) (((p) >> 16) & 0x7f) -+#define pcap_num_event_group(p) (((p) >> 24) & 0x1f) -+#define pcap_filters_mask(p) (((p) >> 32) & 0x1f) -+#define pcap_interrupt(p) (((p) >> 50) & 0x1) -+/* The counter stride is calculated as 2 ^ (x+10) bytes */ -+#define pcap_cntr_stride(p) (1ULL << ((((p) >> 52) & 0x7) + 10)) -+ -+/* -+ * Decoding Perf Event Capability Register -+ */ -+#define pecap_es(p) ((p) & 0xfffffff) -+ - /* Virtual command interface capability */ - #define vccap_pasid(v) (((v) & DMA_VCS_PAS)) /* PASID allocation */ - -@@ -561,6 +584,22 @@ struct dmar_domain { - iommu core */ - }; - -+struct iommu_pmu { -+ struct intel_iommu *iommu; -+ u32 num_cntr; /* Number of counters */ -+ u32 num_eg; /* Number of event group */ -+ u32 cntr_width; /* Counter width */ -+ u32 cntr_stride; /* Counter Stride */ -+ u32 filter; /* Bitmask of filter support */ -+ void __iomem *base; /* the PerfMon base address */ -+ void __iomem *cfg_reg; /* counter configuration base address */ -+ void __iomem *cntr_reg; /* counter 0 address*/ -+ void __iomem *overflow; /* overflow status register */ -+ -+ u64 *evcap; /* Indicates all supported events */ -+ u32 **cntr_evcap; /* Supported events of each counter. */ -+}; -+ - struct intel_iommu { - void __iomem *reg; /* Pointer to hardware regs, virtual addr */ - u64 reg_phys; /* physical address of hw register set */ -@@ -608,6 +647,8 @@ struct intel_iommu { - - struct dmar_drhd_unit *drhd; - void *perf_statistic; -+ -+ struct iommu_pmu *pmu; - }; - - /* PCI domain-device relationship */ -diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c -index 3f03039e5cce5..32432d82d7744 100644 ---- a/drivers/iommu/intel/pasid.c -+++ b/drivers/iommu/intel/pasid.c -@@ -435,6 +435,9 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu, - if (!info || !info->ats_enabled) - return; - -+ if (pci_dev_is_disconnected(to_pci_dev(dev))) -+ return; -+ - sid = info->bus << 8 | info->devfn; - qdep = info->ats_qdep; - pfsid = info->pfsid; -diff --git a/drivers/iommu/intel/perfmon.c b/drivers/iommu/intel/perfmon.c -new file mode 100644 -index 0000000000000..db5791a544551 ---- /dev/null -+++ b/drivers/iommu/intel/perfmon.c -@@ -0,0 +1,172 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Support Intel IOMMU PerfMon -+ * Copyright(c) 2023 Intel Corporation. -+ */ -+#define pr_fmt(fmt) "DMAR: " fmt -+#define dev_fmt(fmt) pr_fmt(fmt) -+ -+#include -+#include "iommu.h" -+#include "perfmon.h" -+ -+static inline void __iomem * -+get_perf_reg_address(struct intel_iommu *iommu, u32 offset) -+{ -+ u32 off = dmar_readl(iommu->reg + offset); -+ -+ return iommu->reg + off; -+} -+ -+int alloc_iommu_pmu(struct intel_iommu *iommu) -+{ -+ struct iommu_pmu *iommu_pmu; -+ int i, j, ret; -+ u64 perfcap; -+ u32 cap; -+ -+ if (!ecap_pms(iommu->ecap)) -+ return 0; -+ -+ /* The IOMMU PMU requires the ECMD support as well */ -+ if (!cap_ecmds(iommu->cap)) -+ return -ENODEV; -+ -+ perfcap = dmar_readq(iommu->reg + DMAR_PERFCAP_REG); -+ /* The performance monitoring is not supported. */ -+ if (!perfcap) -+ return -ENODEV; -+ -+ /* Sanity check for the number of the counters and event groups */ -+ if (!pcap_num_cntr(perfcap) || !pcap_num_event_group(perfcap)) -+ return -ENODEV; -+ -+ /* The interrupt on overflow is required */ -+ if (!pcap_interrupt(perfcap)) -+ return -ENODEV; -+ -+ iommu_pmu = kzalloc(sizeof(*iommu_pmu), GFP_KERNEL); -+ if (!iommu_pmu) -+ return -ENOMEM; -+ -+ iommu_pmu->num_cntr = pcap_num_cntr(perfcap); -+ iommu_pmu->cntr_width = pcap_cntr_width(perfcap); -+ iommu_pmu->filter = pcap_filters_mask(perfcap); -+ iommu_pmu->cntr_stride = pcap_cntr_stride(perfcap); -+ iommu_pmu->num_eg = pcap_num_event_group(perfcap); -+ -+ iommu_pmu->evcap = kcalloc(iommu_pmu->num_eg, sizeof(u64), GFP_KERNEL); -+ if (!iommu_pmu->evcap) { -+ ret = -ENOMEM; -+ goto free_pmu; -+ } -+ -+ /* Parse event group capabilities */ -+ for (i = 0; i < iommu_pmu->num_eg; i++) { -+ u64 pcap; -+ -+ pcap = dmar_readq(iommu->reg + DMAR_PERFEVNTCAP_REG + -+ i * IOMMU_PMU_CAP_REGS_STEP); -+ iommu_pmu->evcap[i] = pecap_es(pcap); -+ } -+ -+ iommu_pmu->cntr_evcap = kcalloc(iommu_pmu->num_cntr, sizeof(u32 *), GFP_KERNEL); -+ if (!iommu_pmu->cntr_evcap) { -+ ret = -ENOMEM; -+ goto free_pmu_evcap; -+ } -+ for (i = 0; i < iommu_pmu->num_cntr; i++) { -+ iommu_pmu->cntr_evcap[i] = kcalloc(iommu_pmu->num_eg, sizeof(u32), GFP_KERNEL); -+ if (!iommu_pmu->cntr_evcap[i]) { -+ ret = -ENOMEM; -+ goto free_pmu_cntr_evcap; -+ } -+ /* -+ * Set to the global capabilities, will adjust according -+ * to per-counter capabilities later. -+ */ -+ for (j = 0; j < iommu_pmu->num_eg; j++) -+ iommu_pmu->cntr_evcap[i][j] = (u32)iommu_pmu->evcap[j]; -+ } -+ -+ iommu_pmu->cfg_reg = get_perf_reg_address(iommu, DMAR_PERFCFGOFF_REG); -+ iommu_pmu->cntr_reg = get_perf_reg_address(iommu, DMAR_PERFCNTROFF_REG); -+ iommu_pmu->overflow = get_perf_reg_address(iommu, DMAR_PERFOVFOFF_REG); -+ -+ /* -+ * Check per-counter capabilities. All counters should have the -+ * same capabilities on Interrupt on Overflow Support and Counter -+ * Width. -+ */ -+ for (i = 0; i < iommu_pmu->num_cntr; i++) { -+ cap = dmar_readl(iommu_pmu->cfg_reg + -+ i * IOMMU_PMU_CFG_OFFSET + -+ IOMMU_PMU_CFG_CNTRCAP_OFFSET); -+ if (!iommu_cntrcap_pcc(cap)) -+ continue; -+ -+ /* -+ * It's possible that some counters have a different -+ * capability because of e.g., HW bug. Check the corner -+ * case here and simply drop those counters. -+ */ -+ if ((iommu_cntrcap_cw(cap) != iommu_pmu->cntr_width) || -+ !iommu_cntrcap_ios(cap)) { -+ iommu_pmu->num_cntr = i; -+ pr_warn("PMU counter capability inconsistent, counter number reduced to %d\n", -+ iommu_pmu->num_cntr); -+ } -+ -+ /* Clear the pre-defined events group */ -+ for (j = 0; j < iommu_pmu->num_eg; j++) -+ iommu_pmu->cntr_evcap[i][j] = 0; -+ -+ /* Override with per-counter event capabilities */ -+ for (j = 0; j < iommu_cntrcap_egcnt(cap); j++) { -+ cap = dmar_readl(iommu_pmu->cfg_reg + i * IOMMU_PMU_CFG_OFFSET + -+ IOMMU_PMU_CFG_CNTREVCAP_OFFSET + -+ (j * IOMMU_PMU_OFF_REGS_STEP)); -+ iommu_pmu->cntr_evcap[i][iommu_event_group(cap)] = iommu_event_select(cap); -+ /* -+ * Some events may only be supported by a specific counter. -+ * Track them in the evcap as well. -+ */ -+ iommu_pmu->evcap[iommu_event_group(cap)] |= iommu_event_select(cap); -+ } -+ } -+ -+ iommu_pmu->iommu = iommu; -+ iommu->pmu = iommu_pmu; -+ -+ return 0; -+ -+free_pmu_cntr_evcap: -+ for (i = 0; i < iommu_pmu->num_cntr; i++) -+ kfree(iommu_pmu->cntr_evcap[i]); -+ kfree(iommu_pmu->cntr_evcap); -+free_pmu_evcap: -+ kfree(iommu_pmu->evcap); -+free_pmu: -+ kfree(iommu_pmu); -+ -+ return ret; -+} -+ -+void free_iommu_pmu(struct intel_iommu *iommu) -+{ -+ struct iommu_pmu *iommu_pmu = iommu->pmu; -+ -+ if (!iommu_pmu) -+ return; -+ -+ if (iommu_pmu->evcap) { -+ int i; -+ -+ for (i = 0; i < iommu_pmu->num_cntr; i++) -+ kfree(iommu_pmu->cntr_evcap[i]); -+ kfree(iommu_pmu->cntr_evcap); -+ } -+ kfree(iommu_pmu->evcap); -+ kfree(iommu_pmu); -+ iommu->pmu = NULL; -+} -diff --git a/drivers/iommu/intel/perfmon.h b/drivers/iommu/intel/perfmon.h -new file mode 100644 -index 0000000000000..4b0d9c1fea6ff ---- /dev/null -+++ b/drivers/iommu/intel/perfmon.h -@@ -0,0 +1,40 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * PERFCFGOFF_REG, PERFFRZOFF_REG -+ * PERFOVFOFF_REG, PERFCNTROFF_REG -+ */ -+#define IOMMU_PMU_NUM_OFF_REGS 4 -+#define IOMMU_PMU_OFF_REGS_STEP 4 -+ -+#define IOMMU_PMU_CFG_OFFSET 0x100 -+#define IOMMU_PMU_CFG_CNTRCAP_OFFSET 0x80 -+#define IOMMU_PMU_CFG_CNTREVCAP_OFFSET 0x84 -+#define IOMMU_PMU_CFG_SIZE 0x8 -+#define IOMMU_PMU_CFG_FILTERS_OFFSET 0x4 -+ -+#define IOMMU_PMU_CAP_REGS_STEP 8 -+ -+#define iommu_cntrcap_pcc(p) ((p) & 0x1) -+#define iommu_cntrcap_cw(p) (((p) >> 8) & 0xff) -+#define iommu_cntrcap_ios(p) (((p) >> 16) & 0x1) -+#define iommu_cntrcap_egcnt(p) (((p) >> 28) & 0xf) -+ -+#define iommu_event_select(p) ((p) & 0xfffffff) -+#define iommu_event_group(p) (((p) >> 28) & 0xf) -+ -+#ifdef CONFIG_INTEL_IOMMU_PERF_EVENTS -+int alloc_iommu_pmu(struct intel_iommu *iommu); -+void free_iommu_pmu(struct intel_iommu *iommu); -+#else -+static inline int -+alloc_iommu_pmu(struct intel_iommu *iommu) -+{ -+ return 0; -+} -+ -+static inline void -+free_iommu_pmu(struct intel_iommu *iommu) -+{ -+} -+#endif /* CONFIG_INTEL_IOMMU_PERF_EVENTS */ -diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c -index 83314b9d8f38b..ee59647c20501 100644 ---- a/drivers/iommu/irq_remapping.c -+++ b/drivers/iommu/irq_remapping.c -@@ -99,7 +99,8 @@ int __init irq_remapping_prepare(void) - if (disable_irq_remap) - return -ENOSYS; - -- if (intel_irq_remap_ops.prepare() == 0) -+ if (IS_ENABLED(CONFIG_INTEL_IOMMU) && -+ intel_irq_remap_ops.prepare() == 0) - remap_ops = &intel_irq_remap_ops; - else if (IS_ENABLED(CONFIG_AMD_IOMMU) && - amd_iommu_irq_ops.prepare() == 0) -diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c -index d3a30ad94ac46..dd5d327c52a10 100644 ---- a/drivers/leds/flash/leds-sgm3140.c -+++ b/drivers/leds/flash/leds-sgm3140.c -@@ -114,8 +114,11 @@ static int sgm3140_brightness_set(struct led_classdev *led_cdev, - "failed to enable regulator: %d\n", ret); - return ret; - } -+ gpiod_set_value_cansleep(priv->flash_gpio, 0); - gpiod_set_value_cansleep(priv->enable_gpio, 1); - } else { -+ del_timer_sync(&priv->powerdown_timer); -+ gpiod_set_value_cansleep(priv->flash_gpio, 0); - gpiod_set_value_cansleep(priv->enable_gpio, 0); - ret = regulator_disable(priv->vin_regulator); - if (ret) { -diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c -index 0b52fc9097c6e..3c05958578a1c 100644 ---- a/drivers/leds/leds-aw2013.c -+++ b/drivers/leds/leds-aw2013.c -@@ -397,6 +397,7 @@ static int aw2013_probe(struct i2c_client *client) - regulator_disable(chip->vcc_regulator); - - error: -+ mutex_unlock(&chip->mutex); - mutex_destroy(&chip->mutex); - return ret; - } -diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c -index 100a6a236d92a..ec662f97ba828 100644 ---- a/drivers/md/dm-bufio.c -+++ b/drivers/md/dm-bufio.c -@@ -614,7 +614,7 @@ static void use_dmio(struct dm_buffer *b, enum req_op op, sector_t sector, - io_req.mem.ptr.vma = (char *)b->data + offset; - } - -- r = dm_io(&io_req, 1, ®ion, NULL); -+ r = dm_io(&io_req, 1, ®ion, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) - b->end_io(b, errno_to_blk_status(r)); - } -@@ -1375,7 +1375,7 @@ int dm_bufio_issue_flush(struct dm_bufio_client *c) - - BUG_ON(dm_bufio_in_request()); - -- return dm_io(&io_req, 1, &io_reg, NULL); -+ return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT); - } - EXPORT_SYMBOL_GPL(dm_bufio_issue_flush); - -@@ -1398,7 +1398,7 @@ int dm_bufio_issue_discard(struct dm_bufio_client *c, sector_t block, sector_t c - - BUG_ON(dm_bufio_in_request()); - -- return dm_io(&io_req, 1, &io_reg, NULL); -+ return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT); - } - EXPORT_SYMBOL_GPL(dm_bufio_issue_discard); - -diff --git a/drivers/md/dm-cache-policy.h b/drivers/md/dm-cache-policy.h -index 6ba3e9c91af53..8bc21d54884e9 100644 ---- a/drivers/md/dm-cache-policy.h -+++ b/drivers/md/dm-cache-policy.h -@@ -75,7 +75,7 @@ struct dm_cache_policy { - * background work. - */ - int (*get_background_work)(struct dm_cache_policy *p, bool idle, -- struct policy_work **result); -+ struct policy_work **result); - - /* - * You must pass in the same work pointer that you were given, not -diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c -index 3e215aa85b99a..25e51dc6e5598 100644 ---- a/drivers/md/dm-crypt.c -+++ b/drivers/md/dm-crypt.c -@@ -52,11 +52,11 @@ - struct convert_context { - struct completion restart; - struct bio *bio_in; -- struct bio *bio_out; - struct bvec_iter iter_in; -+ struct bio *bio_out; - struct bvec_iter iter_out; -- u64 cc_sector; - atomic_t cc_pending; -+ u64 cc_sector; - union { - struct skcipher_request *req; - struct aead_request *req_aead; -@@ -2535,7 +2535,7 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string - type = &key_type_encrypted; - set_key = set_key_encrypted; - } else if (IS_ENABLED(CONFIG_TRUSTED_KEYS) && -- !strncmp(key_string, "trusted:", key_desc - key_string + 1)) { -+ !strncmp(key_string, "trusted:", key_desc - key_string + 1)) { - type = &key_type_trusted; - set_key = set_key_trusted; - } else { -diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c -index 3da4359f51645..9c9e2b50c63c3 100644 ---- a/drivers/md/dm-integrity.c -+++ b/drivers/md/dm-integrity.c -@@ -579,7 +579,7 @@ static int sync_rw_sb(struct dm_integrity_c *ic, blk_opf_t opf) - } - } - -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) - return r; - -@@ -1089,7 +1089,7 @@ static void rw_journal_sectors(struct dm_integrity_c *ic, blk_opf_t opf, - io_loc.sector = ic->start + SB_SECTORS + sector; - io_loc.count = n_sectors; - -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) { - dm_integrity_io_error(ic, (opf & REQ_OP_MASK) == REQ_OP_READ ? - "reading journal" : "writing journal", r); -@@ -1205,7 +1205,7 @@ static void copy_from_journal(struct dm_integrity_c *ic, unsigned int section, u - io_loc.sector = target; - io_loc.count = n_sectors; - -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) { - WARN_ONCE(1, "asynchronous dm_io failed: %d", r); - fn(-1UL, data); -@@ -1532,7 +1532,7 @@ static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_dat - fr.io_reg.count = 0, - fr.ic = ic; - init_completion(&fr.comp); -- r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL); -+ r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL, IOPRIO_DEFAULT); - BUG_ON(r); - } - -@@ -1709,7 +1709,6 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks - struct bio_vec bv; - sector_t sector, logical_sector, area, offset; - struct page *page; -- void *buffer; - - get_area_and_offset(ic, dio->range.logical_sector, &area, &offset); - dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset, -@@ -1718,13 +1717,14 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks - logical_sector = dio->range.logical_sector; - - page = mempool_alloc(&ic->recheck_pool, GFP_NOIO); -- buffer = page_to_virt(page); - - __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { - unsigned pos = 0; - - do { -+ sector_t alignment; - char *mem; -+ char *buffer = page_to_virt(page); - int r; - struct dm_io_request io_req; - struct dm_io_region io_loc; -@@ -1737,7 +1737,15 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks - io_loc.sector = sector; - io_loc.count = ic->sectors_per_block; - -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ /* Align the bio to logical block size */ -+ alignment = dio->range.logical_sector | bio_sectors(bio) | (PAGE_SIZE >> SECTOR_SHIFT); -+ alignment &= -alignment; -+ io_loc.sector = round_down(io_loc.sector, alignment); -+ io_loc.count += sector - io_loc.sector; -+ buffer += (sector - io_loc.sector) << SECTOR_SHIFT; -+ io_loc.count = round_up(io_loc.count, alignment); -+ -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) { - dio->bi_status = errno_to_blk_status(r); - goto free_ret; -@@ -1856,12 +1864,12 @@ static void integrity_metadata(struct work_struct *w) - r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset, - checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE); - if (unlikely(r)) { -+ if (likely(checksums != checksums_onstack)) -+ kfree(checksums); - if (r > 0) { -- integrity_recheck(dio, checksums); -+ integrity_recheck(dio, checksums_onstack); - goto skip_io; - } -- if (likely(checksums != checksums_onstack)) -- kfree(checksums); - goto error; - } - -@@ -2367,7 +2375,6 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map - else - skip_check: - dec_in_flight(dio); -- - } else { - INIT_WORK(&dio->work, integrity_metadata); - queue_work(ic->metadata_wq, &dio->work); -@@ -2775,7 +2782,7 @@ static void integrity_recalc(struct work_struct *w) - io_loc.sector = get_data_sector(ic, area, offset); - io_loc.count = n_sectors; - -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) { - dm_integrity_io_error(ic, "reading data", r); - goto err; -@@ -4151,7 +4158,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv - } else if (sscanf(opt_string, "block_size:%u%c", &val, &dummy) == 1) { - if (val < 1 << SECTOR_SHIFT || - val > MAX_SECTORS_PER_BLOCK << SECTOR_SHIFT || -- (val & (val -1))) { -+ (val & (val - 1))) { - r = -EINVAL; - ti->error = "Invalid block_size argument"; - goto bad; -@@ -4477,7 +4484,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv - if (ic->internal_hash) { - size_t recalc_tags_size; - ic->recalc_wq = alloc_workqueue("dm-integrity-recalc", WQ_MEM_RECLAIM, 1); -- if (!ic->recalc_wq ) { -+ if (!ic->recalc_wq) { - ti->error = "Cannot allocate workqueue"; - r = -ENOMEM; - goto bad; -diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c -index e488b05e35fa3..ec97658387c39 100644 ---- a/drivers/md/dm-io.c -+++ b/drivers/md/dm-io.c -@@ -295,7 +295,7 @@ static void km_dp_init(struct dpages *dp, void *data) - *---------------------------------------------------------------*/ - static void do_region(const blk_opf_t opf, unsigned int region, - struct dm_io_region *where, struct dpages *dp, -- struct io *io) -+ struct io *io, unsigned short ioprio) - { - struct bio *bio; - struct page *page; -@@ -344,6 +344,7 @@ static void do_region(const blk_opf_t opf, unsigned int region, - &io->client->bios); - bio->bi_iter.bi_sector = where->sector + (where->count - remaining); - bio->bi_end_io = endio; -+ bio->bi_ioprio = ioprio; - store_io_and_region_in_bio(bio, io, region); - - if (op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES) { -@@ -371,7 +372,7 @@ static void do_region(const blk_opf_t opf, unsigned int region, - - static void dispatch_io(blk_opf_t opf, unsigned int num_regions, - struct dm_io_region *where, struct dpages *dp, -- struct io *io, int sync) -+ struct io *io, int sync, unsigned short ioprio) - { - int i; - struct dpages old_pages = *dp; -@@ -388,7 +389,7 @@ static void dispatch_io(blk_opf_t opf, unsigned int num_regions, - for (i = 0; i < num_regions; i++) { - *dp = old_pages; - if (where[i].count || (opf & REQ_PREFLUSH)) -- do_region(opf, i, where + i, dp, io); -+ do_region(opf, i, where + i, dp, io, ioprio); - } - - /* -@@ -413,7 +414,7 @@ static void sync_io_complete(unsigned long error, void *context) - - static int sync_io(struct dm_io_client *client, unsigned int num_regions, - struct dm_io_region *where, blk_opf_t opf, struct dpages *dp, -- unsigned long *error_bits) -+ unsigned long *error_bits, unsigned short ioprio) - { - struct io *io; - struct sync_io sio; -@@ -435,7 +436,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - -- dispatch_io(opf, num_regions, where, dp, io, 1); -+ dispatch_io(opf, num_regions, where, dp, io, 1, ioprio); - - wait_for_completion_io(&sio.wait); - -@@ -447,7 +448,8 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, - - static int async_io(struct dm_io_client *client, unsigned int num_regions, - struct dm_io_region *where, blk_opf_t opf, -- struct dpages *dp, io_notify_fn fn, void *context) -+ struct dpages *dp, io_notify_fn fn, void *context, -+ unsigned short ioprio) - { - struct io *io; - -@@ -467,7 +469,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - -- dispatch_io(opf, num_regions, where, dp, io, 0); -+ dispatch_io(opf, num_regions, where, dp, io, 0, ioprio); - return 0; - } - -@@ -509,7 +511,8 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp, - } - - int dm_io(struct dm_io_request *io_req, unsigned int num_regions, -- struct dm_io_region *where, unsigned long *sync_error_bits) -+ struct dm_io_region *where, unsigned long *sync_error_bits, -+ unsigned short ioprio) - { - int r; - struct dpages dp; -@@ -520,11 +523,11 @@ int dm_io(struct dm_io_request *io_req, unsigned int num_regions, - - if (!io_req->notify.fn) - return sync_io(io_req->client, num_regions, where, -- io_req->bi_opf, &dp, sync_error_bits); -+ io_req->bi_opf, &dp, sync_error_bits, ioprio); - - return async_io(io_req->client, num_regions, where, - io_req->bi_opf, &dp, io_req->notify.fn, -- io_req->notify.context); -+ io_req->notify.context, ioprio); - } - EXPORT_SYMBOL(dm_io); - -diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c -index 0ef78e56aa88c..fda51bd140ed3 100644 ---- a/drivers/md/dm-kcopyd.c -+++ b/drivers/md/dm-kcopyd.c -@@ -572,9 +572,9 @@ static int run_io_job(struct kcopyd_job *job) - io_job_start(job->kc->throttle); - - if (job->op == REQ_OP_READ) -- r = dm_io(&io_req, 1, &job->source, NULL); -+ r = dm_io(&io_req, 1, &job->source, NULL, IOPRIO_DEFAULT); - else -- r = dm_io(&io_req, job->num_dests, job->dests, NULL); -+ r = dm_io(&io_req, job->num_dests, job->dests, NULL, IOPRIO_DEFAULT); - - return r; - } -diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c -index 05141eea18d3c..da77878cb2c02 100644 ---- a/drivers/md/dm-log.c -+++ b/drivers/md/dm-log.c -@@ -295,7 +295,7 @@ static int rw_header(struct log_c *lc, enum req_op op) - { - lc->io_req.bi_opf = op; - -- return dm_io(&lc->io_req, 1, &lc->header_location, NULL); -+ return dm_io(&lc->io_req, 1, &lc->header_location, NULL, IOPRIO_DEFAULT); - } - - static int flush_header(struct log_c *lc) -@@ -308,7 +308,7 @@ static int flush_header(struct log_c *lc) - - lc->io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; - -- return dm_io(&lc->io_req, 1, &null_location, NULL); -+ return dm_io(&lc->io_req, 1, &null_location, NULL, IOPRIO_DEFAULT); - } - - static int read_header(struct log_c *log) -@@ -756,8 +756,8 @@ static void core_set_region_sync(struct dm_dirty_log *log, region_t region, - log_clear_bit(lc, lc->recovering_bits, region); - if (in_sync) { - log_set_bit(lc, lc->sync_bits, region); -- lc->sync_count++; -- } else if (log_test_bit(lc->sync_bits, region)) { -+ lc->sync_count++; -+ } else if (log_test_bit(lc->sync_bits, region)) { - lc->sync_count--; - log_clear_bit(lc, lc->sync_bits, region); - } -@@ -765,9 +765,9 @@ static void core_set_region_sync(struct dm_dirty_log *log, region_t region, - - static region_t core_get_sync_count(struct dm_dirty_log *log) - { -- struct log_c *lc = (struct log_c *) log->context; -+ struct log_c *lc = (struct log_c *) log->context; - -- return lc->sync_count; -+ return lc->sync_count; - } - - #define DMEMIT_SYNC \ -diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c -index 4b7528dc2fd08..bf833ca880bc1 100644 ---- a/drivers/md/dm-raid.c -+++ b/drivers/md/dm-raid.c -@@ -362,8 +362,8 @@ static struct { - const int mode; - const char *param; - } _raid456_journal_mode[] = { -- { R5C_JOURNAL_MODE_WRITE_THROUGH , "writethrough" }, -- { R5C_JOURNAL_MODE_WRITE_BACK , "writeback" } -+ { R5C_JOURNAL_MODE_WRITE_THROUGH, "writethrough" }, -+ { R5C_JOURNAL_MODE_WRITE_BACK, "writeback" } - }; - - /* Return MD raid4/5/6 journal mode for dm @journal_mode one */ -@@ -1114,7 +1114,7 @@ static int validate_raid_redundancy(struct raid_set *rs) - * [stripe_cache ] Stripe cache size for higher RAIDs - * [region_size ] Defines granularity of bitmap - * [journal_dev ] raid4/5/6 journaling deviice -- * (i.e. write hole closing log) -+ * (i.e. write hole closing log) - * - * RAID10-only options: - * [raid10_copies <# copies>] Number of copies. (Default: 2) -@@ -3325,14 +3325,14 @@ static int raid_map(struct dm_target *ti, struct bio *bio) - struct mddev *mddev = &rs->md; - - /* -- * If we're reshaping to add disk(s)), ti->len and -+ * If we're reshaping to add disk(s), ti->len and - * mddev->array_sectors will differ during the process - * (ti->len > mddev->array_sectors), so we have to requeue - * bios with addresses > mddev->array_sectors here or - * there will occur accesses past EOD of the component - * data images thus erroring the raid set. - */ -- if (unlikely(bio_end_sector(bio) > mddev->array_sectors)) -+ if (unlikely(bio_has_data(bio) && bio_end_sector(bio) > mddev->array_sectors)) - return DM_MAPIO_REQUEUE; - - md_handle_request(mddev, bio); -@@ -3999,7 +3999,7 @@ static int raid_preresume(struct dm_target *ti) - } - - /* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) or grown device size */ -- if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap && -+ if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap && - (test_bit(RT_FLAG_RS_GROW, &rs->runtime_flags) || - (rs->requested_bitmap_chunk_sectors && - mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)))) { -diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c -index c38e63706d911..1004199ae77ac 100644 ---- a/drivers/md/dm-raid1.c -+++ b/drivers/md/dm-raid1.c -@@ -273,7 +273,7 @@ static int mirror_flush(struct dm_target *ti) - } - - error_bits = -1; -- dm_io(&io_req, ms->nr_mirrors, io, &error_bits); -+ dm_io(&io_req, ms->nr_mirrors, io, &error_bits, IOPRIO_DEFAULT); - if (unlikely(error_bits != 0)) { - for (i = 0; i < ms->nr_mirrors; i++) - if (test_bit(i, &error_bits)) -@@ -543,7 +543,7 @@ static void read_async_bio(struct mirror *m, struct bio *bio) - - map_region(&io, m, bio); - bio_set_m(bio, m); -- BUG_ON(dm_io(&io_req, 1, &io, NULL)); -+ BUG_ON(dm_io(&io_req, 1, &io, NULL, IOPRIO_DEFAULT)); - } - - static inline int region_in_sync(struct mirror_set *ms, region_t region, -@@ -670,7 +670,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio) - */ - bio_set_m(bio, get_default_mirror(ms)); - -- BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL)); -+ BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL, IOPRIO_DEFAULT)); - } - - static void do_writes(struct mirror_set *ms, struct bio_list *writes) -@@ -902,7 +902,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, - if (IS_ERR(ms->io_client)) { - ti->error = "Error creating dm_io client"; - kfree(ms); -- return NULL; -+ return NULL; - } - - ms->rh = dm_region_hash_create(ms, dispatch_bios, wakeup_mirrord, -diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c -index 80b95746a43e0..eee1cd3aa3fcf 100644 ---- a/drivers/md/dm-snap-persistent.c -+++ b/drivers/md/dm-snap-persistent.c -@@ -220,7 +220,7 @@ static void do_metadata(struct work_struct *work) - { - struct mdata_req *req = container_of(work, struct mdata_req, work); - -- req->result = dm_io(req->io_req, 1, req->where, NULL); -+ req->result = dm_io(req->io_req, 1, req->where, NULL, IOPRIO_DEFAULT); - } - - /* -@@ -244,7 +244,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, blk_opf_t opf, - struct mdata_req req; - - if (!metadata) -- return dm_io(&io_req, 1, &where, NULL); -+ return dm_io(&io_req, 1, &where, NULL, IOPRIO_DEFAULT); - - req.where = &where; - req.io_req = &io_req; -diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c -index e0367a672eabf..aabb2435070b8 100644 ---- a/drivers/md/dm-table.c -+++ b/drivers/md/dm-table.c -@@ -72,7 +72,7 @@ static sector_t high(struct dm_table *t, unsigned int l, unsigned int n) - n = get_child(n, CHILDREN_PER_NODE - 1); - - if (n >= t->counts[l]) -- return (sector_t) - 1; -+ return (sector_t) -1; - - return get_node(t, l, n)[KEYS_PER_NODE - 1]; - } -@@ -1533,7 +1533,7 @@ static bool dm_table_any_dev_attr(struct dm_table *t, - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, func, data)) - return true; -- } -+ } - - return false; - } -diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c -index 601f9e4e6234f..f24d89af7c5f0 100644 ---- a/drivers/md/dm-thin.c -+++ b/drivers/md/dm-thin.c -@@ -1179,9 +1179,9 @@ static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m) - discard_parent = bio_alloc(NULL, 1, 0, GFP_NOIO); - discard_parent->bi_end_io = passdown_endio; - discard_parent->bi_private = m; -- if (m->maybe_shared) -- passdown_double_checking_shared_status(m, discard_parent); -- else { -+ if (m->maybe_shared) -+ passdown_double_checking_shared_status(m, discard_parent); -+ else { - struct discard_op op; - - begin_discard(&op, tc, discard_parent); -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index b48e1b59e6da4..6a707b41dc865 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -503,7 +503,7 @@ static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, - io_loc.bdev = v->data_dev->bdev; - io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT); - io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT); -- r = dm_io(&io_req, 1, &io_loc, NULL); -+ r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) - goto free_ret; - -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index 4620a98c99561..db93a91169d5e 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -80,12 +80,12 @@ struct dm_verity_io { - /* original value of bio->bi_end_io */ - bio_end_io_t *orig_bi_end_io; - -+ struct bvec_iter iter; -+ - sector_t block; - unsigned int n_blocks; - bool in_tasklet; - -- struct bvec_iter iter; -- - struct work_struct work; - - char *recheck_buffer; -diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c -index c6ff43a8f0b25..20fc84b24fc75 100644 ---- a/drivers/md/dm-writecache.c -+++ b/drivers/md/dm-writecache.c -@@ -531,7 +531,7 @@ static void ssd_commit_flushed(struct dm_writecache *wc, bool wait_for_ios) - req.notify.context = &endio; - - /* writing via async dm-io (implied by notify.fn above) won't return an error */ -- (void) dm_io(&req, 1, ®ion, NULL); -+ (void) dm_io(&req, 1, ®ion, NULL, IOPRIO_DEFAULT); - i = j; - } - -@@ -568,7 +568,7 @@ static void ssd_commit_superblock(struct dm_writecache *wc) - req.notify.fn = NULL; - req.notify.context = NULL; - -- r = dm_io(&req, 1, ®ion, NULL); -+ r = dm_io(&req, 1, ®ion, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) - writecache_error(wc, r, "error writing superblock"); - } -@@ -596,7 +596,7 @@ static void writecache_disk_flush(struct dm_writecache *wc, struct dm_dev *dev) - req.client = wc->dm_io; - req.notify.fn = NULL; - -- r = dm_io(&req, 1, ®ion, NULL); -+ r = dm_io(&req, 1, ®ion, NULL, IOPRIO_DEFAULT); - if (unlikely(r)) - writecache_error(wc, r, "error flushing metadata: %d", r); - } -@@ -984,7 +984,7 @@ static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors - req.client = wc->dm_io; - req.notify.fn = NULL; - -- return dm_io(&req, 1, ®ion, NULL); -+ return dm_io(&req, 1, ®ion, NULL, IOPRIO_DEFAULT); - } - - static void writecache_resume(struct dm_target *ti) -diff --git a/drivers/md/dm.c b/drivers/md/dm.c -index 0ec85d159bcde..29270f6f272f6 100644 ---- a/drivers/md/dm.c -+++ b/drivers/md/dm.c -@@ -2897,6 +2897,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned int suspend - - static void __dm_internal_resume(struct mapped_device *md) - { -+ int r; -+ struct dm_table *map; -+ - BUG_ON(!md->internal_suspend_count); - - if (--md->internal_suspend_count) -@@ -2905,12 +2908,23 @@ static void __dm_internal_resume(struct mapped_device *md) - if (dm_suspended_md(md)) - goto done; /* resume from nested suspend */ - -- /* -- * NOTE: existing callers don't need to call dm_table_resume_targets -- * (which may fail -- so best to avoid it for now by passing NULL map) -- */ -- (void) __dm_resume(md, NULL); -- -+ map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock)); -+ r = __dm_resume(md, map); -+ if (r) { -+ /* -+ * If a preresume method of some target failed, we are in a -+ * tricky situation. We can't return an error to the caller. We -+ * can't fake success because then the "resume" and -+ * "postsuspend" methods would not be paired correctly, and it -+ * would break various targets, for example it would cause list -+ * corruption in the "origin" target. -+ * -+ * So, we fake normal suspend here, to make sure that the -+ * "resume" and "postsuspend" methods will be paired correctly. -+ */ -+ DMERR("Preresume method failed: %d", r); -+ set_bit(DMF_SUSPENDED, &md->flags); -+ } - done: - clear_bit(DMF_SUSPENDED_INTERNALLY, &md->flags); - smp_mb__after_atomic(); -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 846bdee4daa0e..788acc81e7a84 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -4903,11 +4903,21 @@ action_store(struct mddev *mddev, const char *page, size_t len) - return -EINVAL; - err = mddev_lock(mddev); - if (!err) { -- if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) -+ if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { - err = -EBUSY; -- else { -+ } else if (mddev->reshape_position == MaxSector || -+ mddev->pers->check_reshape == NULL || -+ mddev->pers->check_reshape(mddev)) { - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - err = mddev->pers->start_reshape(mddev); -+ } else { -+ /* -+ * If reshape is still in progress, and -+ * md_check_recovery() can continue to reshape, -+ * don't restart reshape because data can be -+ * corrupted for raid456. -+ */ -+ clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - } - mddev_unlock(mddev); - } -@@ -6233,7 +6243,15 @@ static void md_clean(struct mddev *mddev) - mddev->persistent = 0; - mddev->level = LEVEL_NONE; - mddev->clevel[0] = 0; -- mddev->flags = 0; -+ /* -+ * Don't clear MD_CLOSING, or mddev can be opened again. -+ * 'hold_active != 0' means mddev is still in the creation -+ * process and will be used later. -+ */ -+ if (mddev->hold_active) -+ mddev->flags = 0; -+ else -+ mddev->flags &= BIT_ULL_MASK(MD_CLOSING); - mddev->sb_flags = 0; - mddev->ro = MD_RDWR; - mddev->metadata_type[0] = 0; -@@ -7561,7 +7579,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, - int err = 0; - void __user *argp = (void __user *)arg; - struct mddev *mddev = NULL; -- bool did_set_md_closing = false; - - if (!md_ioctl_valid(cmd)) - return -ENOTTY; -@@ -7648,7 +7665,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, - err = -EBUSY; - goto out; - } -- did_set_md_closing = true; - mutex_unlock(&mddev->open_mutex); - sync_blockdev(bdev); - } -@@ -7811,7 +7827,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, - mddev->hold_active = 0; - mddev_unlock(mddev); - out: -- if(did_set_md_closing) -+ if (cmd == STOP_ARRAY_RO || (err && cmd == STOP_ARRAY)) - clear_bit(MD_CLOSING, &mddev->flags); - return err; - } -diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c -index 1cc783d7030d8..18d949d63543b 100644 ---- a/drivers/md/persistent-data/dm-btree.c -+++ b/drivers/md/persistent-data/dm-btree.c -@@ -726,7 +726,7 @@ static int shadow_child(struct dm_btree_info *info, struct dm_btree_value_type * - * nodes, so saves metadata space. - */ - static int split_two_into_three(struct shadow_spine *s, unsigned int parent_index, -- struct dm_btree_value_type *vt, uint64_t key) -+ struct dm_btree_value_type *vt, uint64_t key) - { - int r; - unsigned int middle_index; -@@ -781,7 +781,7 @@ static int split_two_into_three(struct shadow_spine *s, unsigned int parent_inde - if (shadow_current(s) != right) - unlock_block(s->info, right); - -- return r; -+ return r; - } - - -@@ -1216,7 +1216,7 @@ int btree_get_overwrite_leaf(struct dm_btree_info *info, dm_block_t root, - static bool need_insert(struct btree_node *node, uint64_t *keys, - unsigned int level, unsigned int index) - { -- return ((index >= le32_to_cpu(node->header.nr_entries)) || -+ return ((index >= le32_to_cpu(node->header.nr_entries)) || - (le64_to_cpu(node->keys[index]) != keys[level])); - } - -diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c -index af800efed9f3c..4833a3998c1d9 100644 ---- a/drivers/md/persistent-data/dm-space-map-common.c -+++ b/drivers/md/persistent-data/dm-space-map-common.c -@@ -390,7 +390,7 @@ int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, - } - - int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, -- dm_block_t begin, dm_block_t end, dm_block_t *b) -+ dm_block_t begin, dm_block_t end, dm_block_t *b) - { - int r; - uint32_t count; -diff --git a/drivers/md/persistent-data/dm-space-map-common.h b/drivers/md/persistent-data/dm-space-map-common.h -index 706ceb85d6800..63d9a72e3265c 100644 ---- a/drivers/md/persistent-data/dm-space-map-common.h -+++ b/drivers/md/persistent-data/dm-space-map-common.h -@@ -120,7 +120,7 @@ int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result); - int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, - dm_block_t end, dm_block_t *result); - int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, -- dm_block_t begin, dm_block_t end, dm_block_t *result); -+ dm_block_t begin, dm_block_t end, dm_block_t *result); - - /* - * The next three functions return (via nr_allocations) the net number of -diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index 7b318e7e8d459..009f7ffe4e10c 100644 ---- a/drivers/md/raid10.c -+++ b/drivers/md/raid10.c -@@ -920,6 +920,7 @@ static void flush_pending_writes(struct r10conf *conf) - - raid1_submit_write(bio); - bio = next; -+ cond_resched(); - } - blk_finish_plug(&plug); - } else -@@ -1130,6 +1131,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) - - raid1_submit_write(bio); - bio = next; -+ cond_resched(); - } - kfree(plug); - } -diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c -index 303d02b1d71c9..fe30f5b0050dd 100644 ---- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c -+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c -@@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) - { - unsigned pat; - unsigned plane; -+ int ret = 0; - - tpg->max_line_width = max_w; - for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { -@@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) - - tpg->lines[pat][plane] = - vzalloc(array3_size(max_w, 2, pixelsz)); -- if (!tpg->lines[pat][plane]) -- return -ENOMEM; -+ if (!tpg->lines[pat][plane]) { -+ ret = -ENOMEM; -+ goto free_lines; -+ } - if (plane == 0) - continue; - tpg->downsampled_lines[pat][plane] = - vzalloc(array3_size(max_w, 2, pixelsz)); -- if (!tpg->downsampled_lines[pat][plane]) -- return -ENOMEM; -+ if (!tpg->downsampled_lines[pat][plane]) { -+ ret = -ENOMEM; -+ goto free_lines; -+ } - } - } - for (plane = 0; plane < TPG_MAX_PLANES; plane++) { -@@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) - - tpg->contrast_line[plane] = - vzalloc(array_size(pixelsz, max_w)); -- if (!tpg->contrast_line[plane]) -- return -ENOMEM; -+ if (!tpg->contrast_line[plane]) { -+ ret = -ENOMEM; -+ goto free_contrast_line; -+ } - tpg->black_line[plane] = - vzalloc(array_size(pixelsz, max_w)); -- if (!tpg->black_line[plane]) -- return -ENOMEM; -+ if (!tpg->black_line[plane]) { -+ ret = -ENOMEM; -+ goto free_contrast_line; -+ } - tpg->random_line[plane] = - vzalloc(array3_size(max_w, 2, pixelsz)); -- if (!tpg->random_line[plane]) -- return -ENOMEM; -+ if (!tpg->random_line[plane]) { -+ ret = -ENOMEM; -+ goto free_contrast_line; -+ } - } - return 0; -+ -+free_contrast_line: -+ for (plane = 0; plane < TPG_MAX_PLANES; plane++) { -+ vfree(tpg->contrast_line[plane]); -+ vfree(tpg->black_line[plane]); -+ vfree(tpg->random_line[plane]); -+ tpg->contrast_line[plane] = NULL; -+ tpg->black_line[plane] = NULL; -+ tpg->random_line[plane] = NULL; -+ } -+free_lines: -+ for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) -+ for (plane = 0; plane < TPG_MAX_PLANES; plane++) { -+ vfree(tpg->lines[pat][plane]); -+ tpg->lines[pat][plane] = NULL; -+ if (plane == 0) -+ continue; -+ vfree(tpg->downsampled_lines[pat][plane]); -+ tpg->downsampled_lines[pat][plane] = NULL; -+ } -+ return ret; - } - EXPORT_SYMBOL_GPL(tpg_alloc); - -diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c -index d352e028491aa..aefee2277254d 100644 ---- a/drivers/media/dvb-core/dvbdev.c -+++ b/drivers/media/dvb-core/dvbdev.c -@@ -494,6 +494,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); - if (!dvbdevfops) { - kfree(dvbdev); -+ *pdvbdev = NULL; - mutex_unlock(&dvbdev_register_lock); - return -ENOMEM; - } -@@ -502,6 +503,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - if (!new_node) { - kfree(dvbdevfops); - kfree(dvbdev); -+ *pdvbdev = NULL; - mutex_unlock(&dvbdev_register_lock); - return -ENOMEM; - } -@@ -535,6 +537,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - } - list_del (&dvbdev->list_head); - kfree(dvbdev); -+ *pdvbdev = NULL; - up_write(&minor_rwsem); - mutex_unlock(&dvbdev_register_lock); - return -EINVAL; -@@ -557,6 +560,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - dvb_media_device_free(dvbdev); - list_del (&dvbdev->list_head); - kfree(dvbdev); -+ *pdvbdev = NULL; - mutex_unlock(&dvbdev_register_lock); - return ret; - } -@@ -575,6 +579,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - dvb_media_device_free(dvbdev); - list_del (&dvbdev->list_head); - kfree(dvbdev); -+ *pdvbdev = NULL; - mutex_unlock(&dvbdev_register_lock); - return PTR_ERR(clsdev); - } -diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c -index 04556b77c16c9..0977564a4a1a4 100644 ---- a/drivers/media/dvb-frontends/stv0367.c -+++ b/drivers/media/dvb-frontends/stv0367.c -@@ -118,50 +118,32 @@ static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_S - } - }; - --static --int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len) -+static noinline_for_stack -+int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) - { -- u8 buf[MAX_XFER_SIZE]; -+ u8 buf[3] = { MSB(reg), LSB(reg), data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, -- .len = len + 2 -+ .len = 3, - }; - int ret; - -- if (2 + len > sizeof(buf)) { -- printk(KERN_WARNING -- "%s: i2c wr reg=%04x: len=%d is too big!\n", -- KBUILD_MODNAME, reg, len); -- return -EINVAL; -- } -- -- -- buf[0] = MSB(reg); -- buf[1] = LSB(reg); -- memcpy(buf + 2, data, len); -- - if (i2cdebug) - printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__, -- state->config->demod_address, reg, buf[2]); -+ state->config->demod_address, reg, data); - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) - printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n", -- __func__, state->config->demod_address, reg, buf[2]); -+ __func__, state->config->demod_address, reg, data); - - return (ret != 1) ? -EREMOTEIO : 0; - } - --static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) --{ -- u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ -- -- return stv0367_writeregs(state, reg, &tmp, 1); --} -- --static u8 stv0367_readreg(struct stv0367_state *state, u16 reg) -+static noinline_for_stack -+u8 stv0367_readreg(struct stv0367_state *state, u16 reg) - { - u8 b0[] = { 0, 0 }; - u8 b1[] = { 0 }; -diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c -index 200841c1f5cf0..68628ccecd161 100644 ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -2094,9 +2094,6 @@ static int tc358743_probe(struct i2c_client *client) - state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24; - - sd->dev = &client->dev; -- err = v4l2_async_register_subdev(sd); -- if (err < 0) -- goto err_hdl; - - mutex_init(&state->confctl_mutex); - -@@ -2154,6 +2151,10 @@ static int tc358743_probe(struct i2c_client *client) - if (err) - goto err_work_queues; - -+ err = v4l2_async_register_subdev(sd); -+ if (err < 0) -+ goto err_work_queues; -+ - v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, - client->addr << 1, client->adapter->name); - -diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c -index b065ccd069140..378a1cba0144f 100644 ---- a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c -+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c -@@ -26,7 +26,7 @@ static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg) - vpu->inst_addr = msg->vpu_inst_addr; - } - --static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len, -+static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len, - void *priv) - { - const struct mdp_ipi_comm_ack *msg = data; -diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c -index cfc7ebed8fb7a..1ec29f1b163a1 100644 ---- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c -+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c -@@ -29,15 +29,7 @@ static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id, - mtk_vcodec_ipi_handler handler, - const char *name, void *priv) - { -- /* -- * The handler we receive takes a void * as its first argument. We -- * cannot change this because it needs to be passed down to the rproc -- * subsystem when SCP is used. VPU takes a const argument, which is -- * more constrained, so the conversion below is safe. -- */ -- ipi_handler_t handler_const = (ipi_handler_t)handler; -- -- return vpu_ipi_register(fw->pdev, id, handler_const, name, priv); -+ return vpu_ipi_register(fw->pdev, id, handler, name, priv); - } - - static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf, -diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c -index 6beab9e86a22a..44adf5cfc9bb2 100644 ---- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c -+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c -@@ -635,7 +635,7 @@ int vpu_load_firmware(struct platform_device *pdev) - } - EXPORT_SYMBOL_GPL(vpu_load_firmware); - --static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv) -+static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv) - { - struct mtk_vpu *vpu = priv; - const struct vpu_run *run = data; -diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.h b/drivers/media/platform/mediatek/vpu/mtk_vpu.h -index a56053ff135af..da05f3e740810 100644 ---- a/drivers/media/platform/mediatek/vpu/mtk_vpu.h -+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.h -@@ -17,7 +17,7 @@ - * VPU interfaces with other blocks by share memory and interrupt. - */ - --typedef void (*ipi_handler_t) (const void *data, -+typedef void (*ipi_handler_t) (void *data, - unsigned int len, - void *priv); - -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c -index d4540684ea9af..0bcb9db5ad190 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c -@@ -701,6 +701,9 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx) - unsigned int i; - u32 status; - -+ if (!rkisp1->irqs_enabled) -+ return IRQ_NONE; -+ - status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS); - if (!status) - return IRQ_NONE; -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h -index f9ec1c6138947..5776292f914a4 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h -@@ -467,6 +467,7 @@ struct rkisp1_debug { - * @debug: debug params to be exposed on debugfs - * @info: version-specific ISP information - * @irqs: IRQ line numbers -+ * @irqs_enabled: the hardware is enabled and can cause interrupts - */ - struct rkisp1_device { - void __iomem *base_addr; -@@ -488,6 +489,7 @@ struct rkisp1_device { - struct rkisp1_debug debug; - const struct rkisp1_info *info; - int irqs[RKISP1_NUM_IRQS]; -+ bool irqs_enabled; - }; - - /* -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c -index e862f515cc6d3..95b6e41c48ec2 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c -@@ -211,6 +211,9 @@ irqreturn_t rkisp1_csi_isr(int irq, void *ctx) - struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); - u32 val, status; - -+ if (!rkisp1->irqs_enabled) -+ return IRQ_NONE; -+ - status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS); - if (!status) - return IRQ_NONE; -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -index 41abb18b00acb..7a3b69ba51b97 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -@@ -305,6 +305,24 @@ static int __maybe_unused rkisp1_runtime_suspend(struct device *dev) - { - struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); - -+ rkisp1->irqs_enabled = false; -+ /* Make sure the IRQ handler will see the above */ -+ mb(); -+ -+ /* -+ * Wait until any running IRQ handler has returned. The IRQ handler -+ * may get called even after this (as it's a shared interrupt line) -+ * but the 'irqs_enabled' flag will make the handler return immediately. -+ */ -+ for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) { -+ if (rkisp1->irqs[il] == -1) -+ continue; -+ -+ /* Skip if the irq line is the same as previous */ -+ if (il == 0 || rkisp1->irqs[il - 1] != rkisp1->irqs[il]) -+ synchronize_irq(rkisp1->irqs[il]); -+ } -+ - clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks); - return pinctrl_pm_select_sleep_state(dev); - } -@@ -321,6 +339,10 @@ static int __maybe_unused rkisp1_runtime_resume(struct device *dev) - if (ret) - return ret; - -+ rkisp1->irqs_enabled = true; -+ /* Make sure the IRQ handler will see the above */ -+ mb(); -+ - return 0; - } - -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c -index 00dca284c1222..2af5c1a48070b 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c -@@ -1023,6 +1023,9 @@ irqreturn_t rkisp1_isp_isr(int irq, void *ctx) - struct rkisp1_device *rkisp1 = dev_get_drvdata(dev); - u32 status, isp_err; - -+ if (!rkisp1->irqs_enabled) -+ return IRQ_NONE; -+ - status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS); - if (!status) - return IRQ_NONE; -diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c -index aa65d70b6270a..7a2f558c981db 100644 ---- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c -+++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c -@@ -66,6 +66,7 @@ static void deinterlace_device_run(void *priv) - struct vb2_v4l2_buffer *src, *dst; - unsigned int hstep, vstep; - dma_addr_t addr; -+ int i; - - src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); -@@ -160,6 +161,26 @@ static void deinterlace_device_run(void *priv) - deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep); - deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep); - -+ /* neutral filter coefficients */ -+ deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, -+ DEINTERLACE_FRM_CTRL_COEF_ACCESS); -+ readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val, -+ val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40); -+ -+ for (i = 0; i < 32; i++) { -+ deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4, -+ DEINTERLACE_IDENTITY_COEF); -+ deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4, -+ DEINTERLACE_IDENTITY_COEF); -+ deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4, -+ DEINTERLACE_IDENTITY_COEF); -+ deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4, -+ DEINTERLACE_IDENTITY_COEF); -+ } -+ -+ deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL, -+ DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0); -+ - deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL, - DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK, - DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field)); -@@ -248,7 +269,6 @@ static irqreturn_t deinterlace_irq(int irq, void *data) - static void deinterlace_init(struct deinterlace_dev *dev) - { - u32 val; -- int i; - - deinterlace_write(dev, DEINTERLACE_BYPASS, - DEINTERLACE_BYPASS_CSC); -@@ -284,27 +304,7 @@ static void deinterlace_init(struct deinterlace_dev *dev) - - deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF, - DEINTERLACE_CHROMA_DIFF_TH_MSK, -- DEINTERLACE_CHROMA_DIFF_TH(5)); -- -- /* neutral filter coefficients */ -- deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, -- DEINTERLACE_FRM_CTRL_COEF_ACCESS); -- readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val, -- val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40); -- -- for (i = 0; i < 32; i++) { -- deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4, -- DEINTERLACE_IDENTITY_COEF); -- deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4, -- DEINTERLACE_IDENTITY_COEF); -- deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4, -- DEINTERLACE_IDENTITY_COEF); -- deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4, -- DEINTERLACE_IDENTITY_COEF); -- } -- -- deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL, -- DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0); -+ DEINTERLACE_CHROMA_DIFF_TH(31)); - } - - static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file) -@@ -931,11 +931,18 @@ static int deinterlace_runtime_resume(struct device *device) - return ret; - } - -+ ret = reset_control_deassert(dev->rstc); -+ if (ret) { -+ dev_err(dev->dev, "Failed to apply reset\n"); -+ -+ goto err_exclusive_rate; -+ } -+ - ret = clk_prepare_enable(dev->bus_clk); - if (ret) { - dev_err(dev->dev, "Failed to enable bus clock\n"); - -- goto err_exclusive_rate; -+ goto err_rst; - } - - ret = clk_prepare_enable(dev->mod_clk); -@@ -952,23 +959,16 @@ static int deinterlace_runtime_resume(struct device *device) - goto err_mod_clk; - } - -- ret = reset_control_deassert(dev->rstc); -- if (ret) { -- dev_err(dev->dev, "Failed to apply reset\n"); -- -- goto err_ram_clk; -- } -- - deinterlace_init(dev); - - return 0; - --err_ram_clk: -- clk_disable_unprepare(dev->ram_clk); - err_mod_clk: - clk_disable_unprepare(dev->mod_clk); - err_bus_clk: - clk_disable_unprepare(dev->bus_clk); -+err_rst: -+ reset_control_assert(dev->rstc); - err_exclusive_rate: - clk_rate_exclusive_put(dev->mod_clk); - -@@ -979,11 +979,12 @@ static int deinterlace_runtime_suspend(struct device *device) - { - struct deinterlace_dev *dev = dev_get_drvdata(device); - -- reset_control_assert(dev->rstc); -- - clk_disable_unprepare(dev->ram_clk); - clk_disable_unprepare(dev->mod_clk); - clk_disable_unprepare(dev->bus_clk); -+ -+ reset_control_assert(dev->rstc); -+ - clk_rate_exclusive_put(dev->mod_clk); - - return 0; -diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c -index 4d037c92af7c5..bae76023cf71d 100644 ---- a/drivers/media/usb/em28xx/em28xx-cards.c -+++ b/drivers/media/usb/em28xx/em28xx-cards.c -@@ -4094,6 +4094,10 @@ static int em28xx_usb_probe(struct usb_interface *intf, - * topology will likely change after the load of the em28xx subdrivers. - */ - #ifdef CONFIG_MEDIA_CONTROLLER -+ /* -+ * No need to check the return value, the device will still be -+ * usable without media controller API. -+ */ - retval = media_device_register(dev->media_dev); - #endif - -diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c -index 0c24e29843048..eb03f98b2ef11 100644 ---- a/drivers/media/usb/go7007/go7007-driver.c -+++ b/drivers/media/usb/go7007/go7007-driver.c -@@ -80,7 +80,7 @@ static int go7007_load_encoder(struct go7007 *go) - const struct firmware *fw_entry; - char fw_name[] = "go7007/go7007fw.bin"; - void *bounce; -- int fw_len, rv = 0; -+ int fw_len; - u16 intr_val, intr_data; - - if (go->boot_fw == NULL) { -@@ -109,9 +109,11 @@ static int go7007_load_encoder(struct go7007 *go) - go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || - (intr_val & ~0x1) != 0x5a5a) { - v4l2_err(go, "error transferring firmware\n"); -- rv = -1; -+ kfree(go->boot_fw); -+ go->boot_fw = NULL; -+ return -1; - } -- return rv; -+ return 0; - } - - MODULE_FIRMWARE("go7007/go7007fw.bin"); -diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c -index eeb85981e02b6..762c13e49bfa5 100644 ---- a/drivers/media/usb/go7007/go7007-usb.c -+++ b/drivers/media/usb/go7007/go7007-usb.c -@@ -1201,7 +1201,9 @@ static int go7007_usb_probe(struct usb_interface *intf, - u16 channel; - - /* read channel number from GPIO[1:0] */ -- go7007_read_addr(go, 0x3c81, &channel); -+ if (go7007_read_addr(go, 0x3c81, &channel)) -+ goto allocfail; -+ - channel &= 0x3; - go->board_id = GO7007_BOARDID_ADLINK_MPG24; - usb->board = board = &board_adlink_mpg24; -diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c -index 1764674de98bc..73c95ba2328a4 100644 ---- a/drivers/media/usb/pvrusb2/pvrusb2-context.c -+++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c -@@ -90,8 +90,10 @@ static void pvr2_context_destroy(struct pvr2_context *mp) - } - - --static void pvr2_context_notify(struct pvr2_context *mp) -+static void pvr2_context_notify(void *ptr) - { -+ struct pvr2_context *mp = ptr; -+ - pvr2_context_set_notify(mp,!0); - } - -@@ -106,9 +108,7 @@ static void pvr2_context_check(struct pvr2_context *mp) - pvr2_trace(PVR2_TRACE_CTXT, - "pvr2_context %p (initialize)", mp); - /* Finish hardware initialization */ -- if (pvr2_hdw_initialize(mp->hdw, -- (void (*)(void *))pvr2_context_notify, -- mp)) { -+ if (pvr2_hdw_initialize(mp->hdw, pvr2_context_notify, mp)) { - mp->video_stream.stream = - pvr2_hdw_get_video_stream(mp->hdw); - /* Trigger interface initialization. By doing this -@@ -267,9 +267,9 @@ static void pvr2_context_exit(struct pvr2_context *mp) - void pvr2_context_disconnect(struct pvr2_context *mp) - { - pvr2_hdw_disconnect(mp->hdw); -- mp->disconnect_flag = !0; - if (!pvr2_context_shutok()) - pvr2_context_notify(mp); -+ mp->disconnect_flag = !0; - } - - -diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c -index 26811efe0fb58..9a9bae21c6147 100644 ---- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c -+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c -@@ -88,8 +88,10 @@ static int pvr2_dvb_feed_thread(void *data) - return stat; - } - --static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap) -+static void pvr2_dvb_notify(void *ptr) - { -+ struct pvr2_dvb_adapter *adap = ptr; -+ - wake_up(&adap->buffer_wait_data); - } - -@@ -149,7 +151,7 @@ static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap) - } - - pvr2_stream_set_callback(pvr->video_stream.stream, -- (pvr2_stream_callback) pvr2_dvb_notify, adap); -+ pvr2_dvb_notify, adap); - - ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT); - if (ret < 0) return ret; -diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c -index c04ab7258d645..d608b793fa847 100644 ---- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c -+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c -@@ -1033,8 +1033,10 @@ static int pvr2_v4l2_open(struct file *file) - } - - --static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) -+static void pvr2_v4l2_notify(void *ptr) - { -+ struct pvr2_v4l2_fh *fhp = ptr; -+ - wake_up(&fhp->wait_data); - } - -@@ -1067,7 +1069,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) - - hdw = fh->channel.mc_head->hdw; - sp = fh->pdi->stream->stream; -- pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); -+ pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh); - pvr2_hdw_set_stream_type(hdw,fh->pdi->config); - if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret; - return pvr2_ioread_set_enabled(fh->rhp,!0); -@@ -1198,11 +1200,6 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, - dip->minor_type = pvr2_v4l_type_video; - nr_ptr = video_nr; - caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; -- if (!dip->stream) { -- pr_err(KBUILD_MODNAME -- ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n"); -- return; -- } - break; - case VFL_TYPE_VBI: - dip->config = pvr2_config_vbi; -diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c -index be7fde1ed3eaa..97645d6509e1c 100644 ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -1084,11 +1084,17 @@ static int v4l2_m2m_register_entity(struct media_device *mdev, - entity->function = function; - - ret = media_entity_pads_init(entity, num_pads, pads); -- if (ret) -+ if (ret) { -+ kfree(entity->name); -+ entity->name = NULL; - return ret; -+ } - ret = media_device_register_entity(mdev, entity); -- if (ret) -+ if (ret) { -+ kfree(entity->name); -+ entity->name = NULL; - return ret; -+ } - - return 0; - } -diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c -index 5d3715a28b28e..dbe1009943718 100644 ---- a/drivers/mfd/altera-sysmgr.c -+++ b/drivers/mfd/altera-sysmgr.c -@@ -110,7 +110,9 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np, - - dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver, - (void *)sysmgr_np); -- of_node_put(sysmgr_np); -+ if (property) -+ of_node_put(sysmgr_np); -+ - if (!dev) - return ERR_PTR(-EPROBE_DEFER); - -diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c -index 6196724ef39bb..ecfe151220919 100644 ---- a/drivers/mfd/syscon.c -+++ b/drivers/mfd/syscon.c -@@ -223,7 +223,9 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, - return ERR_PTR(-ENODEV); - - regmap = syscon_node_to_regmap(syscon_np); -- of_node_put(syscon_np); -+ -+ if (property) -+ of_node_put(syscon_np); - - return regmap; - } -diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c -index 9aa3027ca25e4..f2abebb2d8574 100644 ---- a/drivers/mmc/host/wmt-sdmmc.c -+++ b/drivers/mmc/host/wmt-sdmmc.c -@@ -886,7 +886,6 @@ static int wmt_mci_remove(struct platform_device *pdev) - { - struct mmc_host *mmc; - struct wmt_mci_priv *priv; -- struct resource *res; - u32 reg_tmp; - - mmc = platform_get_drvdata(pdev); -@@ -914,9 +913,6 @@ static int wmt_mci_remove(struct platform_device *pdev) - clk_disable_unprepare(priv->clk_sdmmc); - clk_put(priv->clk_sdmmc); - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- release_mem_region(res->start, resource_size(res)); -- - mmc_free_host(mmc); - - dev_info(&pdev->dev, "WMT MCI device removed\n"); -diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c -index 19dad5a23f944..8cdb3512107d3 100644 ---- a/drivers/mtd/maps/physmap-core.c -+++ b/drivers/mtd/maps/physmap-core.c -@@ -524,7 +524,7 @@ static int physmap_flash_probe(struct platform_device *dev) - if (!info->maps[i].phys) - info->maps[i].phys = res->start; - -- info->win_order = get_bitmask_order(resource_size(res)) - 1; -+ info->win_order = fls64(resource_size(res)) - 1; - info->maps[i].size = BIT(info->win_order + - (info->gpios ? - info->gpios->ndescs : 0)); -diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c -index 452ecaf7775ac..1cfe3dd0bad4d 100644 ---- a/drivers/mtd/nand/raw/lpc32xx_mlc.c -+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c -@@ -303,8 +303,9 @@ static int lpc32xx_nand_device_ready(struct nand_chip *nand_chip) - return 0; - } - --static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host) -+static irqreturn_t lpc3xxx_nand_irq(int irq, void *data) - { -+ struct lpc32xx_nand_host *host = data; - uint8_t sr; - - /* Clear interrupt flag by reading status */ -@@ -779,7 +780,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) - goto release_dma_chan; - } - -- if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq, -+ if (request_irq(host->irq, &lpc3xxx_nand_irq, - IRQF_TRIGGER_HIGH, DRV_NAME, host)) { - dev_err(&pdev->dev, "Error requesting NAND IRQ\n"); - res = -ENXIO; -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index b988c8a40d536..07065c1af55e4 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -998,20 +998,56 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface) - mutex_unlock(&priv->reg_mutex); - } - -+/* On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE Std -+ * 802.1Q™-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC DA -+ * must only be propagated to C-VLAN and MAC Bridge components. That means -+ * VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports, -+ * these frames are supposed to be processed by the CPU (software). So we make -+ * the switch only forward them to the CPU port. And if received from a CPU -+ * port, forward to a single port. The software is responsible of making the -+ * switch conform to the latter by setting a single port as destination port on -+ * the special tag. -+ * -+ * This switch intellectual property cannot conform to this part of the standard -+ * fully. Whilst the REV_UN frame tag covers the remaining :04-0D and :0F MAC -+ * DAs, it also includes :22-FF which the scope of propagation is not supposed -+ * to be restricted for these MAC DAs. -+ */ - static void - mt753x_trap_frames(struct mt7530_priv *priv) - { -- /* Trap BPDUs to the CPU port(s) */ -- mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, -+ /* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them -+ * VLAN-untagged. -+ */ -+ mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_EG_TAG_MASK | -+ MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK | -+ MT753X_BPDU_PORT_FW_MASK, -+ MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) | -+ MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | - MT753X_BPDU_CPU_ONLY); - -- /* Trap 802.1X PAE frames to the CPU port(s) */ -- mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK, -- MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY)); -+ /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ mt7530_rmw(priv, MT753X_RGAC1, MT753X_R02_EG_TAG_MASK | -+ MT753X_R02_PORT_FW_MASK | MT753X_R01_EG_TAG_MASK | -+ MT753X_R01_PORT_FW_MASK, -+ MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) | -+ MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ MT753X_BPDU_CPU_ONLY); - -- /* Trap LLDP frames with :0E MAC DA to the CPU port(s) */ -- mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK, -- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY)); -+ /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_EG_TAG_MASK | -+ MT753X_R0E_PORT_FW_MASK | MT753X_R03_EG_TAG_MASK | -+ MT753X_R03_PORT_FW_MASK, -+ MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) | -+ MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ MT753X_BPDU_CPU_ONLY); - } - - static int -@@ -2187,11 +2223,11 @@ mt7530_setup(struct dsa_switch *ds) - */ - if (priv->mcm) { - reset_control_assert(priv->rstc); -- usleep_range(1000, 1100); -+ usleep_range(5000, 5100); - reset_control_deassert(priv->rstc); - } else { - gpiod_set_value_cansleep(priv->reset, 0); -- usleep_range(1000, 1100); -+ usleep_range(5000, 5100); - gpiod_set_value_cansleep(priv->reset, 1); - } - -@@ -2401,11 +2437,11 @@ mt7531_setup(struct dsa_switch *ds) - */ - if (priv->mcm) { - reset_control_assert(priv->rstc); -- usleep_range(1000, 1100); -+ usleep_range(5000, 5100); - reset_control_deassert(priv->rstc); - } else { - gpiod_set_value_cansleep(priv->reset, 0); -- usleep_range(1000, 1100); -+ usleep_range(5000, 5100); - gpiod_set_value_cansleep(priv->reset, 1); - } - -diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h -index 6202b0f8c3f34..fa2afa67ceb07 100644 ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -63,14 +63,33 @@ enum mt753x_id { - - /* Registers for BPDU and PAE frame control*/ - #define MT753X_BPC 0x24 --#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) -+#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22) -+#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x) - #define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16) - #define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x) -+#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6) -+#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x) -+#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) -+ -+/* Register for :01 and :02 MAC DA frame control */ -+#define MT753X_RGAC1 0x28 -+#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22) -+#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x) -+#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16) -+#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x) -+#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6) -+#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x) -+#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0) - - /* Register for :03 and :0E MAC DA frame control */ - #define MT753X_RGAC2 0x2c -+#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22) -+#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x) - #define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16) - #define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x) -+#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6) -+#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x) -+#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0) - - enum mt753x_bpdu_port_fw { - MT753X_BPDU_FOLLOW_MFC, -@@ -251,6 +270,7 @@ enum mt7530_port_mode { - enum mt7530_vlan_port_eg_tag { - MT7530_VLAN_EG_DISABLED = 0, - MT7530_VLAN_EG_CONSISTENT = 1, -+ MT7530_VLAN_EG_UNTAGGED = 4, - }; - - enum mt7530_vlan_port_attr { -diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c -index 044b8afde69a0..9e82e7b9c3b72 100644 ---- a/drivers/net/ethernet/amazon/ena/ena_netdev.c -+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c -@@ -3174,22 +3174,6 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_OK; - } - --static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb, -- struct net_device *sb_dev) --{ -- u16 qid; -- /* we suspect that this is good for in--kernel network services that -- * want to loop incoming skb rx to tx in normal user generated traffic, -- * most probably we will not get to this -- */ -- if (skb_rx_queue_recorded(skb)) -- qid = skb_get_rx_queue(skb); -- else -- qid = netdev_pick_tx(dev, skb, NULL); -- -- return qid; --} -- - static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pdev) - { - struct device *dev = &pdev->dev; -@@ -3359,7 +3343,6 @@ static const struct net_device_ops ena_netdev_ops = { - .ndo_open = ena_open, - .ndo_stop = ena_close, - .ndo_start_xmit = ena_start_xmit, -- .ndo_select_queue = ena_select_queue, - .ndo_get_stats64 = ena_get_stats64, - .ndo_tx_timeout = ena_tx_timeout, - .ndo_change_mtu = ena_change_mtu, -diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h -index d8b1824c334d3..0bc1367fd6492 100644 ---- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h -+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h -@@ -1002,9 +1002,6 @@ static inline void bnx2x_set_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid, - static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp, - struct bnx2x_alloc_pool *pool) - { -- if (!pool->page) -- return; -- - put_page(pool->page); - - pool->page = NULL; -@@ -1015,6 +1012,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, - { - int i; - -+ if (!fp->page_pool.page) -+ return; -+ - if (fp->mode == TPA_MODE_DISABLED) - return; - -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c -index 3b6dbf158b98d..f72dc0cee30e5 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c -@@ -76,7 +76,7 @@ static int hns3_dcbnl_ieee_delapp(struct net_device *ndev, struct dcb_app *app) - if (hns3_nic_resetting(ndev)) - return -EBUSY; - -- if (h->kinfo.dcb_ops->ieee_setapp) -+ if (h->kinfo.dcb_ops->ieee_delapp) - return h->kinfo.dcb_ops->ieee_delapp(h, app); - - return -EOPNOTSUPP; -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 48b0cb5ec5d29..27037ce795902 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -2990,7 +2990,10 @@ static int hclge_mac_init(struct hclge_dev *hdev) - int ret; - - hdev->support_sfp_query = true; -- hdev->hw.mac.duplex = HCLGE_MAC_FULL; -+ -+ if (!test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) -+ hdev->hw.mac.duplex = HCLGE_MAC_FULL; -+ - ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, - hdev->hw.mac.duplex, hdev->hw.mac.lane_num); - if (ret) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c -index a40b1583f1149..0f06f95b09bc2 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c -@@ -120,7 +120,7 @@ void hclge_ptp_get_rx_hwts(struct hnae3_handle *handle, struct sk_buff *skb, - u64 ns = nsec; - u32 sec_h; - -- if (!test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags)) -+ if (!hdev->ptp || !test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags)) - return; - - /* Since the BD does not have enough space for the higher 16 bits of -diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c -index 45ce4ed16146e..81d9a5338be5e 100644 ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -6926,44 +6926,31 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt) - static void igb_tsync_interrupt(struct igb_adapter *adapter) - { - struct e1000_hw *hw = &adapter->hw; -- u32 ack = 0, tsicr = rd32(E1000_TSICR); -+ u32 tsicr = rd32(E1000_TSICR); - struct ptp_clock_event event; - - if (tsicr & TSINTR_SYS_WRAP) { - event.type = PTP_CLOCK_PPS; - if (adapter->ptp_caps.pps) - ptp_clock_event(adapter->ptp_clock, &event); -- ack |= TSINTR_SYS_WRAP; - } - - if (tsicr & E1000_TSICR_TXTS) { - /* retrieve hardware timestamp */ - schedule_work(&adapter->ptp_tx_work); -- ack |= E1000_TSICR_TXTS; - } - -- if (tsicr & TSINTR_TT0) { -+ if (tsicr & TSINTR_TT0) - igb_perout(adapter, 0); -- ack |= TSINTR_TT0; -- } - -- if (tsicr & TSINTR_TT1) { -+ if (tsicr & TSINTR_TT1) - igb_perout(adapter, 1); -- ack |= TSINTR_TT1; -- } - -- if (tsicr & TSINTR_AUTT0) { -+ if (tsicr & TSINTR_AUTT0) - igb_extts(adapter, 0); -- ack |= TSINTR_AUTT0; -- } - -- if (tsicr & TSINTR_AUTT1) { -+ if (tsicr & TSINTR_AUTT1) - igb_extts(adapter, 1); -- ack |= TSINTR_AUTT1; -- } -- -- /* acknowledge the interrupts */ -- wr32(E1000_TSICR, ack); - } - - static irqreturn_t igb_msix_other(int irq, void *data) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -index 90be87dc105d3..e6fe599f7bf3a 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -@@ -1346,7 +1346,7 @@ static irqreturn_t cgx_fwi_event_handler(int irq, void *data) - - /* Release thread waiting for completion */ - lmac->cmd_pend = false; -- wake_up_interruptible(&lmac->wq_cmd_cmplt); -+ wake_up(&lmac->wq_cmd_cmplt); - break; - case CGX_EVT_ASYNC: - if (cgx_event_is_linkevent(event)) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c -index 9690ac01f02c8..7d741e3ba8c51 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c -@@ -214,11 +214,12 @@ int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid) - } - EXPORT_SYMBOL(otx2_mbox_busy_poll_for_rsp); - --void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid) -+static void otx2_mbox_msg_send_data(struct otx2_mbox *mbox, int devid, u64 data) - { - struct otx2_mbox_dev *mdev = &mbox->dev[devid]; - struct mbox_hdr *tx_hdr, *rx_hdr; - void *hw_mbase = mdev->hwbase; -+ u64 intr_val; - - tx_hdr = hw_mbase + mbox->tx_start; - rx_hdr = hw_mbase + mbox->rx_start; -@@ -254,14 +255,52 @@ void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid) - - spin_unlock(&mdev->mbox_lock); - -+ /* Check if interrupt pending */ -+ intr_val = readq((void __iomem *)mbox->reg_base + -+ (mbox->trigger | (devid << mbox->tr_shift))); -+ -+ intr_val |= data; - /* The interrupt should be fired after num_msgs is written - * to the shared memory - */ -- writeq(1, (void __iomem *)mbox->reg_base + -+ writeq(intr_val, (void __iomem *)mbox->reg_base + - (mbox->trigger | (devid << mbox->tr_shift))); - } -+ -+void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid) -+{ -+ otx2_mbox_msg_send_data(mbox, devid, MBOX_DOWN_MSG); -+} - EXPORT_SYMBOL(otx2_mbox_msg_send); - -+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid) -+{ -+ otx2_mbox_msg_send_data(mbox, devid, MBOX_UP_MSG); -+} -+EXPORT_SYMBOL(otx2_mbox_msg_send_up); -+ -+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid) -+{ -+ u64 data; -+ -+ data = readq((void __iomem *)mbox->reg_base + -+ (mbox->trigger | (devid << mbox->tr_shift))); -+ -+ /* If data is non-zero wait for ~1ms and return to caller -+ * whether data has changed to zero or not after the wait. -+ */ -+ if (!data) -+ return true; -+ -+ usleep_range(950, 1000); -+ -+ data = readq((void __iomem *)mbox->reg_base + -+ (mbox->trigger | (devid << mbox->tr_shift))); -+ -+ return data == 0; -+} -+EXPORT_SYMBOL(otx2_mbox_wait_for_zero); -+ - struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid, - int size, int size_rsp) - { -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -index 03ebabd616353..be70269e91684 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -@@ -16,6 +16,9 @@ - - #define MBOX_SIZE SZ_64K - -+#define MBOX_DOWN_MSG 1 -+#define MBOX_UP_MSG 2 -+ - /* AF/PF: PF initiated, PF/VF VF initiated */ - #define MBOX_DOWN_RX_START 0 - #define MBOX_DOWN_RX_SIZE (46 * SZ_1K) -@@ -101,6 +104,7 @@ int otx2_mbox_regions_init(struct otx2_mbox *mbox, void __force **hwbase, - struct pci_dev *pdev, void __force *reg_base, - int direction, int ndevs, unsigned long *bmap); - void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid); -+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid); - int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid); - int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid); - struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid, -@@ -118,6 +122,8 @@ static inline struct mbox_msghdr *otx2_mbox_alloc_msg(struct otx2_mbox *mbox, - return otx2_mbox_alloc_msg_rsp(mbox, devid, size, 0); - } - -+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid); -+ - /* Mailbox message types */ - #define MBOX_MSG_MASK 0xFFFF - #define MBOX_MSG_INVALID 0xFFFE -@@ -196,6 +202,9 @@ M(CPT_STATS, 0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp) \ - M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \ - msg_rsp) \ - M(CPT_CTX_CACHE_SYNC, 0xA07, cpt_ctx_cache_sync, msg_req, msg_rsp) \ -+M(CPT_LF_RESET, 0xA08, cpt_lf_reset, cpt_lf_rst_req, msg_rsp) \ -+M(CPT_FLT_ENG_INFO, 0xA09, cpt_flt_eng_info, cpt_flt_eng_info_req, \ -+ cpt_flt_eng_info_rsp) \ - /* SDP mbox IDs (range 0x1000 - 0x11FF) */ \ - M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \ - M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \ -@@ -1702,6 +1711,28 @@ struct cpt_inst_lmtst_req { - u64 rsvd; - }; - -+/* Mailbox message format to request for CPT LF reset */ -+struct cpt_lf_rst_req { -+ struct mbox_msghdr hdr; -+ u32 slot; -+ u32 rsvd; -+}; -+ -+/* Mailbox message format to request for CPT faulted engines */ -+struct cpt_flt_eng_info_req { -+ struct mbox_msghdr hdr; -+ int blkaddr; -+ bool reset; -+ u32 rsvd; -+}; -+ -+struct cpt_flt_eng_info_rsp { -+ struct mbox_msghdr hdr; -+ u64 flt_eng_map[CPT_10K_AF_INT_VEC_RVU]; -+ u64 rcvrd_eng_map[CPT_10K_AF_INT_VEC_RVU]; -+ u64 rsvd; -+}; -+ - struct sdp_node_info { - /* Node to which this PF belons to */ - u8 node_id; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c -index dfd23580e3b8e..d39d86e694ccf 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c -@@ -121,13 +121,17 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event) - static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu) - { - struct mcs_intr_info *req; -- int err, pf; -+ int pf; - - pf = rvu_get_pf(event->pcifunc); - -+ mutex_lock(&rvu->mbox_lock); -+ - req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf); -- if (!req) -+ if (!req) { -+ mutex_unlock(&rvu->mbox_lock); - return -ENOMEM; -+ } - - req->mcs_id = event->mcs_id; - req->intr_mask = event->intr_mask; -@@ -135,10 +139,11 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu) - req->hdr.pcifunc = event->pcifunc; - req->lmac_id = event->lmac_id; - -- otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pf); -- err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf); -- if (err) -- dev_warn(rvu->dev, "MCS notification to pf %d failed\n", pf); -+ otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); -+ -+ otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); -+ -+ mutex_unlock(&rvu->mbox_lock); - - return 0; - } -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -index d88d86bf07b03..a7034b47ed6c9 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -@@ -1164,8 +1164,16 @@ static int rvu_setup_hw_resources(struct rvu *rvu) - goto nix_err; - } - -+ err = rvu_cpt_init(rvu); -+ if (err) { -+ dev_err(rvu->dev, "%s: Failed to initialize cpt\n", __func__); -+ goto mcs_err; -+ } -+ - return 0; - -+mcs_err: -+ rvu_mcs_exit(rvu); - nix_err: - rvu_nix_freemem(rvu); - npa_err: -@@ -2106,7 +2114,7 @@ MBOX_MESSAGES - } - } - --static void __rvu_mbox_handler(struct rvu_work *mwork, int type) -+static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll) - { - struct rvu *rvu = mwork->rvu; - int offset, err, id, devid; -@@ -2173,6 +2181,9 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type) - } - mw->mbox_wrk[devid].num_msgs = 0; - -+ if (poll) -+ otx2_mbox_wait_for_zero(mbox, devid); -+ - /* Send mbox responses to VF/PF */ - otx2_mbox_msg_send(mbox, devid); - } -@@ -2180,15 +2191,18 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type) - static inline void rvu_afpf_mbox_handler(struct work_struct *work) - { - struct rvu_work *mwork = container_of(work, struct rvu_work, work); -+ struct rvu *rvu = mwork->rvu; - -- __rvu_mbox_handler(mwork, TYPE_AFPF); -+ mutex_lock(&rvu->mbox_lock); -+ __rvu_mbox_handler(mwork, TYPE_AFPF, true); -+ mutex_unlock(&rvu->mbox_lock); - } - - static inline void rvu_afvf_mbox_handler(struct work_struct *work) - { - struct rvu_work *mwork = container_of(work, struct rvu_work, work); - -- __rvu_mbox_handler(mwork, TYPE_AFVF); -+ __rvu_mbox_handler(mwork, TYPE_AFVF, false); - } - - static void __rvu_mbox_up_handler(struct rvu_work *mwork, int type) -@@ -2363,6 +2377,8 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw, - } - } - -+ mutex_init(&rvu->mbox_lock); -+ - mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL); - if (!mbox_regions) { - err = -ENOMEM; -@@ -2512,10 +2528,9 @@ static void rvu_queue_work(struct mbox_wq_info *mw, int first, - } - } - --static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq) -+static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq) - { - struct rvu *rvu = (struct rvu *)rvu_irq; -- int vfs = rvu->vfs; - u64 intr; - - intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT); -@@ -2529,6 +2544,18 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq) - - rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr); - -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq) -+{ -+ struct rvu *rvu = (struct rvu *)rvu_irq; -+ int vfs = rvu->vfs; -+ u64 intr; -+ -+ /* Sync with mbox memory region */ -+ rmb(); -+ - /* Handle VF interrupts */ - if (vfs > 64) { - intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1)); -@@ -2865,7 +2892,7 @@ static int rvu_register_interrupts(struct rvu *rvu) - /* Register mailbox interrupt handler */ - sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox"); - ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX), -- rvu_mbox_intr_handler, 0, -+ rvu_mbox_pf_intr_handler, 0, - &rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu); - if (ret) { - dev_err(rvu->dev, -@@ -3039,9 +3066,8 @@ static int rvu_flr_init(struct rvu *rvu) - cfg | BIT_ULL(22)); - } - -- rvu->flr_wq = alloc_workqueue("rvu_afpf_flr", -- WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM, -- 1); -+ rvu->flr_wq = alloc_ordered_workqueue("rvu_afpf_flr", -+ WQ_HIGHPRI | WQ_MEM_RECLAIM); - if (!rvu->flr_wq) - return -ENOMEM; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -index 0b76dfa979d4e..a3ae21398ca74 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -@@ -109,6 +109,8 @@ struct rvu_block { - u64 lfreset_reg; - unsigned char name[NAME_SIZE]; - struct rvu *rvu; -+ u64 cpt_flt_eng_map[3]; -+ u64 cpt_rcvrd_eng_map[3]; - }; - - struct nix_mcast { -@@ -506,6 +508,7 @@ struct rvu { - struct ptp *ptp; - - int mcs_blk_cnt; -+ int cpt_pf_num; - - #ifdef CONFIG_DEBUG_FS - struct rvu_debugfs rvu_dbg; -@@ -520,6 +523,10 @@ struct rvu { - struct list_head mcs_intrq_head; - /* mcs interrupt queue lock */ - spinlock_t mcs_intrq_lock; -+ /* CPT interrupt lock */ -+ spinlock_t cpt_intr_lock; -+ -+ struct mutex mbox_lock; /* Serialize mbox up and down msgs */ - }; - - static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) -@@ -872,6 +879,7 @@ void rvu_cpt_unregister_interrupts(struct rvu *rvu); - int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, - int slot); - int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc); -+int rvu_cpt_init(struct rvu *rvu); - - #define NDC_AF_BANK_MASK GENMASK_ULL(7, 0) - #define NDC_AF_BANK_LINE_MASK GENMASK_ULL(31, 16) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -index bcb4385d0621c..d1e6b12ecfa70 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -@@ -232,7 +232,7 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu) - struct cgx_link_user_info *linfo; - struct cgx_link_info_msg *msg; - unsigned long pfmap; -- int err, pfid; -+ int pfid; - - linfo = &event->link_uinfo; - pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id); -@@ -250,16 +250,22 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu) - continue; - } - -+ mutex_lock(&rvu->mbox_lock); -+ - /* Send mbox message to PF */ - msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid); -- if (!msg) -+ if (!msg) { -+ mutex_unlock(&rvu->mbox_lock); - continue; -+ } -+ - msg->link_info = *linfo; -- otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid); -- err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid); -- if (err) -- dev_warn(rvu->dev, "notification to pf %d failed\n", -- pfid); -+ -+ otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pfid); -+ -+ otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pfid); -+ -+ mutex_unlock(&rvu->mbox_lock); - } while (pfmap); - } - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c -index 38bbae5d9ae05..6fb02b93c1718 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c -@@ -37,34 +37,68 @@ - (_rsp)->free_sts_##etype = free_sts; \ - }) - --static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr) -+static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr) - { - struct rvu_block *block = ptr; - struct rvu *rvu = block->rvu; - int blkaddr = block->addr; -- u64 reg0, reg1, reg2; -- -- reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0)); -- reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1)); -- if (!is_rvu_otx2(rvu)) { -- reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2)); -- dev_err_ratelimited(rvu->dev, -- "Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx", -- reg0, reg1, reg2); -- } else { -- dev_err_ratelimited(rvu->dev, -- "Received CPTAF FLT irq : 0x%llx, 0x%llx", -- reg0, reg1); -+ u64 reg, val; -+ int i, eng; -+ u8 grp; -+ -+ reg = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(vec)); -+ dev_err_ratelimited(rvu->dev, "Received CPTAF FLT%d irq : 0x%llx", vec, reg); -+ -+ i = -1; -+ while ((i = find_next_bit((unsigned long *)®, 64, i + 1)) < 64) { -+ switch (vec) { -+ case 0: -+ eng = i; -+ break; -+ case 1: -+ eng = i + 64; -+ break; -+ case 2: -+ eng = i + 128; -+ break; -+ } -+ grp = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng)) & 0xFF; -+ /* Disable and enable the engine which triggers fault */ -+ rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), 0x0); -+ val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng)); -+ rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val & ~1ULL); -+ -+ rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp); -+ rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL); -+ -+ spin_lock(&rvu->cpt_intr_lock); -+ block->cpt_flt_eng_map[vec] |= BIT_ULL(i); -+ val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(eng)); -+ val = val & 0x3; -+ if (val == 0x1 || val == 0x2) -+ block->cpt_rcvrd_eng_map[vec] |= BIT_ULL(i); -+ spin_unlock(&rvu->cpt_intr_lock); - } -- -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0); -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1); -- if (!is_rvu_otx2(rvu)) -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg); - - return IRQ_HANDLED; - } - -+static irqreturn_t rvu_cpt_af_flt0_intr_handler(int irq, void *ptr) -+{ -+ return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT0, ptr); -+} -+ -+static irqreturn_t rvu_cpt_af_flt1_intr_handler(int irq, void *ptr) -+{ -+ return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT1, ptr); -+} -+ -+static irqreturn_t rvu_cpt_af_flt2_intr_handler(int irq, void *ptr) -+{ -+ return cpt_af_flt_intr_handler(CPT_10K_AF_INT_VEC_FLT2, ptr); -+} -+ - static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr) - { - struct rvu_block *block = ptr; -@@ -119,8 +153,10 @@ static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off) - int i; - - /* Disable all CPT AF interrupts */ -- for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++) -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(0), ~0ULL); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(1), ~0ULL); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(2), 0xFFFF); -+ - rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); - rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); - -@@ -151,7 +187,7 @@ static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr) - - /* Disable all CPT AF interrupts */ - for (i = 0; i < CPT_AF_INT_VEC_RVU; i++) -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), ~0ULL); - rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); - rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); - -@@ -172,16 +208,31 @@ static int cpt_10k_register_interrupts(struct rvu_block *block, int off) - { - struct rvu *rvu = block->rvu; - int blkaddr = block->addr; -+ irq_handler_t flt_fn; - int i, ret; - - for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) { - sprintf(&rvu->irq_name[(off + i) * NAME_SIZE], "CPTAF FLT%d", i); -+ -+ switch (i) { -+ case CPT_10K_AF_INT_VEC_FLT0: -+ flt_fn = rvu_cpt_af_flt0_intr_handler; -+ break; -+ case CPT_10K_AF_INT_VEC_FLT1: -+ flt_fn = rvu_cpt_af_flt1_intr_handler; -+ break; -+ case CPT_10K_AF_INT_VEC_FLT2: -+ flt_fn = rvu_cpt_af_flt2_intr_handler; -+ break; -+ } - ret = rvu_cpt_do_register_interrupt(block, off + i, -- rvu_cpt_af_flt_intr_handler, -- &rvu->irq_name[(off + i) * NAME_SIZE]); -+ flt_fn, &rvu->irq_name[(off + i) * NAME_SIZE]); - if (ret) - goto err; -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); -+ if (i == CPT_10K_AF_INT_VEC_FLT2) -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0xFFFF); -+ else -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); - } - - ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RVU, -@@ -208,8 +259,8 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) - { - struct rvu_hwinfo *hw = rvu->hw; - struct rvu_block *block; -+ irq_handler_t flt_fn; - int i, offs, ret = 0; -- char irq_name[16]; - - if (!is_block_implemented(rvu->hw, blkaddr)) - return 0; -@@ -226,13 +277,20 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) - return cpt_10k_register_interrupts(block, offs); - - for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) { -- snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i); -+ sprintf(&rvu->irq_name[(offs + i) * NAME_SIZE], "CPTAF FLT%d", i); -+ switch (i) { -+ case CPT_AF_INT_VEC_FLT0: -+ flt_fn = rvu_cpt_af_flt0_intr_handler; -+ break; -+ case CPT_AF_INT_VEC_FLT1: -+ flt_fn = rvu_cpt_af_flt1_intr_handler; -+ break; -+ } - ret = rvu_cpt_do_register_interrupt(block, offs + i, -- rvu_cpt_af_flt_intr_handler, -- irq_name); -+ flt_fn, &rvu->irq_name[(offs + i) * NAME_SIZE]); - if (ret) - goto err; -- rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); -+ rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); - } - - ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU, -@@ -290,7 +348,7 @@ static int get_cpt_pf_num(struct rvu *rvu) - - static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) - { -- int cpt_pf_num = get_cpt_pf_num(rvu); -+ int cpt_pf_num = rvu->cpt_pf_num; - - if (rvu_get_pf(pcifunc) != cpt_pf_num) - return false; -@@ -302,7 +360,7 @@ static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) - - static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc) - { -- int cpt_pf_num = get_cpt_pf_num(rvu); -+ int cpt_pf_num = rvu->cpt_pf_num; - - if (rvu_get_pf(pcifunc) != cpt_pf_num) - return false; -@@ -801,6 +859,64 @@ int rvu_mbox_handler_cpt_ctx_cache_sync(struct rvu *rvu, struct msg_req *req, - return rvu_cpt_ctx_flush(rvu, req->hdr.pcifunc); - } - -+int rvu_mbox_handler_cpt_lf_reset(struct rvu *rvu, struct cpt_lf_rst_req *req, -+ struct msg_rsp *rsp) -+{ -+ u16 pcifunc = req->hdr.pcifunc; -+ struct rvu_block *block; -+ int cptlf, blkaddr, ret; -+ u16 actual_slot; -+ u64 ctl, ctl2; -+ -+ blkaddr = rvu_get_blkaddr_from_slot(rvu, BLKTYPE_CPT, pcifunc, -+ req->slot, &actual_slot); -+ if (blkaddr < 0) -+ return CPT_AF_ERR_LF_INVALID; -+ -+ block = &rvu->hw->block[blkaddr]; -+ -+ cptlf = rvu_get_lf(rvu, block, pcifunc, actual_slot); -+ if (cptlf < 0) -+ return CPT_AF_ERR_LF_INVALID; -+ ctl = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf)); -+ ctl2 = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf)); -+ -+ ret = rvu_lf_reset(rvu, block, cptlf); -+ if (ret) -+ dev_err(rvu->dev, "Failed to reset blkaddr %d LF%d\n", -+ block->addr, cptlf); -+ -+ rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), ctl); -+ rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), ctl2); -+ -+ return 0; -+} -+ -+int rvu_mbox_handler_cpt_flt_eng_info(struct rvu *rvu, struct cpt_flt_eng_info_req *req, -+ struct cpt_flt_eng_info_rsp *rsp) -+{ -+ struct rvu_block *block; -+ unsigned long flags; -+ int blkaddr, vec; -+ -+ blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); -+ if (blkaddr < 0) -+ return blkaddr; -+ -+ block = &rvu->hw->block[blkaddr]; -+ for (vec = 0; vec < CPT_10K_AF_INT_VEC_RVU; vec++) { -+ spin_lock_irqsave(&rvu->cpt_intr_lock, flags); -+ rsp->flt_eng_map[vec] = block->cpt_flt_eng_map[vec]; -+ rsp->rcvrd_eng_map[vec] = block->cpt_rcvrd_eng_map[vec]; -+ if (req->reset) { -+ block->cpt_flt_eng_map[vec] = 0x0; -+ block->cpt_rcvrd_eng_map[vec] = 0x0; -+ } -+ spin_unlock_irqrestore(&rvu->cpt_intr_lock, flags); -+ } -+ return 0; -+} -+ - static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) - { - struct cpt_rxc_time_cfg_req req; -@@ -940,7 +1056,7 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s - static int cpt_inline_inb_lf_cmd_send(struct rvu *rvu, int blkaddr, - int nix_blkaddr) - { -- int cpt_pf_num = get_cpt_pf_num(rvu); -+ int cpt_pf_num = rvu->cpt_pf_num; - struct cpt_inst_lmtst_req *req; - dma_addr_t res_daddr; - int timeout = 3000; -@@ -1084,3 +1200,12 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc) - - return 0; - } -+ -+int rvu_cpt_init(struct rvu *rvu) -+{ -+ /* Retrieve CPT PF number */ -+ rvu->cpt_pf_num = get_cpt_pf_num(rvu); -+ spin_lock_init(&rvu->cpt_intr_lock); -+ -+ return 0; -+} -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -index 44950c2542bb7..c15d1864a6371 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -@@ -785,7 +785,7 @@ static inline int otx2_sync_mbox_up_msg(struct mbox *mbox, int devid) - - if (!otx2_mbox_nonempty(&mbox->mbox_up, devid)) - return 0; -- otx2_mbox_msg_send(&mbox->mbox_up, devid); -+ otx2_mbox_msg_send_up(&mbox->mbox_up, devid); - err = otx2_mbox_wait_for_rsp(&mbox->mbox_up, devid); - if (err) - return err; -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index a2d8ac6204054..7e2c30927c312 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -272,8 +272,7 @@ static int otx2_pf_flr_init(struct otx2_nic *pf, int num_vfs) - { - int vf; - -- pf->flr_wq = alloc_workqueue("otx2_pf_flr_wq", -- WQ_UNBOUND | WQ_HIGHPRI, 1); -+ pf->flr_wq = alloc_ordered_workqueue("otx2_pf_flr_wq", WQ_HIGHPRI); - if (!pf->flr_wq) - return -ENOMEM; - -@@ -292,8 +291,8 @@ static int otx2_pf_flr_init(struct otx2_nic *pf, int num_vfs) - return 0; - } - --static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq, -- int first, int mdevs, u64 intr, int type) -+static void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq, -+ int first, int mdevs, u64 intr) - { - struct otx2_mbox_dev *mdev; - struct otx2_mbox *mbox; -@@ -307,40 +306,26 @@ static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq, - - mbox = &mw->mbox; - mdev = &mbox->dev[i]; -- if (type == TYPE_PFAF) -- otx2_sync_mbox_bbuf(mbox, i); - hdr = mdev->mbase + mbox->rx_start; - /* The hdr->num_msgs is set to zero immediately in the interrupt -- * handler to ensure that it holds a correct value next time -- * when the interrupt handler is called. -- * pf->mbox.num_msgs holds the data for use in pfaf_mbox_handler -- * pf>mbox.up_num_msgs holds the data for use in -- * pfaf_mbox_up_handler. -+ * handler to ensure that it holds a correct value next time -+ * when the interrupt handler is called. pf->mw[i].num_msgs -+ * holds the data for use in otx2_pfvf_mbox_handler and -+ * pf->mw[i].up_num_msgs holds the data for use in -+ * otx2_pfvf_mbox_up_handler. - */ - if (hdr->num_msgs) { - mw[i].num_msgs = hdr->num_msgs; - hdr->num_msgs = 0; -- if (type == TYPE_PFAF) -- memset(mbox->hwbase + mbox->rx_start, 0, -- ALIGN(sizeof(struct mbox_hdr), -- sizeof(u64))); -- - queue_work(mbox_wq, &mw[i].mbox_wrk); - } - - mbox = &mw->mbox_up; - mdev = &mbox->dev[i]; -- if (type == TYPE_PFAF) -- otx2_sync_mbox_bbuf(mbox, i); - hdr = mdev->mbase + mbox->rx_start; - if (hdr->num_msgs) { - mw[i].up_num_msgs = hdr->num_msgs; - hdr->num_msgs = 0; -- if (type == TYPE_PFAF) -- memset(mbox->hwbase + mbox->rx_start, 0, -- ALIGN(sizeof(struct mbox_hdr), -- sizeof(u64))); -- - queue_work(mbox_wq, &mw[i].mbox_up_wrk); - } - } -@@ -356,8 +341,10 @@ static void otx2_forward_msg_pfvf(struct otx2_mbox_dev *mdev, - /* Msgs are already copied, trigger VF's mbox irq */ - smp_wmb(); - -+ otx2_mbox_wait_for_zero(pfvf_mbox, devid); -+ - offset = pfvf_mbox->trigger | (devid << pfvf_mbox->tr_shift); -- writeq(1, (void __iomem *)pfvf_mbox->reg_base + offset); -+ writeq(MBOX_DOWN_MSG, (void __iomem *)pfvf_mbox->reg_base + offset); - - /* Restore VF's mbox bounce buffer region address */ - src_mdev->mbase = bbuf_base; -@@ -547,7 +534,7 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work) - end: - offset = mbox->rx_start + msg->next_msgoff; - if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1)) -- __otx2_mbox_reset(mbox, 0); -+ __otx2_mbox_reset(mbox, vf_idx); - mdev->msgs_acked++; - } - } -@@ -564,8 +551,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) - if (vfs > 64) { - intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(1)); - otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr); -- otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr, -- TYPE_PFVF); -+ otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr); - if (intr) - trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); - vfs = 64; -@@ -574,7 +560,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) - intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0)); - otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(0), intr); - -- otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF); -+ otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr); - - if (intr) - trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); -@@ -599,7 +585,7 @@ static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs) - - pf->mbox_pfvf_wq = alloc_workqueue("otx2_pfvf_mailbox", - WQ_UNBOUND | WQ_HIGHPRI | -- WQ_MEM_RECLAIM, 1); -+ WQ_MEM_RECLAIM, 0); - if (!pf->mbox_pfvf_wq) - return -ENOMEM; - -@@ -822,20 +808,22 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work) - struct mbox *af_mbox; - struct otx2_nic *pf; - int offset, id; -+ u16 num_msgs; - - af_mbox = container_of(work, struct mbox, mbox_wrk); - mbox = &af_mbox->mbox; - mdev = &mbox->dev[0]; - rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ num_msgs = rsp_hdr->num_msgs; - - offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN); - pf = af_mbox->pfvf; - -- for (id = 0; id < af_mbox->num_msgs; id++) { -+ for (id = 0; id < num_msgs; id++) { - msg = (struct mbox_msghdr *)(mdev->mbase + offset); - otx2_process_pfaf_mbox_msg(pf, msg); - offset = mbox->rx_start + msg->next_msgoff; -- if (mdev->msgs_acked == (af_mbox->num_msgs - 1)) -+ if (mdev->msgs_acked == (num_msgs - 1)) - __otx2_mbox_reset(mbox, 0); - mdev->msgs_acked++; - } -@@ -946,12 +934,14 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work) - int offset, id, devid = 0; - struct mbox_hdr *rsp_hdr; - struct mbox_msghdr *msg; -+ u16 num_msgs; - - rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ num_msgs = rsp_hdr->num_msgs; - - offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN); - -- for (id = 0; id < af_mbox->up_num_msgs; id++) { -+ for (id = 0; id < num_msgs; id++) { - msg = (struct mbox_msghdr *)(mdev->mbase + offset); - - devid = msg->pcifunc & RVU_PFVF_FUNC_MASK; -@@ -960,10 +950,11 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work) - otx2_process_mbox_msg_up(pf, msg); - offset = mbox->rx_start + msg->next_msgoff; - } -- if (devid) { -+ /* Forward to VF iff VFs are really present */ -+ if (devid && pci_num_vf(pf->pdev)) { - otx2_forward_vf_mbox_msgs(pf, &pf->mbox.mbox_up, - MBOX_DIR_PFVF_UP, devid - 1, -- af_mbox->up_num_msgs); -+ num_msgs); - return; - } - -@@ -973,16 +964,49 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work) - static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq) - { - struct otx2_nic *pf = (struct otx2_nic *)pf_irq; -- struct mbox *mbox; -+ struct mbox *mw = &pf->mbox; -+ struct otx2_mbox_dev *mdev; -+ struct otx2_mbox *mbox; -+ struct mbox_hdr *hdr; -+ u64 mbox_data; - - /* Clear the IRQ */ - otx2_write64(pf, RVU_PF_INT, BIT_ULL(0)); - -- mbox = &pf->mbox; - -- trace_otx2_msg_interrupt(mbox->mbox.pdev, "AF to PF", BIT_ULL(0)); -+ mbox_data = otx2_read64(pf, RVU_PF_PFAF_MBOX0); -+ -+ if (mbox_data & MBOX_UP_MSG) { -+ mbox_data &= ~MBOX_UP_MSG; -+ otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data); -+ -+ mbox = &mw->mbox_up; -+ mdev = &mbox->dev[0]; -+ otx2_sync_mbox_bbuf(mbox, 0); -+ -+ hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ if (hdr->num_msgs) -+ queue_work(pf->mbox_wq, &mw->mbox_up_wrk); -+ -+ trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF", -+ BIT_ULL(0)); -+ } -+ -+ if (mbox_data & MBOX_DOWN_MSG) { -+ mbox_data &= ~MBOX_DOWN_MSG; -+ otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data); -+ -+ mbox = &mw->mbox; -+ mdev = &mbox->dev[0]; -+ otx2_sync_mbox_bbuf(mbox, 0); -+ -+ hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ if (hdr->num_msgs) -+ queue_work(pf->mbox_wq, &mw->mbox_wrk); - -- otx2_queue_work(mbox, pf->mbox_wq, 0, 1, 1, TYPE_PFAF); -+ trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF", -+ BIT_ULL(0)); -+ } - - return IRQ_HANDLED; - } -@@ -1063,9 +1087,8 @@ static int otx2_pfaf_mbox_init(struct otx2_nic *pf) - int err; - - mbox->pfvf = pf; -- pf->mbox_wq = alloc_workqueue("otx2_pfaf_mailbox", -- WQ_UNBOUND | WQ_HIGHPRI | -- WQ_MEM_RECLAIM, 1); -+ pf->mbox_wq = alloc_ordered_workqueue("otx2_pfaf_mailbox", -+ WQ_HIGHPRI | WQ_MEM_RECLAIM); - if (!pf->mbox_wq) - return -ENOMEM; - -@@ -3030,6 +3053,7 @@ static void otx2_vf_link_event_task(struct work_struct *work) - struct otx2_vf_config *config; - struct cgx_link_info_msg *req; - struct mbox_msghdr *msghdr; -+ struct delayed_work *dwork; - struct otx2_nic *pf; - int vf_idx; - -@@ -3038,10 +3062,24 @@ static void otx2_vf_link_event_task(struct work_struct *work) - vf_idx = config - config->pf->vf_configs; - pf = config->pf; - -+ if (config->intf_down) -+ return; -+ -+ mutex_lock(&pf->mbox.lock); -+ -+ dwork = &config->link_event_work; -+ -+ if (!otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx)) { -+ schedule_delayed_work(dwork, msecs_to_jiffies(100)); -+ mutex_unlock(&pf->mbox.lock); -+ return; -+ } -+ - msghdr = otx2_mbox_alloc_msg_rsp(&pf->mbox_pfvf[0].mbox_up, vf_idx, - sizeof(*req), sizeof(struct msg_rsp)); - if (!msghdr) { - dev_err(pf->dev, "Failed to create VF%d link event\n", vf_idx); -+ mutex_unlock(&pf->mbox.lock); - return; - } - -@@ -3050,7 +3088,11 @@ static void otx2_vf_link_event_task(struct work_struct *work) - req->hdr.sig = OTX2_MBOX_REQ_SIG; - memcpy(&req->link_info, &pf->linfo, sizeof(req->link_info)); - -+ otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx); -+ - otx2_sync_mbox_up_msg(&pf->mbox_pfvf[0], vf_idx); -+ -+ mutex_unlock(&pf->mbox.lock); - } - - static int otx2_sriov_enable(struct pci_dev *pdev, int numvfs) -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -index 404855bccb4b6..dcb8190de2407 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -@@ -89,16 +89,20 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work) - struct otx2_mbox *mbox; - struct mbox *af_mbox; - int offset, id; -+ u16 num_msgs; - - af_mbox = container_of(work, struct mbox, mbox_wrk); - mbox = &af_mbox->mbox; - mdev = &mbox->dev[0]; - rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -- if (af_mbox->num_msgs == 0) -+ num_msgs = rsp_hdr->num_msgs; -+ -+ if (num_msgs == 0) - return; -+ - offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN); - -- for (id = 0; id < af_mbox->num_msgs; id++) { -+ for (id = 0; id < num_msgs; id++) { - msg = (struct mbox_msghdr *)(mdev->mbase + offset); - otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg); - offset = mbox->rx_start + msg->next_msgoff; -@@ -151,6 +155,7 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work) - struct mbox *vf_mbox; - struct otx2_nic *vf; - int offset, id; -+ u16 num_msgs; - - vf_mbox = container_of(work, struct mbox, mbox_up_wrk); - vf = vf_mbox->pfvf; -@@ -158,12 +163,14 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work) - mdev = &mbox->dev[0]; - - rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -- if (vf_mbox->up_num_msgs == 0) -+ num_msgs = rsp_hdr->num_msgs; -+ -+ if (num_msgs == 0) - return; - - offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN); - -- for (id = 0; id < vf_mbox->up_num_msgs; id++) { -+ for (id = 0; id < num_msgs; id++) { - msg = (struct mbox_msghdr *)(mdev->mbase + offset); - otx2vf_process_mbox_msg_up(vf, msg); - offset = mbox->rx_start + msg->next_msgoff; -@@ -178,40 +185,48 @@ static irqreturn_t otx2vf_vfaf_mbox_intr_handler(int irq, void *vf_irq) - struct otx2_mbox_dev *mdev; - struct otx2_mbox *mbox; - struct mbox_hdr *hdr; -+ u64 mbox_data; - - /* Clear the IRQ */ - otx2_write64(vf, RVU_VF_INT, BIT_ULL(0)); - -+ mbox_data = otx2_read64(vf, RVU_VF_VFPF_MBOX0); -+ - /* Read latest mbox data */ - smp_rmb(); - -- /* Check for PF => VF response messages */ -- mbox = &vf->mbox.mbox; -- mdev = &mbox->dev[0]; -- otx2_sync_mbox_bbuf(mbox, 0); -+ if (mbox_data & MBOX_DOWN_MSG) { -+ mbox_data &= ~MBOX_DOWN_MSG; -+ otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data); - -- trace_otx2_msg_interrupt(mbox->pdev, "PF to VF", BIT_ULL(0)); -+ /* Check for PF => VF response messages */ -+ mbox = &vf->mbox.mbox; -+ mdev = &mbox->dev[0]; -+ otx2_sync_mbox_bbuf(mbox, 0); - -- hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -- if (hdr->num_msgs) { -- vf->mbox.num_msgs = hdr->num_msgs; -- hdr->num_msgs = 0; -- memset(mbox->hwbase + mbox->rx_start, 0, -- ALIGN(sizeof(struct mbox_hdr), sizeof(u64))); -- queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk); -+ hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ if (hdr->num_msgs) -+ queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk); -+ -+ trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF to VF", -+ BIT_ULL(0)); - } -- /* Check for PF => VF notification messages */ -- mbox = &vf->mbox.mbox_up; -- mdev = &mbox->dev[0]; -- otx2_sync_mbox_bbuf(mbox, 0); - -- hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -- if (hdr->num_msgs) { -- vf->mbox.up_num_msgs = hdr->num_msgs; -- hdr->num_msgs = 0; -- memset(mbox->hwbase + mbox->rx_start, 0, -- ALIGN(sizeof(struct mbox_hdr), sizeof(u64))); -- queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk); -+ if (mbox_data & MBOX_UP_MSG) { -+ mbox_data &= ~MBOX_UP_MSG; -+ otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data); -+ -+ /* Check for PF => VF notification messages */ -+ mbox = &vf->mbox.mbox_up; -+ mdev = &mbox->dev[0]; -+ otx2_sync_mbox_bbuf(mbox, 0); -+ -+ hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); -+ if (hdr->num_msgs) -+ queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk); -+ -+ trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF to VF", -+ BIT_ULL(0)); - } - - return IRQ_HANDLED; -@@ -293,9 +308,8 @@ static int otx2vf_vfaf_mbox_init(struct otx2_nic *vf) - int err; - - mbox->pfvf = vf; -- vf->mbox_wq = alloc_workqueue("otx2_vfaf_mailbox", -- WQ_UNBOUND | WQ_HIGHPRI | -- WQ_MEM_RECLAIM, 1); -+ vf->mbox_wq = alloc_ordered_workqueue("otx2_vfaf_mailbox", -+ WQ_HIGHPRI | WQ_MEM_RECLAIM); - if (!vf->mbox_wq) - return -ENOMEM; - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 17e6ac4445afc..fecf3dd22dfaa 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -561,8 +561,7 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode, - mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr_new = mcr_cur; - mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE | -- MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK | -- MAC_MCR_RX_FIFO_CLR_DIS; -+ MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_RX_FIFO_CLR_DIS; - - /* Only update control register when needed! */ - if (mcr_new != mcr_cur) -@@ -610,7 +609,7 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phylink_config); - u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN); -+ mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -@@ -649,7 +648,7 @@ static void mtk_mac_link_up(struct phylink_config *config, - if (rx_pause) - mcr |= MAC_MCR_FORCE_RX_FC; - -- mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN; -+ mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK; - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index d6eed204574a9..c64211e22ae70 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -811,7 +811,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_KEEPALIVE_DISABLE) | - FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) | - FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE, -- MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | -+ MTK_PPE_SCAN_MODE_CHECK_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); - if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -@@ -895,17 +895,21 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) - - mtk_ppe_cache_enable(ppe, false); - -- /* disable offload engine */ -- ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN); -- ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0); -- - /* disable aging */ - val = MTK_PPE_TB_CFG_AGE_NON_L4 | - MTK_PPE_TB_CFG_AGE_UNBIND | - MTK_PPE_TB_CFG_AGE_TCP | - MTK_PPE_TB_CFG_AGE_UDP | -- MTK_PPE_TB_CFG_AGE_TCP_FIN; -+ MTK_PPE_TB_CFG_AGE_TCP_FIN | -+ MTK_PPE_TB_CFG_SCAN_MODE; - ppe_clear(ppe, MTK_PPE_TB_CFG, val); - -- return mtk_ppe_wait_busy(ppe); -+ if (mtk_ppe_wait_busy(ppe)) -+ return -ETIMEDOUT; -+ -+ /* disable offload engine */ -+ ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN); -+ ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0); -+ -+ return 0; - } -diff --git a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c -index e92860e20a24a..c6a2c302a8c8b 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c -@@ -308,6 +308,11 @@ static void nfp_fl_lag_do_work(struct work_struct *work) - - acti_netdevs = kmalloc_array(entry->slave_cnt, - sizeof(*acti_netdevs), GFP_KERNEL); -+ if (!acti_netdevs) { -+ schedule_delayed_work(&lag->work, -+ NFP_FL_LAG_DELAY); -+ continue; -+ } - - /* Include sanity check in the loop. It may be that a bond has - * changed between processing the last notification and the -diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c -index 267e6fd3d4448..57411ee1d8374 100644 ---- a/drivers/net/phy/dp83822.c -+++ b/drivers/net/phy/dp83822.c -@@ -380,7 +380,7 @@ static int dp83822_config_init(struct phy_device *phydev) - { - struct dp83822_private *dp83822 = phydev->priv; - struct device *dev = &phydev->mdio.dev; -- int rgmii_delay; -+ int rgmii_delay = 0; - s32 rx_int_delay; - s32 tx_int_delay; - int err = 0; -@@ -390,30 +390,33 @@ static int dp83822_config_init(struct phy_device *phydev) - rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, - true); - -- if (rx_int_delay <= 0) -- rgmii_delay = 0; -- else -- rgmii_delay = DP83822_RX_CLK_SHIFT; -+ /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */ -+ if (rx_int_delay > 0) -+ rgmii_delay |= DP83822_RX_CLK_SHIFT; - - tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, - false); -+ -+ /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */ - if (tx_int_delay <= 0) -- rgmii_delay &= ~DP83822_TX_CLK_SHIFT; -- else - rgmii_delay |= DP83822_TX_CLK_SHIFT; - -- if (rgmii_delay) { -- err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, -- MII_DP83822_RCSR, rgmii_delay); -- if (err) -- return err; -- } -+ err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, -+ DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay); -+ if (err) -+ return err; -+ -+ err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, -+ MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); - -- phy_set_bits_mmd(phydev, DP83822_DEVADDR, -- MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); -+ if (err) -+ return err; - } else { -- phy_clear_bits_mmd(phydev, DP83822_DEVADDR, -- MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); -+ err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, -+ MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); -+ -+ if (err) -+ return err; - } - - if (dp83822->fx_enabled) { -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 944f76e6fc8eb..f25b0d338ca8d 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2640,8 +2640,8 @@ EXPORT_SYMBOL(genphy_resume); - int genphy_loopback(struct phy_device *phydev, bool enable) - { - if (enable) { -- u16 val, ctl = BMCR_LOOPBACK; -- int ret; -+ u16 ctl = BMCR_LOOPBACK; -+ int ret, val; - - ctl |= mii_bmcr_encode_fixed(phydev->speed, phydev->duplex); - -@@ -2893,7 +2893,7 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, - if (delay < 0) - return delay; - -- if (delay && size == 0) -+ if (size == 0) - return delay; - - if (delay < delay_values[0] || delay > delay_values[size - 1]) { -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index a530f20ee2575..2fa46baa589e5 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -2104,6 +2104,11 @@ static const struct usb_device_id products[] = { - USB_DEVICE(0x0424, 0x9E08), - .driver_info = (unsigned long) &smsc95xx_info, - }, -+ { -+ /* SYSTEC USB-SPEmodule1 10BASE-T1L Ethernet Device */ -+ USB_DEVICE(0x0878, 0x1400), -+ .driver_info = (unsigned long)&smsc95xx_info, -+ }, - { - /* Microchip's EVB-LAN8670-USB 10BASE-T1S Ethernet Device */ - USB_DEVICE(0x184F, 0x0051), -diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c -index f5e19f3ef6cdd..4de5144821835 100644 ---- a/drivers/net/usb/sr9800.c -+++ b/drivers/net/usb/sr9800.c -@@ -737,7 +737,9 @@ static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) - - data->eeprom_len = SR9800_EEPROM_LEN; - -- usbnet_get_endpoints(dev, intf); -+ ret = usbnet_get_endpoints(dev, intf); -+ if (ret) -+ goto out; - - /* LED Setting Rule : - * AABB:CCDD -diff --git a/drivers/net/veth.c b/drivers/net/veth.c -index dd9f5f1461921..8dcd3b6e143b9 100644 ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -1444,8 +1444,6 @@ static netdev_features_t veth_fix_features(struct net_device *dev, - if (peer_priv->_xdp_prog) - features &= ~NETIF_F_GSO_SOFTWARE; - } -- if (priv->_xdp_prog) -- features |= NETIF_F_GRO; - - return features; - } -@@ -1542,14 +1540,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, - } - - if (!old_prog) { -- if (!veth_gro_requested(dev)) { -- /* user-space did not require GRO, but adding -- * XDP is supposed to get GRO working -- */ -- dev->features |= NETIF_F_GRO; -- netdev_features_change(dev); -- } -- - peer->hw_features &= ~NETIF_F_GSO_SOFTWARE; - peer->max_mtu = max_mtu; - } -@@ -1560,14 +1550,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, - if (dev->flags & IFF_UP) - veth_disable_xdp(dev); - -- /* if user-space did not require GRO, since adding XDP -- * enabled it, clear it now -- */ -- if (!veth_gro_requested(dev)) { -- dev->features &= ~NETIF_F_GRO; -- netdev_features_change(dev); -- } -- - if (peer) { - peer->hw_features |= NETIF_F_GSO_SOFTWARE; - peer->max_mtu = ETH_MAX_MTU; -diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c -index a176653c88616..db01ec03bda00 100644 ---- a/drivers/net/wireguard/receive.c -+++ b/drivers/net/wireguard/receive.c -@@ -251,7 +251,7 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair) - - if (unlikely(!READ_ONCE(keypair->receiving.is_valid) || - wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) || -- keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) { -+ READ_ONCE(keypair->receiving_counter.counter) >= REJECT_AFTER_MESSAGES)) { - WRITE_ONCE(keypair->receiving.is_valid, false); - return false; - } -@@ -318,7 +318,7 @@ static bool counter_validate(struct noise_replay_counter *counter, u64 their_cou - for (i = 1; i <= top; ++i) - counter->backtrack[(i + index_current) & - ((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0; -- counter->counter = their_counter; -+ WRITE_ONCE(counter->counter, their_counter); - } - - index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1; -@@ -463,7 +463,7 @@ int wg_packet_rx_poll(struct napi_struct *napi, int budget) - net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n", - peer->device->dev->name, - PACKET_CB(skb)->nonce, -- keypair->receiving_counter.counter); -+ READ_ONCE(keypair->receiving_counter.counter)); - goto next; - } - -diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -index 876410a47d1d2..4d5009604eee7 100644 ---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c -+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -@@ -844,6 +844,10 @@ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb, - } - - ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT]; -+ if (!ev) { -+ kfree(tb); -+ return -EPROTO; -+ } - - arg->desc_id = ev->desc_id; - arg->status = ev->status; -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 21c6b36dc6ebb..51fc77e93de5c 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -2112,6 +2112,8 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, - mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); - mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); - -+ /* Initialize rx_mcs_160 to 9 which is an invalid value */ -+ rx_mcs_160 = 9; - if (support_160) { - for (i = 7; i >= 0; i--) { - u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3; -@@ -2123,6 +2125,8 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, - } - } - -+ /* Initialize rx_mcs_80 to 9 which is an invalid value */ -+ rx_mcs_80 = 9; - for (i = 7; i >= 0; i--) { - u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3; - -diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h -index 237f4ec2cffd7..6c33e898b3000 100644 ---- a/drivers/net/wireless/ath/ath9k/htc.h -+++ b/drivers/net/wireless/ath/ath9k/htc.h -@@ -306,7 +306,6 @@ struct ath9k_htc_tx { - DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); - struct timer_list cleanup_timer; - spinlock_t tx_lock; -- bool initialized; - }; - - struct ath9k_htc_tx_ctl { -@@ -515,6 +514,7 @@ struct ath9k_htc_priv { - unsigned long ps_usecount; - bool ps_enabled; - bool ps_idle; -+ bool initialized; - - #ifdef CONFIG_MAC80211_LEDS - enum led_brightness brightness; -diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c -index 96a3185a96d75..b014185373f34 100644 ---- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c -@@ -966,6 +966,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - - htc_handle->drv_priv = priv; - -+ /* Allow ath9k_wmi_event_tasklet() to operate. */ -+ smp_wmb(); -+ priv->initialized = true; -+ - return 0; - - err_init: -diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -index d6a3f001dacb9..2fdd27885f543 100644 ---- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -@@ -815,10 +815,6 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv) - skb_queue_head_init(&priv->tx.data_vo_queue); - skb_queue_head_init(&priv->tx.tx_failed); - -- /* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */ -- smp_wmb(); -- priv->tx.initialized = true; -- - return 0; - } - -diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c -index 1476b42b52a91..805ad31edba2b 100644 ---- a/drivers/net/wireless/ath/ath9k/wmi.c -+++ b/drivers/net/wireless/ath/ath9k/wmi.c -@@ -155,6 +155,12 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t) - } - spin_unlock_irqrestore(&wmi->wmi_lock, flags); - -+ /* Check if ath9k_htc_probe_device() completed. */ -+ if (!data_race(priv->initialized)) { -+ kfree_skb(skb); -+ continue; -+ } -+ - hdr = (struct wmi_cmd_hdr *) skb->data; - cmd_id = be16_to_cpu(hdr->command_id); - wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); -@@ -169,10 +175,6 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t) - &wmi->drv_priv->fatal_work); - break; - case WMI_TXSTATUS_EVENTID: -- /* Check if ath9k_tx_init() completed. */ -- if (!data_race(priv->tx.initialized)) -- break; -- - spin_lock_bh(&priv->tx.tx_lock); - if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { - spin_unlock_bh(&priv->tx.tx_lock); -diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h -index 67b4bac048e58..c0d8fc0b22fb2 100644 ---- a/drivers/net/wireless/broadcom/b43/b43.h -+++ b/drivers/net/wireless/broadcom/b43/b43.h -@@ -1082,6 +1082,22 @@ static inline bool b43_using_pio_transfers(struct b43_wldev *dev) - return dev->__using_pio_transfers; - } - -+static inline void b43_wake_queue(struct b43_wldev *dev, int queue_prio) -+{ -+ if (dev->qos_enabled) -+ ieee80211_wake_queue(dev->wl->hw, queue_prio); -+ else -+ ieee80211_wake_queue(dev->wl->hw, 0); -+} -+ -+static inline void b43_stop_queue(struct b43_wldev *dev, int queue_prio) -+{ -+ if (dev->qos_enabled) -+ ieee80211_stop_queue(dev->wl->hw, queue_prio); -+ else -+ ieee80211_stop_queue(dev->wl->hw, 0); -+} -+ - /* Message printing */ - __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); - __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); -diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c -index 9a7c62bd5e431..cfaf2f9d67b22 100644 ---- a/drivers/net/wireless/broadcom/b43/dma.c -+++ b/drivers/net/wireless/broadcom/b43/dma.c -@@ -1399,7 +1399,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) - should_inject_overflow(ring)) { - /* This TX ring is full. */ - unsigned int skb_mapping = skb_get_queue_mapping(skb); -- ieee80211_stop_queue(dev->wl->hw, skb_mapping); -+ b43_stop_queue(dev, skb_mapping); - dev->wl->tx_queue_stopped[skb_mapping] = true; - ring->stopped = true; - if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { -@@ -1570,7 +1570,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, - } else { - /* If the driver queue is running wake the corresponding - * mac80211 queue. */ -- ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); -+ b43_wake_queue(dev, ring->queue_prio); - if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { - b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); - } -diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c -index b2539a916fd04..bdfa68cc7ee2a 100644 ---- a/drivers/net/wireless/broadcom/b43/main.c -+++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -2587,7 +2587,8 @@ static void b43_request_firmware(struct work_struct *work) - - start_ieee80211: - wl->hw->queues = B43_QOS_QUEUE_NUM; -- if (!modparam_qos || dev->fw.opensource) -+ if (!modparam_qos || dev->fw.opensource || -+ dev->dev->chip_id == BCMA_CHIP_ID_BCM4331) - wl->hw->queues = 1; - - err = ieee80211_register_hw(wl->hw); -@@ -3603,7 +3604,7 @@ static void b43_tx_work(struct work_struct *work) - err = b43_dma_tx(dev, skb); - if (err == -ENOSPC) { - wl->tx_queue_stopped[queue_num] = true; -- ieee80211_stop_queue(wl->hw, queue_num); -+ b43_stop_queue(dev, queue_num); - skb_queue_head(&wl->tx_queue[queue_num], skb); - break; - } -@@ -3627,6 +3628,7 @@ static void b43_op_tx(struct ieee80211_hw *hw, - struct sk_buff *skb) - { - struct b43_wl *wl = hw_to_b43_wl(hw); -+ u16 skb_queue_mapping; - - if (unlikely(skb->len < 2 + 2 + 6)) { - /* Too short, this can't be a valid frame. */ -@@ -3635,12 +3637,12 @@ static void b43_op_tx(struct ieee80211_hw *hw, - } - B43_WARN_ON(skb_shinfo(skb)->nr_frags); - -- skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); -- if (!wl->tx_queue_stopped[skb->queue_mapping]) { -+ skb_queue_mapping = skb_get_queue_mapping(skb); -+ skb_queue_tail(&wl->tx_queue[skb_queue_mapping], skb); -+ if (!wl->tx_queue_stopped[skb_queue_mapping]) - ieee80211_queue_work(wl->hw, &wl->tx_work); -- } else { -- ieee80211_stop_queue(wl->hw, skb->queue_mapping); -- } -+ else -+ b43_stop_queue(wl->current_dev, skb_queue_mapping); - } - - static void b43_qos_params_upload(struct b43_wldev *dev, -diff --git a/drivers/net/wireless/broadcom/b43/pio.c b/drivers/net/wireless/broadcom/b43/pio.c -index 8c28a9250cd19..cc19b589fa70d 100644 ---- a/drivers/net/wireless/broadcom/b43/pio.c -+++ b/drivers/net/wireless/broadcom/b43/pio.c -@@ -525,7 +525,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) - if (total_len > (q->buffer_size - q->buffer_used)) { - /* Not enough memory on the queue. */ - err = -EBUSY; -- ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); -+ b43_stop_queue(dev, skb_get_queue_mapping(skb)); - q->stopped = true; - goto out; - } -@@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) - if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || - (q->free_packet_slots == 0)) { - /* The queue is full. */ -- ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); -+ b43_stop_queue(dev, skb_get_queue_mapping(skb)); - q->stopped = true; - } - -@@ -587,7 +587,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, - list_add(&pack->list, &q->packets_list); - - if (q->stopped) { -- ieee80211_wake_queue(dev->wl->hw, q->queue_prio); -+ b43_wake_queue(dev, q->queue_prio); - q->stopped = false; - } - } -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c -index ccc621b8ed9f2..4a1fe982a948e 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c -@@ -383,8 +383,9 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) - return sh; - } - --static void wlc_phy_timercb_phycal(struct brcms_phy *pi) -+static void wlc_phy_timercb_phycal(void *ptr) - { -+ struct brcms_phy *pi = ptr; - uint delay = 5; - - if (PHY_PERICAL_MPHASE_PENDING(pi)) { -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c -index a0de5db0cd646..b723817915365 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c -@@ -57,12 +57,11 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim) - } - - struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, -- void (*fn)(struct brcms_phy *pi), -+ void (*fn)(void *pi), - void *arg, const char *name) - { - return (struct wlapi_timer *) -- brcms_init_timer(physhim->wl, (void (*)(void *))fn, -- arg, name); -+ brcms_init_timer(physhim->wl, fn, arg, name); - } - - void wlapi_free_timer(struct wlapi_timer *t) -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h -index dd8774717adee..27d0934e600ed 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h -@@ -131,7 +131,7 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim); - - /* PHY to WL utility functions */ - struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, -- void (*fn)(struct brcms_phy *pi), -+ void (*fn)(void *pi), - void *arg, const char *name); - void wlapi_free_timer(struct wlapi_timer *t); - void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); -diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -index f5fcc547de391..235963e1d7a9a 100644 ---- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c -@@ -725,7 +725,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt) - * from index 1, so the maximum value allowed here is - * ACPI_SAR_PROFILES_NUM - 1. - */ -- if (n_profiles <= 0 || n_profiles >= ACPI_SAR_PROFILE_NUM) { -+ if (n_profiles >= ACPI_SAR_PROFILE_NUM) { - ret = -EINVAL; - goto out_free; - } -diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c -index 5979d904bbbd2..677c9e0b46f10 100644 ---- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c -+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c -@@ -103,6 +103,12 @@ static int iwl_dbg_tlv_alloc_debug_info(struct iwl_trans *trans, - if (le32_to_cpu(tlv->length) != sizeof(*debug_info)) - return -EINVAL; - -+ /* we use this as a string, ensure input was NUL terminated */ -+ if (strnlen(debug_info->debug_cfg_name, -+ sizeof(debug_info->debug_cfg_name)) == -+ sizeof(debug_info->debug_cfg_name)) -+ return -EINVAL; -+ - IWL_DEBUG_FW(trans, "WRT: Loading debug cfg: %s\n", - debug_info->debug_cfg_name); - -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c -index 2748459d12279..88f4f429d875c 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c -@@ -461,12 +461,10 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm, - struct wowlan_key_rsc_v5_data data = {}; - int i; - -- data.rsc = kmalloc(sizeof(*data.rsc), GFP_KERNEL); -+ data.rsc = kzalloc(sizeof(*data.rsc), GFP_KERNEL); - if (!data.rsc) - return -ENOMEM; - -- memset(data.rsc, 0xff, sizeof(*data.rsc)); -- - for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++) - data.rsc->mcast_key_id_map[i] = - IWL_MCAST_KEY_MAP_INVALID; -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c -index f268a31ce26d9..105f283b777d2 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c -@@ -299,6 +299,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - u32 status, - struct ieee80211_rx_status *stats) - { -+ struct wireless_dev *wdev; - struct iwl_mvm_sta *mvmsta; - struct iwl_mvm_vif *mvmvif; - u8 keyid; -@@ -320,9 +321,15 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - if (!ieee80211_is_beacon(hdr->frame_control)) - return 0; - -+ if (!sta) -+ return -1; -+ -+ mvmsta = iwl_mvm_sta_from_mac80211(sta); -+ mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); -+ - /* key mismatch - will also report !MIC_OK but we shouldn't count it */ - if (!(status & IWL_RX_MPDU_STATUS_KEY_VALID)) -- return -1; -+ goto report; - - /* good cases */ - if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK && -@@ -331,13 +338,6 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - return 0; - } - -- if (!sta) -- return -1; -- -- mvmsta = iwl_mvm_sta_from_mac80211(sta); -- -- mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); -- - /* - * both keys will have the same cipher and MIC length, use - * whichever one is available -@@ -346,11 +346,11 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - if (!key) { - key = rcu_dereference(mvmvif->bcn_prot.keys[1]); - if (!key) -- return -1; -+ goto report; - } - - if (len < key->icv_len + IEEE80211_GMAC_PN_LEN + 2) -- return -1; -+ goto report; - - /* get the real key ID */ - keyid = frame[len - key->icv_len - IEEE80211_GMAC_PN_LEN - 2]; -@@ -364,7 +364,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - return -1; - key = rcu_dereference(mvmvif->bcn_prot.keys[keyid - 6]); - if (!key) -- return -1; -+ goto report; - } - - /* Report status to mac80211 */ -@@ -372,6 +372,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, - ieee80211_key_mic_failure(key); - else if (status & IWL_RX_MPDU_STATUS_REPLAY_ERROR) - ieee80211_key_replay(key); -+report: -+ wdev = ieee80211_vif_to_wdev(mvmsta->vif); -+ if (wdev->netdev) -+ cfg80211_rx_unprot_mlme_mgmt(wdev->netdev, (void *)hdr, len); - - return -1; - } -diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/marvell/libertas/cmd.c -index 104d2b6dc9af6..5a525da434c28 100644 ---- a/drivers/net/wireless/marvell/libertas/cmd.c -+++ b/drivers/net/wireless/marvell/libertas/cmd.c -@@ -1132,7 +1132,7 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv) - if (!cmdarray[i].cmdbuf) { - lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); - ret = -1; -- goto done; -+ goto free_cmd_array; - } - } - -@@ -1140,8 +1140,17 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv) - init_waitqueue_head(&cmdarray[i].cmdwait_q); - lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]); - } -- ret = 0; -+ return 0; - -+free_cmd_array: -+ for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { -+ if (cmdarray[i].cmdbuf) { -+ kfree(cmdarray[i].cmdbuf); -+ cmdarray[i].cmdbuf = NULL; -+ } -+ } -+ kfree(priv->cmd_array); -+ priv->cmd_array = NULL; - done: - return ret; - } -diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c -index 63f232c723374..55ca5b287fe7f 100644 ---- a/drivers/net/wireless/marvell/mwifiex/debugfs.c -+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c -@@ -964,9 +964,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) - priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name, - mwifiex_dfs_dir); - -- if (!priv->dfs_dev_dir) -- return; -- - MWIFIEX_DFS_ADD_FILE(info); - MWIFIEX_DFS_ADD_FILE(debug); - MWIFIEX_DFS_ADD_FILE(getlog); -diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c -index b545d93c6e374..6f3245a43aef1 100644 ---- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c -+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c -@@ -1615,7 +1615,6 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) - cfg80211_unregister_netdevice(vif->ndev); - vif->monitor_flag = 0; - -- wilc_set_operation_mode(vif, 0, 0, 0); - mutex_lock(&wl->vif_mutex); - list_del_rcu(&vif->list); - wl->vif_num--; -@@ -1810,15 +1809,24 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type, - INIT_LIST_HEAD(&wl->rxq_head.list); - INIT_LIST_HEAD(&wl->vif_list); - -+ wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, -+ wiphy_name(wl->wiphy)); -+ if (!wl->hif_workqueue) { -+ ret = -ENOMEM; -+ goto free_cfg; -+ } - vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE, - NL80211_IFTYPE_STATION, false); - if (IS_ERR(vif)) { - ret = PTR_ERR(vif); -- goto free_cfg; -+ goto free_hq; - } - - return 0; - -+free_hq: -+ destroy_workqueue(wl->hif_workqueue); -+ - free_cfg: - wilc_wlan_cfg_deinit(wl); - -diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c -index a1b75feec6edf..5eb02902e875a 100644 ---- a/drivers/net/wireless/microchip/wilc1000/hif.c -+++ b/drivers/net/wireless/microchip/wilc1000/hif.c -@@ -374,38 +374,49 @@ static void handle_connect_timeout(struct work_struct *work) - void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - struct cfg80211_crypto_settings *crypto) - { -- struct wilc_join_bss_param *param; -- struct ieee80211_p2p_noa_attr noa_attr; -- u8 rates_len = 0; -- const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie; -+ const u8 *ies_data, *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie; - const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie; -+ struct ieee80211_p2p_noa_attr noa_attr; -+ const struct cfg80211_bss_ies *ies; -+ struct wilc_join_bss_param *param; -+ u8 rates_len = 0, ies_len; - int ret; -- const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (!param) - return NULL; - -+ rcu_read_lock(); -+ ies = rcu_dereference(bss->ies); -+ ies_data = kmemdup(ies->data, ies->len, GFP_ATOMIC); -+ if (!ies_data) { -+ rcu_read_unlock(); -+ kfree(param); -+ return NULL; -+ } -+ ies_len = ies->len; -+ rcu_read_unlock(); -+ - param->beacon_period = cpu_to_le16(bss->beacon_interval); - param->cap_info = cpu_to_le16(bss->capability); - param->bss_type = WILC_FW_BSS_TYPE_INFRA; - param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq); - ether_addr_copy(param->bssid, bss->bssid); - -- ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len); -+ ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies_data, ies_len); - if (ssid_elm) { - if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN) - memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]); - } - -- tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len); -+ tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies_data, ies_len); - if (tim_elm && tim_elm[1] >= 2) - param->dtim_period = tim_elm[3]; - - memset(param->p_suites, 0xFF, 3); - memset(param->akm_suites, 0xFF, 3); - -- rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len); -+ rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies_data, ies_len); - if (rates_ie) { - rates_len = rates_ie[1]; - if (rates_len > WILC_MAX_RATES_SUPPORTED) -@@ -416,7 +427,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - - if (rates_len < WILC_MAX_RATES_SUPPORTED) { - supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, -- ies->data, ies->len); -+ ies_data, ies_len); - if (supp_rates_ie) { - u8 ext_rates = supp_rates_ie[1]; - -@@ -431,11 +442,11 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - } - } - -- ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len); -+ ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies_data, ies_len); - if (ht_ie) - param->ht_capable = true; - -- ret = cfg80211_get_p2p_attr(ies->data, ies->len, -+ ret = cfg80211_get_p2p_attr(ies_data, ies_len, - IEEE80211_P2P_ATTR_ABSENCE_NOTICE, - (u8 *)&noa_attr, sizeof(noa_attr)); - if (ret > 0) { -@@ -459,7 +470,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - } - wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, - WLAN_OUI_TYPE_MICROSOFT_WMM, -- ies->data, ies->len); -+ ies_data, ies_len); - if (wmm_ie) { - struct ieee80211_wmm_param_ie *ie; - -@@ -474,13 +485,13 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - - wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, - WLAN_OUI_TYPE_MICROSOFT_WPA, -- ies->data, ies->len); -+ ies_data, ies_len); - if (wpa_ie) { - param->mode_802_11i = 1; - param->rsn_found = true; - } - -- rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); -+ rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies_data, ies_len); - if (rsn_ie) { - int rsn_ie_len = sizeof(struct element) + rsn_ie[1]; - int offset = 8; -@@ -514,6 +525,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, - param->akm_suites[i] = crypto->akm_suites[i] & 0xFF; - } - -+ kfree(ies_data); - return (void *)param; - } - -diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c -index e9f59de31b0b9..b714da48eaa17 100644 ---- a/drivers/net/wireless/microchip/wilc1000/netdev.c -+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c -@@ -878,8 +878,7 @@ static const struct net_device_ops wilc_netdev_ops = { - - void wilc_netdev_cleanup(struct wilc *wilc) - { -- struct wilc_vif *vif; -- int srcu_idx, ifc_cnt = 0; -+ struct wilc_vif *vif, *vif_tmp; - - if (!wilc) - return; -@@ -889,32 +888,19 @@ void wilc_netdev_cleanup(struct wilc *wilc) - wilc->firmware = NULL; - } - -- srcu_idx = srcu_read_lock(&wilc->srcu); -- list_for_each_entry_rcu(vif, &wilc->vif_list, list) { -+ list_for_each_entry_safe(vif, vif_tmp, &wilc->vif_list, list) { -+ mutex_lock(&wilc->vif_mutex); -+ list_del_rcu(&vif->list); -+ wilc->vif_num--; -+ mutex_unlock(&wilc->vif_mutex); -+ synchronize_srcu(&wilc->srcu); - if (vif->ndev) - unregister_netdev(vif->ndev); - } -- srcu_read_unlock(&wilc->srcu, srcu_idx); - - wilc_wfi_deinit_mon_interface(wilc, false); - destroy_workqueue(wilc->hif_workqueue); - -- while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) { -- mutex_lock(&wilc->vif_mutex); -- if (wilc->vif_num <= 0) { -- mutex_unlock(&wilc->vif_mutex); -- break; -- } -- vif = wilc_get_wl_to_vif(wilc); -- if (!IS_ERR(vif)) -- list_del_rcu(&vif->list); -- -- wilc->vif_num--; -- mutex_unlock(&wilc->vif_mutex); -- synchronize_srcu(&wilc->srcu); -- ifc_cnt++; -- } -- - wilc_wlan_cfg_deinit(wilc); - wlan_deinit_locks(wilc); - wiphy_unregister(wilc->wiphy); -@@ -977,13 +963,6 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name, - goto error; - } - -- wl->hif_workqueue = alloc_ordered_workqueue("%s-wq", WQ_MEM_RECLAIM, -- ndev->name); -- if (!wl->hif_workqueue) { -- ret = -ENOMEM; -- goto unregister_netdev; -- } -- - ndev->needs_free_netdev = true; - vif->iftype = vif_type; - vif->idx = wilc_get_available_idx(wl); -@@ -996,12 +975,11 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name, - - return vif; - --unregister_netdev: -+error: - if (rtnl_locked) - cfg80211_unregister_netdevice(ndev); - else - unregister_netdev(ndev); -- error: - free_netdev(ndev); - return ERR_PTR(ret); - } -diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c -index b0fc5e68feeca..5877e2c1fa0fc 100644 ---- a/drivers/net/wireless/microchip/wilc1000/spi.c -+++ b/drivers/net/wireless/microchip/wilc1000/spi.c -@@ -191,11 +191,11 @@ static void wilc_wlan_power(struct wilc *wilc, bool on) - /* assert ENABLE: */ - gpiod_set_value(gpios->enable, 1); - mdelay(5); -- /* assert RESET: */ -- gpiod_set_value(gpios->reset, 1); -- } else { - /* deassert RESET: */ - gpiod_set_value(gpios->reset, 0); -+ } else { -+ /* assert RESET: */ -+ gpiod_set_value(gpios->reset, 1); - /* deassert ENABLE: */ - gpiod_set_value(gpios->enable, 0); - } -diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -index 6dd5ec1e4d8c3..ccac47dd781d6 100644 ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -6542,6 +6542,7 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw) - if (priv->usb_interrupts) - rtl8xxxu_write32(priv, REG_USB_HIMR, 0); - -+ cancel_work_sync(&priv->c2hcmd_work); - cancel_delayed_work_sync(&priv->ra_watchdog); - - rtl8xxxu_free_rx_resources(priv); -diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c -index 4c8164db4a9e4..81f3112923f1c 100644 ---- a/drivers/net/wireless/realtek/rtw88/main.c -+++ b/drivers/net/wireless/realtek/rtw88/main.c -@@ -1989,8 +1989,6 @@ static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) - rtw_phy_setup_phy_cond(rtwdev, 0); - - rtw_phy_init_tx_power(rtwdev); -- if (rfe_def->agc_btg_tbl) -- rtw_load_table(rtwdev, rfe_def->agc_btg_tbl); - rtw_load_table(rtwdev, rfe_def->phy_pg_tbl); - rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl); - rtw_phy_tx_power_by_rate_config(hal); -diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c -index bd7d05e080848..fde7b532bc07e 100644 ---- a/drivers/net/wireless/realtek/rtw88/phy.c -+++ b/drivers/net/wireless/realtek/rtw88/phy.c -@@ -1761,12 +1761,15 @@ static void rtw_load_rfk_table(struct rtw_dev *rtwdev) - - void rtw_phy_load_tables(struct rtw_dev *rtwdev) - { -+ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); - const struct rtw_chip_info *chip = rtwdev->chip; - u8 rf_path; - - rtw_load_table(rtwdev, chip->mac_tbl); - rtw_load_table(rtwdev, chip->bb_tbl); - rtw_load_table(rtwdev, chip->agc_tbl); -+ if (rfe_def->agc_btg_tbl) -+ rtw_load_table(rtwdev, rfe_def->agc_btg_tbl); - rtw_load_rfk_table(rtwdev); - - for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) { -diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -index 609a2b86330d8..50e3e46f7d8aa 100644 ---- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c -+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c -@@ -674,9 +674,9 @@ static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) - - dm_info->cck_fa_cnt = cck_fa_cnt; - dm_info->ofdm_fa_cnt = ofdm_fa_cnt; -+ dm_info->total_fa_cnt = ofdm_fa_cnt; - if (cck_enable) - dm_info->total_fa_cnt += cck_fa_cnt; -- dm_info->total_fa_cnt = ofdm_fa_cnt; - - crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); - dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); -diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c -index 073e870b26415..871667650dbef 100644 ---- a/drivers/net/wireless/silabs/wfx/sta.c -+++ b/drivers/net/wireless/silabs/wfx/sta.c -@@ -362,6 +362,7 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif) - const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); - const int pairwise_cipher_suite_size = 4 / sizeof(u16); - const int akm_suite_size = 4 / sizeof(u16); -+ int ret = -EINVAL; - const u16 *ptr; - - if (unlikely(!skb)) -@@ -370,22 +371,26 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif) - ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, - skb->len - ieoffset); - if (unlikely(!ptr)) -- return -EINVAL; -+ goto free_skb; - - ptr += pairwise_cipher_suite_count_offset; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) -- return -EINVAL; -+ goto free_skb; - - ptr += 1 + pairwise_cipher_suite_size * *ptr; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) -- return -EINVAL; -+ goto free_skb; - - ptr += 1 + akm_suite_size * *ptr; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) -- return -EINVAL; -+ goto free_skb; - - wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); -- return 0; -+ ret = 0; -+ -+free_skb: -+ dev_kfree_skb(skb); -+ return ret; - } - - int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c -index 27dd93deff6e5..d702bee780826 100644 ---- a/drivers/ntb/core.c -+++ b/drivers/ntb/core.c -@@ -100,6 +100,8 @@ EXPORT_SYMBOL(ntb_unregister_client); - - int ntb_register_device(struct ntb_dev *ntb) - { -+ int ret; -+ - if (!ntb) - return -EINVAL; - if (!ntb->pdev) -@@ -120,7 +122,11 @@ int ntb_register_device(struct ntb_dev *ntb) - ntb->ctx_ops = NULL; - spin_lock_init(&ntb->ctx_lock); - -- return device_register(&ntb->dev); -+ ret = device_register(&ntb->dev); -+ if (ret) -+ put_device(&ntb->dev); -+ -+ return ret; - } - EXPORT_SYMBOL(ntb_register_device); - -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index 0c088db944706..d7516e99275b6 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -4971,7 +4971,8 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, - set->ops = ops; - set->queue_depth = NVME_AQ_MQ_TAG_DEPTH; - if (ctrl->ops->flags & NVME_F_FABRICS) -- set->reserved_tags = NVMF_RESERVED_TAGS; -+ /* Reserved for fabric connect and keep alive */ -+ set->reserved_tags = 2; - set->numa_node = ctrl->numa_node; - set->flags = BLK_MQ_F_NO_SCHED; - if (ctrl->ops->flags & NVME_F_BLOCKING) -@@ -5029,7 +5030,15 @@ int nvme_alloc_io_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, - memset(set, 0, sizeof(*set)); - set->ops = ops; - set->queue_depth = ctrl->sqsize + 1; -- set->reserved_tags = NVMF_RESERVED_TAGS; -+ /* -+ * Some Apple controllers requires tags to be unique across admin and -+ * the (only) I/O queue, so reserve the first 32 tags of the I/O queue. -+ */ -+ if (ctrl->quirks & NVME_QUIRK_SHARED_TAGS) -+ set->reserved_tags = NVME_AQ_DEPTH; -+ else if (ctrl->ops->flags & NVME_F_FABRICS) -+ /* Reserved for fabric connect */ -+ set->reserved_tags = 1; - set->numa_node = ctrl->numa_node; - set->flags = BLK_MQ_F_SHOULD_MERGE; - if (ctrl->ops->flags & NVME_F_BLOCKING) -diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h -index dcac3df8a5f76..60c238caf7a97 100644 ---- a/drivers/nvme/host/fabrics.h -+++ b/drivers/nvme/host/fabrics.h -@@ -18,13 +18,6 @@ - /* default is -1: the fail fast mechanism is disabled */ - #define NVMF_DEF_FAIL_FAST_TMO -1 - --/* -- * Reserved one command for internal usage. This command is used for sending -- * the connect command, as well as for the keep alive command on the admin -- * queue once live. -- */ --#define NVMF_RESERVED_TAGS 1 -- - /* - * Define a host as seen by the target. We allocate one at boot, but also - * allow the override it when creating controllers. This is both to provide -diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c -index 2c7fb683441ef..de81bbf4be100 100644 ---- a/drivers/opp/debugfs.c -+++ b/drivers/opp/debugfs.c -@@ -37,10 +37,12 @@ static ssize_t bw_name_read(struct file *fp, char __user *userbuf, - size_t count, loff_t *ppos) - { - struct icc_path *path = fp->private_data; -+ const char *name = icc_get_name(path); - char buf[64]; -- int i; -+ int i = 0; - -- i = scnprintf(buf, sizeof(buf), "%.62s\n", icc_get_name(path)); -+ if (name) -+ i = scnprintf(buf, sizeof(buf), "%.62s\n", name); - - return simple_read_from_buffer(userbuf, count, ppos, buf, i); - } -diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c -index 8c6931210ac4d..b4c1a4f6029d4 100644 ---- a/drivers/pci/endpoint/functions/pci-epf-vntb.c -+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c -@@ -1281,14 +1281,11 @@ static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id) - ret = ntb_register_device(&ndev->ntb); - if (ret) { - dev_err(dev, "Failed to register NTB device\n"); -- goto err_register_dev; -+ return ret; - } - - dev_dbg(dev, "PCI Virtual NTB driver loaded\n"); - return 0; -- --err_register_dev: -- return -EINVAL; - } - - static struct pci_device_id pci_vntb_table[] = { -diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h -index e1d02b7c60294..9950deeb047a7 100644 ---- a/drivers/pci/pci.h -+++ b/drivers/pci/pci.h -@@ -357,11 +357,6 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) - return 0; - } - --static inline bool pci_dev_is_disconnected(const struct pci_dev *dev) --{ -- return dev->error_state == pci_channel_io_perm_failure; --} -- - /* pci_dev priv_flags */ - #define PCI_DEV_ADDED 0 - #define PCI_DPC_RECOVERED 1 -diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c -index a5d7c69b764e0..08800282825e1 100644 ---- a/drivers/pci/pcie/dpc.c -+++ b/drivers/pci/pcie/dpc.c -@@ -231,7 +231,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev) - - for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) { - pci_read_config_dword(pdev, -- cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix); -+ cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, &prefix); - pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix); - } - clear_status: -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 51d634fbdfb8e..c175b70a984c6 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -5415,6 +5415,7 @@ static void quirk_no_ext_tags(struct pci_dev *pdev) - - pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL); - } -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_3WARE, 0x1004, quirk_no_ext_tags); - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0132, quirk_no_ext_tags); - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags); - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0141, quirk_no_ext_tags); -diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c -index 3f3320d0a4f8f..d05a482639e3c 100644 ---- a/drivers/pci/switch/switchtec.c -+++ b/drivers/pci/switch/switchtec.c -@@ -1674,7 +1674,7 @@ static int switchtec_pci_probe(struct pci_dev *pdev, - rc = switchtec_init_isr(stdev); - if (rc) { - dev_err(&stdev->dev, "failed to init isr.\n"); -- goto err_put; -+ goto err_exit_pci; - } - - iowrite32(SWITCHTEC_EVENT_CLEAR | -@@ -1695,6 +1695,8 @@ static int switchtec_pci_probe(struct pci_dev *pdev, - - err_devadd: - stdev_kill(stdev); -+err_exit_pci: -+ switchtec_exit_pci(stdev); - err_put: - ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt)); - put_device(&stdev->dev); -diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c -index 47e7c3206939f..899e4ed49905c 100644 ---- a/drivers/perf/arm-cmn.c -+++ b/drivers/perf/arm-cmn.c -@@ -2178,6 +2178,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) - dev_dbg(cmn->dev, "ignoring external node %llx\n", reg); - continue; - } -+ /* -+ * AmpereOneX erratum AC04_MESH_1 makes some XPs report a bogus -+ * child count larger than the number of valid child pointers. -+ * A child offset of 0 can only occur on CMN-600; otherwise it -+ * would imply the root node being its own grandchild, which -+ * we can safely dismiss in general. -+ */ -+ if (reg == 0 && cmn->part != PART_CMN600) { -+ dev_dbg(cmn->dev, "bogus child pointer?\n"); -+ continue; -+ } - - arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn); - -diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8186.c b/drivers/pinctrl/mediatek/pinctrl-mt8186.c -index a02f7c3269707..09edcf47effec 100644 ---- a/drivers/pinctrl/mediatek/pinctrl-mt8186.c -+++ b/drivers/pinctrl/mediatek/pinctrl-mt8186.c -@@ -1198,7 +1198,6 @@ static const struct mtk_pin_reg_calc mt8186_reg_cals[PINCTRL_PIN_REG_MAX] = { - [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8186_pin_dir_range), - [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8186_pin_di_range), - [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8186_pin_do_range), -- [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8186_pin_dir_range), - [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8186_pin_smt_range), - [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8186_pin_ies_range), - [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8186_pin_pu_range), -diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8192.c b/drivers/pinctrl/mediatek/pinctrl-mt8192.c -index 9695f4ec6aba9..f120268c00f56 100644 ---- a/drivers/pinctrl/mediatek/pinctrl-mt8192.c -+++ b/drivers/pinctrl/mediatek/pinctrl-mt8192.c -@@ -1379,7 +1379,6 @@ static const struct mtk_pin_reg_calc mt8192_reg_cals[PINCTRL_PIN_REG_MAX] = { - [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8192_pin_dir_range), - [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8192_pin_di_range), - [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8192_pin_do_range), -- [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8192_pin_dir_range), - [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8192_pin_smt_range), - [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8192_pin_ies_range), - [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8192_pin_pu_range), -diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c -index f7d02513d8cc1..e79037dc85796 100644 ---- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c -+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c -@@ -1571,8 +1571,10 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, - * Then mask the pins that need to be sleeping now when we're - * switching to the ALT C function. - */ -- for (i = 0; i < g->grp.npins; i++) -- slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]); -+ for (i = 0; i < g->grp.npins; i++) { -+ unsigned int bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP; -+ slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(bit); -+ } - nmk_gpio_glitch_slpm_init(slpm); - } - -diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c -index 43a63a21a6fb5..acf7664ea835b 100644 ---- a/drivers/pinctrl/renesas/pfc-r8a779g0.c -+++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c -@@ -2360,6 +2360,30 @@ static const unsigned int scif_clk_mux[] = { - SCIF_CLK_MARK, - }; - -+static const unsigned int scif_clk2_pins[] = { -+ /* SCIF_CLK2 */ -+ RCAR_GP_PIN(8, 11), -+}; -+static const unsigned int scif_clk2_mux[] = { -+ SCIF_CLK2_MARK, -+}; -+ -+/* - SSI ------------------------------------------------- */ -+static const unsigned int ssi_data_pins[] = { -+ /* SSI_SD */ -+ RCAR_GP_PIN(1, 20), -+}; -+static const unsigned int ssi_data_mux[] = { -+ SSI_SD_MARK, -+}; -+static const unsigned int ssi_ctrl_pins[] = { -+ /* SSI_SCK, SSI_WS */ -+ RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 19), -+}; -+static const unsigned int ssi_ctrl_mux[] = { -+ SSI_SCK_MARK, SSI_WS_MARK, -+}; -+ - /* - TPU ------------------------------------------------------------------- */ - static const unsigned int tpu_to0_pins[] = { - /* TPU0TO0 */ -@@ -2651,6 +2675,10 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { - SH_PFC_PIN_GROUP(scif4_clk), - SH_PFC_PIN_GROUP(scif4_ctrl), - SH_PFC_PIN_GROUP(scif_clk), -+ SH_PFC_PIN_GROUP(scif_clk2), -+ -+ SH_PFC_PIN_GROUP(ssi_data), -+ SH_PFC_PIN_GROUP(ssi_ctrl), - - SH_PFC_PIN_GROUP(tpu_to0), /* suffix might be updated */ - SH_PFC_PIN_GROUP(tpu_to0_a), /* suffix might be updated */ -@@ -2964,6 +2992,15 @@ static const char * const scif_clk_groups[] = { - "scif_clk", - }; - -+static const char * const scif_clk2_groups[] = { -+ "scif_clk2", -+}; -+ -+static const char * const ssi_groups[] = { -+ "ssi_data", -+ "ssi_ctrl", -+}; -+ - static const char * const tpu_groups[] = { - /* suffix might be updated */ - "tpu_to0", -@@ -3044,6 +3081,9 @@ static const struct sh_pfc_function pinmux_functions[] = { - SH_PFC_FUNCTION(scif3), - SH_PFC_FUNCTION(scif4), - SH_PFC_FUNCTION(scif_clk), -+ SH_PFC_FUNCTION(scif_clk2), -+ -+ SH_PFC_FUNCTION(ssi), - - SH_PFC_FUNCTION(tpu), - -diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c -index 9193c3b8edebe..ae7ee611978ba 100644 ---- a/drivers/powercap/dtpm_cpu.c -+++ b/drivers/powercap/dtpm_cpu.c -@@ -219,7 +219,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) - ret = freq_qos_add_request(&policy->constraints, - &dtpm_cpu->qos_req, FREQ_QOS_MAX, - pd->table[pd->nr_perf_states - 1].frequency); -- if (ret) -+ if (ret < 0) - goto out_dtpm_unregister; - - cpufreq_cpu_put(policy); -diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c -index a43b2babc8093..3e9c94a8d7f72 100644 ---- a/drivers/pwm/pwm-atmel-hlcdc.c -+++ b/drivers/pwm/pwm-atmel-hlcdc.c -@@ -38,11 +38,11 @@ static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip) - return container_of(chip, struct atmel_hlcdc_pwm, chip); - } - --static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, -+static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - const struct pwm_state *state) - { -- struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); -- struct atmel_hlcdc *hlcdc = chip->hlcdc; -+ struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip); -+ struct atmel_hlcdc *hlcdc = atmel->hlcdc; - unsigned int status; - int ret; - -@@ -54,7 +54,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - u32 pwmcfg; - int pres; - -- if (!chip->errata || !chip->errata->slow_clk_erratum) { -+ if (!atmel->errata || !atmel->errata->slow_clk_erratum) { - clk_freq = clk_get_rate(new_clk); - if (!clk_freq) - return -EINVAL; -@@ -64,7 +64,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - } - - /* Errata: cannot use slow clk on some IP revisions */ -- if ((chip->errata && chip->errata->slow_clk_erratum) || -+ if ((atmel->errata && atmel->errata->slow_clk_erratum) || - clk_period_ns > state->period) { - new_clk = hlcdc->sys_clk; - clk_freq = clk_get_rate(new_clk); -@@ -77,8 +77,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - - for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) { - /* Errata: cannot divide by 1 on some IP revisions */ -- if (!pres && chip->errata && -- chip->errata->div1_clk_erratum) -+ if (!pres && atmel->errata && -+ atmel->errata->div1_clk_erratum) - continue; - - if ((clk_period_ns << pres) >= state->period) -@@ -90,7 +90,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - - pwmcfg = ATMEL_HLCDC_PWMPS(pres); - -- if (new_clk != chip->cur_clk) { -+ if (new_clk != atmel->cur_clk) { - u32 gencfg = 0; - int ret; - -@@ -98,8 +98,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - if (ret) - return ret; - -- clk_disable_unprepare(chip->cur_clk); -- chip->cur_clk = new_clk; -+ clk_disable_unprepare(atmel->cur_clk); -+ atmel->cur_clk = new_clk; - - if (new_clk == hlcdc->sys_clk) - gencfg = ATMEL_HLCDC_CLKPWMSEL; -@@ -160,8 +160,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - if (ret) - return ret; - -- clk_disable_unprepare(chip->cur_clk); -- chip->cur_clk = NULL; -+ clk_disable_unprepare(atmel->cur_clk); -+ atmel->cur_clk = NULL; - } - - return 0; -@@ -183,31 +183,32 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = { - #ifdef CONFIG_PM_SLEEP - static int atmel_hlcdc_pwm_suspend(struct device *dev) - { -- struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev); -+ struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev); - - /* Keep the periph clock enabled if the PWM is still running. */ -- if (pwm_is_enabled(&chip->chip.pwms[0])) -- clk_disable_unprepare(chip->hlcdc->periph_clk); -+ if (!pwm_is_enabled(&atmel->chip.pwms[0])) -+ clk_disable_unprepare(atmel->hlcdc->periph_clk); - - return 0; - } - - static int atmel_hlcdc_pwm_resume(struct device *dev) - { -- struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev); -+ struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev); - struct pwm_state state; - int ret; - -- pwm_get_state(&chip->chip.pwms[0], &state); -+ pwm_get_state(&atmel->chip.pwms[0], &state); - - /* Re-enable the periph clock it was stopped during suspend. */ - if (!state.enabled) { -- ret = clk_prepare_enable(chip->hlcdc->periph_clk); -+ ret = clk_prepare_enable(atmel->hlcdc->periph_clk); - if (ret) - return ret; - } - -- return atmel_hlcdc_pwm_apply(&chip->chip, &chip->chip.pwms[0], &state); -+ return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0], -+ &state); - } - #endif - -@@ -244,14 +245,14 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) - { - const struct of_device_id *match; - struct device *dev = &pdev->dev; -- struct atmel_hlcdc_pwm *chip; -+ struct atmel_hlcdc_pwm *atmel; - struct atmel_hlcdc *hlcdc; - int ret; - - hlcdc = dev_get_drvdata(dev->parent); - -- chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); -- if (!chip) -+ atmel = devm_kzalloc(dev, sizeof(*atmel), GFP_KERNEL); -+ if (!atmel) - return -ENOMEM; - - ret = clk_prepare_enable(hlcdc->periph_clk); -@@ -260,33 +261,31 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) - - match = of_match_node(atmel_hlcdc_dt_ids, dev->parent->of_node); - if (match) -- chip->errata = match->data; -+ atmel->errata = match->data; - -- chip->hlcdc = hlcdc; -- chip->chip.ops = &atmel_hlcdc_pwm_ops; -- chip->chip.dev = dev; -- chip->chip.npwm = 1; -+ atmel->hlcdc = hlcdc; -+ atmel->chip.ops = &atmel_hlcdc_pwm_ops; -+ atmel->chip.dev = dev; -+ atmel->chip.npwm = 1; - -- ret = pwmchip_add(&chip->chip); -+ ret = pwmchip_add(&atmel->chip); - if (ret) { - clk_disable_unprepare(hlcdc->periph_clk); - return ret; - } - -- platform_set_drvdata(pdev, chip); -+ platform_set_drvdata(pdev, atmel); - - return 0; - } - --static int atmel_hlcdc_pwm_remove(struct platform_device *pdev) -+static void atmel_hlcdc_pwm_remove(struct platform_device *pdev) - { -- struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev); -+ struct atmel_hlcdc_pwm *atmel = platform_get_drvdata(pdev); - -- pwmchip_remove(&chip->chip); -+ pwmchip_remove(&atmel->chip); - -- clk_disable_unprepare(chip->hlcdc->periph_clk); -- -- return 0; -+ clk_disable_unprepare(atmel->hlcdc->periph_clk); - } - - static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = { -@@ -301,7 +300,7 @@ static struct platform_driver atmel_hlcdc_pwm_driver = { - .pm = &atmel_hlcdc_pwm_pm_ops, - }, - .probe = atmel_hlcdc_pwm_probe, -- .remove = atmel_hlcdc_pwm_remove, -+ .remove_new = atmel_hlcdc_pwm_remove, - }; - module_platform_driver(atmel_hlcdc_pwm_driver); - -diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c -index 652fdb8dc7bfa..0a7920cbd4949 100644 ---- a/drivers/pwm/pwm-sti.c -+++ b/drivers/pwm/pwm-sti.c -@@ -395,8 +395,17 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, - static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - const struct pwm_state *state) - { -+ struct sti_pwm_chip *pc = to_sti_pwmchip(chip); -+ struct sti_pwm_compat_data *cdata = pc->cdata; -+ struct device *dev = pc->dev; - int err; - -+ if (pwm->hwpwm >= cdata->pwm_num_devs) { -+ dev_err(dev, "device %u is not valid for pwm mode\n", -+ pwm->hwpwm); -+ return -EINVAL; -+ } -+ - if (state->polarity != PWM_POLARITY_NORMAL) - return -EINVAL; - -@@ -647,7 +656,7 @@ static int sti_pwm_probe(struct platform_device *pdev) - - pc->chip.dev = dev; - pc->chip.ops = &sti_pwm_ops; -- pc->chip.npwm = pc->cdata->pwm_num_devs; -+ pc->chip.npwm = max(cdata->pwm_num_devs, cdata->cpt_num_devs); - - for (i = 0; i < cdata->cpt_num_devs; i++) { - struct sti_cpt_ddata *ddata = &cdata->ddata[i]; -diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig -index 1660197866531..d93113b6ffaa1 100644 ---- a/drivers/remoteproc/Kconfig -+++ b/drivers/remoteproc/Kconfig -@@ -313,7 +313,7 @@ config ST_SLIM_REMOTEPROC - - config STM32_RPROC - tristate "STM32 remoteproc support" -- depends on ARCH_STM32 -+ depends on ARCH_STM32 || COMPILE_TEST - depends on REMOTEPROC - select MAILBOX - help -diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c -index 8746cbb1f168d..74da0393172c5 100644 ---- a/drivers/remoteproc/stm32_rproc.c -+++ b/drivers/remoteproc/stm32_rproc.c -@@ -118,10 +118,10 @@ static int stm32_rproc_mem_alloc(struct rproc *rproc, - struct device *dev = rproc->dev.parent; - void *va; - -- dev_dbg(dev, "map memory: %pa+%x\n", &mem->dma, mem->len); -- va = ioremap_wc(mem->dma, mem->len); -+ dev_dbg(dev, "map memory: %pad+%zx\n", &mem->dma, mem->len); -+ va = (__force void *)ioremap_wc(mem->dma, mem->len); - if (IS_ERR_OR_NULL(va)) { -- dev_err(dev, "Unable to map memory region: %pa+%x\n", -+ dev_err(dev, "Unable to map memory region: %pad+0x%zx\n", - &mem->dma, mem->len); - return -ENOMEM; - } -@@ -136,7 +136,7 @@ static int stm32_rproc_mem_release(struct rproc *rproc, - struct rproc_mem_entry *mem) - { - dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); -- iounmap(mem->va); -+ iounmap((__force __iomem void *)mem->va); - - return 0; - } -@@ -627,7 +627,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz) - - ddata->rsc_va = devm_ioremap_wc(dev, rsc_pa, RSC_TBL_SIZE); - if (IS_ERR_OR_NULL(ddata->rsc_va)) { -- dev_err(dev, "Unable to map memory region: %pa+%zx\n", -+ dev_err(dev, "Unable to map memory region: %pa+%x\n", - &rsc_pa, RSC_TBL_SIZE); - ddata->rsc_va = NULL; - return ERR_PTR(-ENOMEM); -@@ -641,7 +641,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz) - * entire area by overwriting it with the initial values stored in rproc->clean_table. - */ - *table_sz = RSC_TBL_SIZE; -- return (struct resource_table *)ddata->rsc_va; -+ return (__force struct resource_table *)ddata->rsc_va; - } - - static const struct rproc_ops st_rproc_ops = { -@@ -889,7 +889,7 @@ static int stm32_rproc_remove(struct platform_device *pdev) - return 0; - } - --static int __maybe_unused stm32_rproc_suspend(struct device *dev) -+static int stm32_rproc_suspend(struct device *dev) - { - struct rproc *rproc = dev_get_drvdata(dev); - struct stm32_rproc *ddata = rproc->priv; -@@ -900,7 +900,7 @@ static int __maybe_unused stm32_rproc_suspend(struct device *dev) - return 0; - } - --static int __maybe_unused stm32_rproc_resume(struct device *dev) -+static int stm32_rproc_resume(struct device *dev) - { - struct rproc *rproc = dev_get_drvdata(dev); - struct stm32_rproc *ddata = rproc->priv; -@@ -911,16 +911,16 @@ static int __maybe_unused stm32_rproc_resume(struct device *dev) - return 0; - } - --static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, -- stm32_rproc_suspend, stm32_rproc_resume); -+static DEFINE_SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, -+ stm32_rproc_suspend, stm32_rproc_resume); - - static struct platform_driver stm32_rproc_driver = { - .probe = stm32_rproc_probe, - .remove = stm32_rproc_remove, - .driver = { - .name = "stm32-rproc", -- .pm = &stm32_rproc_pm_ops, -- .of_match_table = of_match_ptr(stm32_rproc_match), -+ .pm = pm_ptr(&stm32_rproc_pm_ops), -+ .of_match_table = stm32_rproc_match, - }, - }; - module_platform_driver(stm32_rproc_driver); -diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig -index bb63edb507da4..87dc050ca004c 100644 ---- a/drivers/rtc/Kconfig -+++ b/drivers/rtc/Kconfig -@@ -1843,7 +1843,8 @@ config RTC_DRV_MT2712 - - config RTC_DRV_MT6397 - tristate "MediaTek PMIC based RTC" -- depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN) -+ depends on MFD_MT6397 || COMPILE_TEST -+ select IRQ_DOMAIN - help - This selects the MediaTek(R) RTC driver. RTC is part of MediaTek - MT6397 PMIC. You should enable MT6397 PMIC MFD before select -diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c -index d5caf36c56cdc..225c859d6da55 100644 ---- a/drivers/rtc/lib_test.c -+++ b/drivers/rtc/lib_test.c -@@ -54,7 +54,7 @@ static void rtc_time64_to_tm_test_date_range(struct kunit *test) - - days = div_s64(secs, 86400); - -- #define FAIL_MSG "%d/%02d/%02d (%2d) : %ld", \ -+ #define FAIL_MSG "%d/%02d/%02d (%2d) : %lld", \ - year, month, mday, yday, days - - KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG); -diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c -index f207de4a87a0f..341d65acd715d 100644 ---- a/drivers/s390/block/dasd.c -+++ b/drivers/s390/block/dasd.c -@@ -8,9 +8,6 @@ - * Copyright IBM Corp. 1999, 2009 - */ - --#define KMSG_COMPONENT "dasd" --#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -- - #include - #include - #include -@@ -73,7 +70,8 @@ static void dasd_profile_init(struct dasd_profile *, struct dentry *); - static void dasd_profile_exit(struct dasd_profile *); - static void dasd_hosts_init(struct dentry *, struct dasd_device *); - static void dasd_hosts_exit(struct dasd_device *); -- -+static int dasd_handle_autoquiesce(struct dasd_device *, struct dasd_ccw_req *, -+ unsigned int); - /* - * SECTION: Operations on the device structure. - */ -@@ -2327,7 +2325,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) - /* Non-temporary stop condition will trigger fail fast */ - if (device->stopped & ~DASD_STOPPED_PENDING && - test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && -- (!dasd_eer_enabled(device))) { -+ !dasd_eer_enabled(device) && device->aq_mask == 0) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -ENOLINK; - continue; -@@ -2803,20 +2801,18 @@ static void __dasd_process_block_ccw_queue(struct dasd_block *block, - dasd_log_sense(cqr, &cqr->irb); - } - -- /* First of all call extended error reporting. */ -- if (dasd_eer_enabled(base) && -- cqr->status == DASD_CQR_FAILED) { -- dasd_eer_write(base, cqr, DASD_EER_FATALERROR); -- -- /* restart request */ -+ /* -+ * First call extended error reporting and check for autoquiesce -+ */ -+ spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); -+ if (cqr->status == DASD_CQR_FAILED && -+ dasd_handle_autoquiesce(base, cqr, DASD_EER_FATALERROR)) { - cqr->status = DASD_CQR_FILLED; - cqr->retries = 255; -- spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); -- dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE); -- spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), -- flags); -+ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); - goto restart; - } -+ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); - - /* Process finished ERP request. */ - if (cqr->refers) { -@@ -2858,7 +2854,7 @@ static void __dasd_block_start_head(struct dasd_block *block) - /* Non-temporary stop condition will trigger fail fast */ - if (block->base->stopped & ~DASD_STOPPED_PENDING && - test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && -- (!dasd_eer_enabled(block->base))) { -+ !dasd_eer_enabled(block->base) && block->base->aq_mask == 0) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -ENOLINK; - dasd_schedule_block_bh(block); -@@ -3391,8 +3387,7 @@ static void dasd_generic_auto_online(void *data, async_cookie_t cookie) - - ret = ccw_device_set_online(cdev); - if (ret) -- pr_warn("%s: Setting the DASD online failed with rc=%d\n", -- dev_name(&cdev->dev), ret); -+ dev_warn(&cdev->dev, "Setting the DASD online failed with rc=%d\n", ret); - } - - /* -@@ -3479,8 +3474,11 @@ int dasd_generic_set_online(struct ccw_device *cdev, - { - struct dasd_discipline *discipline; - struct dasd_device *device; -+ struct device *dev; - int rc; - -+ dev = &cdev->dev; -+ - /* first online clears initial online feature flag */ - dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0); - device = dasd_create_device(cdev); -@@ -3493,11 +3491,10 @@ int dasd_generic_set_online(struct ccw_device *cdev, - /* Try to load the required module. */ - rc = request_module(DASD_DIAG_MOD); - if (rc) { -- pr_warn("%s Setting the DASD online failed " -- "because the required module %s " -- "could not be loaded (rc=%d)\n", -- dev_name(&cdev->dev), DASD_DIAG_MOD, -- rc); -+ dev_warn(dev, "Setting the DASD online failed " -+ "because the required module %s " -+ "could not be loaded (rc=%d)\n", -+ DASD_DIAG_MOD, rc); - dasd_delete_device(device); - return -ENODEV; - } -@@ -3505,8 +3502,7 @@ int dasd_generic_set_online(struct ccw_device *cdev, - /* Module init could have failed, so check again here after - * request_module(). */ - if (!dasd_diag_discipline_pointer) { -- pr_warn("%s Setting the DASD online failed because of missing DIAG discipline\n", -- dev_name(&cdev->dev)); -+ dev_warn(dev, "Setting the DASD online failed because of missing DIAG discipline\n"); - dasd_delete_device(device); - return -ENODEV; - } -@@ -3516,37 +3512,33 @@ int dasd_generic_set_online(struct ccw_device *cdev, - dasd_delete_device(device); - return -EINVAL; - } -+ device->base_discipline = base_discipline; - if (!try_module_get(discipline->owner)) { -- module_put(base_discipline->owner); - dasd_delete_device(device); - return -EINVAL; - } -- device->base_discipline = base_discipline; - device->discipline = discipline; - - /* check_device will allocate block device if necessary */ - rc = discipline->check_device(device); - if (rc) { -- pr_warn("%s Setting the DASD online with discipline %s failed with rc=%i\n", -- dev_name(&cdev->dev), discipline->name, rc); -- module_put(discipline->owner); -- module_put(base_discipline->owner); -+ dev_warn(dev, "Setting the DASD online with discipline %s failed with rc=%i\n", -+ discipline->name, rc); - dasd_delete_device(device); - return rc; - } - - dasd_set_target_state(device, DASD_STATE_ONLINE); - if (device->state <= DASD_STATE_KNOWN) { -- pr_warn("%s Setting the DASD online failed because of a missing discipline\n", -- dev_name(&cdev->dev)); -+ dev_warn(dev, "Setting the DASD online failed because of a missing discipline\n"); - rc = -ENODEV; - dasd_set_target_state(device, DASD_STATE_NEW); - if (device->block) - dasd_free_block(device->block); - dasd_delete_device(device); -- } else -- pr_debug("dasd_generic device %s found\n", -- dev_name(&cdev->dev)); -+ } else { -+ dev_dbg(dev, "dasd_generic device found\n"); -+ } - - wait_event(dasd_init_waitq, _wait_for_device(device)); - -@@ -3557,10 +3549,13 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online); - - int dasd_generic_set_offline(struct ccw_device *cdev) - { -+ int max_count, open_count, rc; - struct dasd_device *device; - struct dasd_block *block; -- int max_count, open_count, rc; - unsigned long flags; -+ struct device *dev; -+ -+ dev = &cdev->dev; - - rc = 0; - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); -@@ -3581,11 +3576,10 @@ int dasd_generic_set_offline(struct ccw_device *cdev) - open_count = atomic_read(&device->block->open_count); - if (open_count > max_count) { - if (open_count > 0) -- pr_warn("%s: The DASD cannot be set offline with open count %i\n", -- dev_name(&cdev->dev), open_count); -+ dev_warn(dev, "The DASD cannot be set offline with open count %i\n", -+ open_count); - else -- pr_warn("%s: The DASD cannot be set offline while it is in use\n", -- dev_name(&cdev->dev)); -+ dev_warn(dev, "The DASD cannot be set offline while it is in use\n"); - rc = -EBUSY; - goto out_err; - } -@@ -3682,8 +3676,8 @@ int dasd_generic_last_path_gone(struct dasd_device *device) - dev_warn(&device->cdev->dev, "No operational channel path is left " - "for the device\n"); - DBF_DEV_EVENT(DBF_WARNING, device, "%s", "last path gone"); -- /* First of all call extended error reporting. */ -- dasd_eer_write(device, NULL, DASD_EER_NOPATH); -+ /* First call extended error reporting and check for autoquiesce. */ -+ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOPATH); - - if (device->state < DASD_STATE_BASIC) - return 0; -@@ -3815,7 +3809,8 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) - "No verified channel paths remain for the device\n"); - DBF_DEV_EVENT(DBF_WARNING, device, - "%s", "last verified path gone"); -- dasd_eer_write(device, NULL, DASD_EER_NOPATH); -+ /* First call extended error reporting and check for autoquiesce. */ -+ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOPATH); - dasd_device_set_stop_bits(device, - DASD_STOPPED_DC_WAIT); - } -@@ -3837,7 +3832,8 @@ EXPORT_SYMBOL_GPL(dasd_generic_verify_path); - void dasd_generic_space_exhaust(struct dasd_device *device, - struct dasd_ccw_req *cqr) - { -- dasd_eer_write(device, NULL, DASD_EER_NOSPC); -+ /* First call extended error reporting and check for autoquiesce. */ -+ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOSPC); - - if (device->state < DASD_STATE_BASIC) - return; -@@ -3931,6 +3927,31 @@ void dasd_schedule_requeue(struct dasd_device *device) - } - EXPORT_SYMBOL(dasd_schedule_requeue); - -+static int dasd_handle_autoquiesce(struct dasd_device *device, -+ struct dasd_ccw_req *cqr, -+ unsigned int reason) -+{ -+ /* in any case write eer message with reason */ -+ if (dasd_eer_enabled(device)) -+ dasd_eer_write(device, cqr, reason); -+ -+ if (!test_bit(reason, &device->aq_mask)) -+ return 0; -+ -+ /* notify eer about autoquiesce */ -+ if (dasd_eer_enabled(device)) -+ dasd_eer_write(device, NULL, DASD_EER_AUTOQUIESCE); -+ -+ dev_info(&device->cdev->dev, -+ "The DASD has been put in the quiesce state\n"); -+ dasd_device_set_stop_bits(device, DASD_STOPPED_QUIESCE); -+ -+ if (device->features & DASD_FEATURE_REQUEUEQUIESCE) -+ dasd_schedule_requeue(device); -+ -+ return 1; -+} -+ - static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, - int rdc_buffer_size, - int magic) -diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c -index d4d31cd11d261..d16c699b9ac6d 100644 ---- a/drivers/s390/block/dasd_eer.c -+++ b/drivers/s390/block/dasd_eer.c -@@ -387,6 +387,7 @@ void dasd_eer_write(struct dasd_device *device, struct dasd_ccw_req *cqr, - break; - case DASD_EER_NOPATH: - case DASD_EER_NOSPC: -+ case DASD_EER_AUTOQUIESCE: - dasd_eer_write_standard_trigger(device, NULL, id); - break; - case DASD_EER_STATECHANGE: -diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h -index f50932518f83a..00bcd177264ac 100644 ---- a/drivers/s390/block/dasd_int.h -+++ b/drivers/s390/block/dasd_int.h -@@ -464,6 +464,7 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer; - #define DASD_EER_STATECHANGE 3 - #define DASD_EER_PPRCSUSPEND 4 - #define DASD_EER_NOSPC 5 -+#define DASD_EER_AUTOQUIESCE 31 - - /* DASD path handling */ - -@@ -641,6 +642,7 @@ struct dasd_device { - struct dasd_format_entry format_entry; - struct kset *paths_info; - struct dasd_copy_relation *copy; -+ unsigned long aq_mask; - }; - - struct dasd_block { -diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h -index 7bd2ba1ad4d11..f30fe324e6ecc 100644 ---- a/drivers/scsi/bfa/bfa.h -+++ b/drivers/scsi/bfa/bfa.h -@@ -20,7 +20,6 @@ - struct bfa_s; - - typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); --typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status); - - /* - * Interrupt message handlers -@@ -437,4 +436,12 @@ struct bfa_cb_pending_q_s { - (__qe)->data = (__data); \ - } while (0) - -+#define bfa_pending_q_init_status(__qe, __cbfn, __cbarg, __data) do { \ -+ bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \ -+ (__qe)->hcb_qe.cbfn_status = (__cbfn); \ -+ (__qe)->hcb_qe.cbarg = (__cbarg); \ -+ (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \ -+ (__qe)->data = (__data); \ -+} while (0) -+ - #endif /* __BFA_H__ */ -diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c -index 6846ca8f7313c..3438d0b8ba062 100644 ---- a/drivers/scsi/bfa/bfa_core.c -+++ b/drivers/scsi/bfa/bfa_core.c -@@ -1907,15 +1907,13 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) - struct list_head *qe; - struct list_head *qen; - struct bfa_cb_qe_s *hcb_qe; -- bfa_cb_cbfn_status_t cbfn; - - list_for_each_safe(qe, qen, comp_q) { - hcb_qe = (struct bfa_cb_qe_s *) qe; - if (hcb_qe->pre_rmv) { - /* qe is invalid after return, dequeue before cbfn() */ - list_del(qe); -- cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn); -- cbfn(hcb_qe->cbarg, hcb_qe->fw_status); -+ hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status); - } else - hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); - } -diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h -index 933a1c3890ff5..5e568d6d7b261 100644 ---- a/drivers/scsi/bfa/bfa_ioc.h -+++ b/drivers/scsi/bfa/bfa_ioc.h -@@ -361,14 +361,18 @@ struct bfa_reqq_wait_s { - void *cbarg; - }; - --typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); -+typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); -+typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status); - - /* - * Generic BFA callback element. - */ - struct bfa_cb_qe_s { - struct list_head qe; -- bfa_cb_cbfn_t cbfn; -+ union { -+ bfa_cb_cbfn_status_t cbfn_status; -+ bfa_cb_cbfn_t cbfn; -+ }; - bfa_boolean_t once; - bfa_boolean_t pre_rmv; /* set for stack based qe(s) */ - bfa_status_t fw_status; /* to access fw status in comp proc */ -diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c -index be8dfbe13e904..524e4e6979c9f 100644 ---- a/drivers/scsi/bfa/bfad_bsg.c -+++ b/drivers/scsi/bfa/bfad_bsg.c -@@ -2135,8 +2135,7 @@ bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd) - struct bfa_cb_pending_q_s cb_qe; - - init_completion(&fcomp.comp); -- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, -- &fcomp, &iocmd->stats); -+ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); - spin_lock_irqsave(&bfad->bfad_lock, flags); - iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); -@@ -2159,7 +2158,7 @@ bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) - struct bfa_cb_pending_q_s cb_qe; - - init_completion(&fcomp.comp); -- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); -+ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); - - spin_lock_irqsave(&bfad->bfad_lock, flags); - iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); -@@ -2443,8 +2442,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); - - init_completion(&fcomp.comp); -- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, -- &fcomp, &iocmd->stats); -+ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); - - spin_lock_irqsave(&bfad->bfad_lock, flags); - WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); -@@ -2474,8 +2472,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); - - init_completion(&fcomp.comp); -- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, -- &fcomp, NULL); -+ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); - - spin_lock_irqsave(&bfad->bfad_lock, flags); - WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); -diff --git a/drivers/scsi/csiostor/csio_defs.h b/drivers/scsi/csiostor/csio_defs.h -index c38017b4af982..e50e93e7fe5a1 100644 ---- a/drivers/scsi/csiostor/csio_defs.h -+++ b/drivers/scsi/csiostor/csio_defs.h -@@ -73,7 +73,21 @@ csio_list_deleted(struct list_head *list) - #define csio_list_prev(elem) (((struct list_head *)(elem))->prev) - - /* State machine */ --typedef void (*csio_sm_state_t)(void *, uint32_t); -+struct csio_lnode; -+ -+/* State machine evets */ -+enum csio_ln_ev { -+ CSIO_LNE_NONE = (uint32_t)0, -+ CSIO_LNE_LINKUP, -+ CSIO_LNE_FAB_INIT_DONE, -+ CSIO_LNE_LINK_DOWN, -+ CSIO_LNE_DOWN_LINK, -+ CSIO_LNE_LOGO, -+ CSIO_LNE_CLOSE, -+ CSIO_LNE_MAX_EVENT, -+}; -+ -+typedef void (*csio_sm_state_t)(struct csio_lnode *ln, enum csio_ln_ev evt); - - struct csio_sm { - struct list_head sm_list; -@@ -83,7 +97,7 @@ struct csio_sm { - static inline void - csio_set_state(void *smp, void *state) - { -- ((struct csio_sm *)smp)->sm_state = (csio_sm_state_t)state; -+ ((struct csio_sm *)smp)->sm_state = state; - } - - static inline void -diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c -index d5ac938970232..5b3ffefae476d 100644 ---- a/drivers/scsi/csiostor/csio_lnode.c -+++ b/drivers/scsi/csiostor/csio_lnode.c -@@ -1095,7 +1095,7 @@ csio_handle_link_down(struct csio_hw *hw, uint8_t portid, uint32_t fcfi, - int - csio_is_lnode_ready(struct csio_lnode *ln) - { -- return (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)); -+ return (csio_get_state(ln) == csio_lns_ready); - } - - /*****************************************************************************/ -@@ -1366,15 +1366,15 @@ csio_free_fcfinfo(struct kref *kref) - void - csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str) - { -- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_uninit)) { -+ if (csio_get_state(ln) == csio_lns_uninit) { - strcpy(str, "UNINIT"); - return; - } -- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)) { -+ if (csio_get_state(ln) == csio_lns_ready) { - strcpy(str, "READY"); - return; - } -- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_offline)) { -+ if (csio_get_state(ln) == csio_lns_offline) { - strcpy(str, "OFFLINE"); - return; - } -diff --git a/drivers/scsi/csiostor/csio_lnode.h b/drivers/scsi/csiostor/csio_lnode.h -index 372a67d122d38..607698a0f0631 100644 ---- a/drivers/scsi/csiostor/csio_lnode.h -+++ b/drivers/scsi/csiostor/csio_lnode.h -@@ -53,19 +53,6 @@ - extern int csio_fcoe_rnodes; - extern int csio_fdmi_enable; - --/* State machine evets */ --enum csio_ln_ev { -- CSIO_LNE_NONE = (uint32_t)0, -- CSIO_LNE_LINKUP, -- CSIO_LNE_FAB_INIT_DONE, -- CSIO_LNE_LINK_DOWN, -- CSIO_LNE_DOWN_LINK, -- CSIO_LNE_LOGO, -- CSIO_LNE_CLOSE, -- CSIO_LNE_MAX_EVENT, --}; -- -- - struct csio_fcf_info { - struct list_head list; - uint8_t priority; -diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c -index 809be43f440dc..8e6ac08e553bb 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_base.c -+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c -@@ -7398,7 +7398,9 @@ _base_wait_for_iocstate(struct MPT3SAS_ADAPTER *ioc, int timeout) - return -EFAULT; - } - -- issue_diag_reset: -+ return 0; -+ -+issue_diag_reset: - rc = _base_diag_reset(ioc); - return rc; - } -diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c -index 1d2b27e3ea63f..b811446e0fa55 100644 ---- a/drivers/soc/fsl/dpio/dpio-service.c -+++ b/drivers/soc/fsl/dpio/dpio-service.c -@@ -523,7 +523,7 @@ int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, - struct qbman_eq_desc *ed; - int i, ret; - -- ed = kcalloc(sizeof(struct qbman_eq_desc), 32, GFP_KERNEL); -+ ed = kcalloc(32, sizeof(struct qbman_eq_desc), GFP_KERNEL); - if (!ed) - return -ENOMEM; - -diff --git a/drivers/soc/microchip/Kconfig b/drivers/soc/microchip/Kconfig -index eb656b33156ba..f19e74d342aa2 100644 ---- a/drivers/soc/microchip/Kconfig -+++ b/drivers/soc/microchip/Kconfig -@@ -1,5 +1,5 @@ - config POLARFIRE_SOC_SYS_CTRL -- tristate "POLARFIRE_SOC_SYS_CTRL" -+ tristate "Microchip PolarFire SoC (MPFS) system controller support" - depends on POLARFIRE_SOC_MAILBOX - help - This driver adds support for the PolarFire SoC (MPFS) system controller. -diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c -index 9a90f241bb97f..6efe36aeb48e9 100644 ---- a/drivers/soc/qcom/rpmhpd.c -+++ b/drivers/soc/qcom/rpmhpd.c -@@ -195,7 +195,6 @@ static struct rpmhpd *sa8540p_rpmhpds[] = { - [SC8280XP_CX] = &cx, - [SC8280XP_CX_AO] = &cx_ao, - [SC8280XP_EBI] = &ebi, -- [SC8280XP_GFX] = &gfx, - [SC8280XP_LCX] = &lcx, - [SC8280XP_LMX] = &lmx, - [SC8280XP_MMCX] = &mmcx, -diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c -index 6e95efb50acbc..f9ec8742917a6 100644 ---- a/drivers/spi/spi-mt65xx.c -+++ b/drivers/spi/spi-mt65xx.c -@@ -787,17 +787,19 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) - mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len); - mtk_spi_setup_packet(master); - -- cnt = mdata->xfer_len / 4; -- iowrite32_rep(mdata->base + SPI_TX_DATA_REG, -- trans->tx_buf + mdata->num_xfered, cnt); -+ if (trans->tx_buf) { -+ cnt = mdata->xfer_len / 4; -+ iowrite32_rep(mdata->base + SPI_TX_DATA_REG, -+ trans->tx_buf + mdata->num_xfered, cnt); - -- remainder = mdata->xfer_len % 4; -- if (remainder > 0) { -- reg_val = 0; -- memcpy(®_val, -- trans->tx_buf + (cnt * 4) + mdata->num_xfered, -- remainder); -- writel(reg_val, mdata->base + SPI_TX_DATA_REG); -+ remainder = mdata->xfer_len % 4; -+ if (remainder > 0) { -+ reg_val = 0; -+ memcpy(®_val, -+ trans->tx_buf + (cnt * 4) + mdata->num_xfered, -+ remainder); -+ writel(reg_val, mdata->base + SPI_TX_DATA_REG); -+ } - } - - mtk_spi_enable_transfer(master); -diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c -index 87d36948c6106..c6bd86a5335ab 100644 ---- a/drivers/staging/greybus/light.c -+++ b/drivers/staging/greybus/light.c -@@ -100,15 +100,15 @@ static struct led_classdev *get_channel_cdev(struct gb_channel *channel) - static struct gb_channel *get_channel_from_mode(struct gb_light *light, - u32 mode) - { -- struct gb_channel *channel = NULL; -+ struct gb_channel *channel; - int i; - - for (i = 0; i < light->channels_count; i++) { - channel = &light->channels[i]; -- if (channel && channel->mode == mode) -- break; -+ if (channel->mode == mode) -+ return channel; - } -- return channel; -+ return NULL; - } - - static int __gb_lights_flash_intensity_set(struct gb_channel *channel, -diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c -index 0c61a2dec2211..81fc4835679f3 100644 ---- a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c -+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c -@@ -1462,7 +1462,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio - budget_av->has_saa7113 = 1; - err = saa7146_vv_init(dev, &vv_data); - if (err != 0) { -- /* fixme: proper cleanup here */ -+ ttpci_budget_deinit(&budget_av->budget); -+ kfree(budget_av); - ERR("cannot init vv subsystem\n"); - return err; - } -@@ -1471,9 +1472,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio - vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - - if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) { -- /* fixme: proper cleanup here */ -- ERR("cannot register capture v4l2 device\n"); - saa7146_vv_release(dev); -+ ttpci_budget_deinit(&budget_av->budget); -+ kfree(budget_av); -+ ERR("cannot register capture v4l2 device\n"); - return err; - } - -diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c -index 1fd39a2fca98a..95cca281e8a37 100644 ---- a/drivers/staging/media/imx/imx-media-csc-scaler.c -+++ b/drivers/staging/media/imx/imx-media-csc-scaler.c -@@ -803,6 +803,7 @@ static int ipu_csc_scaler_release(struct file *file) - - dev_dbg(priv->dev, "Releasing instance %p\n", ctx); - -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdlr); - v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h -index 93a2196006f73..cb99610f3e128 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus.h -+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h -@@ -109,6 +109,11 @@ struct cedrus_buffer { - unsigned int position; - enum cedrus_h264_pic_type pic_type; - } h264; -+ struct { -+ void *mv_col_buf; -+ dma_addr_t mv_col_buf_dma; -+ ssize_t mv_col_buf_size; -+ } h265; - } codec; - }; - -@@ -142,10 +147,6 @@ struct cedrus_ctx { - ssize_t intra_pred_buf_size; - } h264; - struct { -- void *mv_col_buf; -- dma_addr_t mv_col_buf_addr; -- ssize_t mv_col_buf_size; -- ssize_t mv_col_buf_unit_size; - void *neighbor_info_buf; - dma_addr_t neighbor_info_buf_addr; - void *entry_points_buf; -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c -index 625f77a8c5bde..9f13c942a806b 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c -@@ -90,12 +90,13 @@ static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data, - } - - static inline dma_addr_t --cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx, -- unsigned int index, unsigned int field) -+cedrus_h265_frame_info_mv_col_buf_addr(struct vb2_buffer *buf, -+ unsigned int field) - { -- return ctx->codec.h265.mv_col_buf_addr + index * -- ctx->codec.h265.mv_col_buf_unit_size + -- field * ctx->codec.h265.mv_col_buf_unit_size / 2; -+ struct cedrus_buffer *cedrus_buf = vb2_to_cedrus_buffer(buf); -+ -+ return cedrus_buf->codec.h265.mv_col_buf_dma + -+ field * cedrus_buf->codec.h265.mv_col_buf_size / 2; - } - - static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx, -@@ -108,9 +109,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx, - dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buf, 0); - dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buf, 1); - dma_addr_t mv_col_buf_addr[2] = { -- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, 0), -- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, -- field_pic ? 1 : 0) -+ cedrus_h265_frame_info_mv_col_buf_addr(buf, 0), -+ cedrus_h265_frame_info_mv_col_buf_addr(buf, field_pic ? 1 : 0) - }; - u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO + - VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index; -@@ -412,12 +412,13 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) - unsigned int width_in_ctb_luma, ctb_size_luma; - unsigned int log2_max_luma_coding_block_size; - unsigned int ctb_addr_x, ctb_addr_y; -+ struct cedrus_buffer *cedrus_buf; - dma_addr_t src_buf_addr; -- dma_addr_t src_buf_end_addr; - u32 chroma_log2_weight_denom; - u32 num_entry_point_offsets; - u32 output_pic_list_index; - u32 pic_order_cnt[2]; -+ size_t slice_bytes; - u8 padding; - int count; - u32 reg; -@@ -428,6 +429,8 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) - decode_params = run->h265.decode_params; - pred_weight_table = &slice_params->pred_weight_table; - num_entry_point_offsets = slice_params->num_entry_point_offsets; -+ cedrus_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf); -+ slice_bytes = vb2_get_plane_payload(&run->src->vb2_buf, 0); - - /* - * If entry points offsets are present, we should get them -@@ -445,31 +448,25 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) - DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma); - - /* MV column buffer size and allocation. */ -- if (!ctx->codec.h265.mv_col_buf_size) { -- unsigned int num_buffers = -- run->dst->vb2_buf.vb2_queue->num_buffers; -- -+ if (!cedrus_buf->codec.h265.mv_col_buf_size) { - /* - * Each CTB requires a MV col buffer with a specific unit size. - * Since the address is given with missing lsb bits, 1 KiB is - * added to each buffer to ensure proper alignment. - */ -- ctx->codec.h265.mv_col_buf_unit_size = -+ cedrus_buf->codec.h265.mv_col_buf_size = - DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) * - DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) * - CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K; - -- ctx->codec.h265.mv_col_buf_size = num_buffers * -- ctx->codec.h265.mv_col_buf_unit_size; -- - /* Buffer is never accessed by CPU, so we can skip kernel mapping. */ -- ctx->codec.h265.mv_col_buf = -+ cedrus_buf->codec.h265.mv_col_buf = - dma_alloc_attrs(dev->dev, -- ctx->codec.h265.mv_col_buf_size, -- &ctx->codec.h265.mv_col_buf_addr, -+ cedrus_buf->codec.h265.mv_col_buf_size, -+ &cedrus_buf->codec.h265.mv_col_buf_dma, - GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); -- if (!ctx->codec.h265.mv_col_buf) { -- ctx->codec.h265.mv_col_buf_size = 0; -+ if (!cedrus_buf->codec.h265.mv_col_buf) { -+ cedrus_buf->codec.h265.mv_col_buf_size = 0; - return -ENOMEM; - } - } -@@ -481,7 +478,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) - - cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0); - -- reg = slice_params->bit_size; -+ reg = slice_bytes * 8; - cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg); - - /* Source beginning and end addresses. */ -@@ -495,10 +492,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) - - cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg); - -- src_buf_end_addr = src_buf_addr + -- DIV_ROUND_UP(slice_params->bit_size, 8); -- -- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr); -+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_addr + slice_bytes); - cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg); - - /* Coding tree block address */ -@@ -816,9 +810,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx) - { - struct cedrus_dev *dev = ctx->dev; - -- /* The buffer size is calculated at setup time. */ -- ctx->codec.h265.mv_col_buf_size = 0; -- - /* Buffer is never accessed by CPU, so we can skip kernel mapping. */ - ctx->codec.h265.neighbor_info_buf = - dma_alloc_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE, -@@ -845,14 +836,24 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx) - static void cedrus_h265_stop(struct cedrus_ctx *ctx) - { - struct cedrus_dev *dev = ctx->dev; -+ struct cedrus_buffer *buf; -+ struct vb2_queue *vq; -+ unsigned int i; - -- if (ctx->codec.h265.mv_col_buf_size > 0) { -- dma_free_attrs(dev->dev, ctx->codec.h265.mv_col_buf_size, -- ctx->codec.h265.mv_col_buf, -- ctx->codec.h265.mv_col_buf_addr, -- DMA_ATTR_NO_KERNEL_MAPPING); -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); -+ -+ for (i = 0; i < vq->num_buffers; i++) { -+ buf = vb2_to_cedrus_buffer(vb2_get_buffer(vq, i)); - -- ctx->codec.h265.mv_col_buf_size = 0; -+ if (buf->codec.h265.mv_col_buf_size > 0) { -+ dma_free_attrs(dev->dev, -+ buf->codec.h265.mv_col_buf_size, -+ buf->codec.h265.mv_col_buf, -+ buf->codec.h265.mv_col_buf_dma, -+ DMA_ATTR_NO_KERNEL_MAPPING); -+ -+ buf->codec.h265.mv_col_buf_size = 0; -+ } - } - - dma_free_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE, -diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c -index dca1abe363248..55451ff846520 100644 ---- a/drivers/tty/serial/8250/8250_exar.c -+++ b/drivers/tty/serial/8250/8250_exar.c -@@ -714,6 +714,7 @@ static void exar_pci_remove(struct pci_dev *pcidev) - for (i = 0; i < priv->nr; i++) - serial8250_unregister_port(priv->line[i]); - -+ /* Ensure that every init quirk is properly torn down */ - if (priv->board->exit) - priv->board->exit(pcidev); - } -@@ -728,10 +729,6 @@ static int __maybe_unused exar_suspend(struct device *dev) - if (priv->line[i] >= 0) - serial8250_suspend_port(priv->line[i]); - -- /* Ensure that every init quirk is properly torn down */ -- if (priv->board->exit) -- priv->board->exit(pcidev); -- - return 0; - } - -diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c -index 163a89f84c9c2..444f89eb2d4b7 100644 ---- a/drivers/tty/serial/max310x.c -+++ b/drivers/tty/serial/max310x.c -@@ -1459,7 +1459,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty - if (!ret) - return 0; - -- dev_err(dev, "Unable to reguest IRQ %i\n", irq); -+ dev_err(dev, "Unable to request IRQ %i\n", irq); - - out_uart: - for (i = 0; i < devtype->nr; i++) { -diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c -index aa2c51b84116f..589daed19e625 100644 ---- a/drivers/tty/serial/samsung_tty.c -+++ b/drivers/tty/serial/samsung_tty.c -@@ -996,11 +996,10 @@ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) - if ((ufstat & info->tx_fifomask) != 0 || - (ufstat & info->tx_fifofull)) - return 0; -- -- return 1; -+ return TIOCSER_TEMT; - } - -- return s3c24xx_serial_txempty_nofifo(port); -+ return s3c24xx_serial_txempty_nofifo(port) ? TIOCSER_TEMT : 0; - } - - /* no modem control lines */ -diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c -index 981d2bfcf9a5b..9e30ef2b6eb8c 100644 ---- a/drivers/tty/vt/vt.c -+++ b/drivers/tty/vt/vt.c -@@ -2515,7 +2515,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) - } - return; - case EScsiignore: -- if (c >= 20 && c <= 0x3f) -+ if (c >= 0x20 && c <= 0x3f) - return; - vc->vc_state = ESnormal; - return; -diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c -index 538c1b9a28835..c42d5aa99e81a 100644 ---- a/drivers/usb/gadget/udc/net2272.c -+++ b/drivers/usb/gadget/udc/net2272.c -@@ -2650,7 +2650,7 @@ net2272_plat_probe(struct platform_device *pdev) - goto err_req; - } - -- ret = net2272_probe_fin(dev, IRQF_TRIGGER_LOW); -+ ret = net2272_probe_fin(dev, irqflags); - if (ret) - goto err_io; - -diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c -index 3dc5c04e7cbf9..953df04b40d40 100644 ---- a/drivers/usb/phy/phy-generic.c -+++ b/drivers/usb/phy/phy-generic.c -@@ -265,6 +265,13 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) - return -EPROBE_DEFER; - } - -+ nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus"); -+ if (PTR_ERR(nop->vbus_draw) == -ENODEV) -+ nop->vbus_draw = NULL; -+ if (IS_ERR(nop->vbus_draw)) -+ return dev_err_probe(dev, PTR_ERR(nop->vbus_draw), -+ "could not get vbus regulator\n"); -+ - nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus"); - if (PTR_ERR(nop->vbus_draw) == -ENODEV) - nop->vbus_draw = NULL; -diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c -index 2b7e796c48897..74d295312466f 100644 ---- a/drivers/vdpa/mlx5/net/mlx5_vnet.c -+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c -@@ -185,8 +185,6 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev); - - static bool mlx5_vdpa_debug; - --#define MLX5_CVQ_MAX_ENT 16 -- - #define MLX5_LOG_VIO_FLAG(_feature) \ - do { \ - if (features & BIT_ULL(_feature)) \ -@@ -1980,9 +1978,16 @@ static void mlx5_vdpa_set_vq_num(struct vdpa_device *vdev, u16 idx, u32 num) - struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); - struct mlx5_vdpa_virtqueue *mvq; - -- if (!is_index_valid(mvdev, idx) || is_ctrl_vq_idx(mvdev, idx)) -+ if (!is_index_valid(mvdev, idx)) - return; - -+ if (is_ctrl_vq_idx(mvdev, idx)) { -+ struct mlx5_control_vq *cvq = &mvdev->cvq; -+ -+ cvq->vring.vring.num = num; -+ return; -+ } -+ - mvq = &ndev->vqs[idx]; - mvq->num_ent = num; - } -@@ -2512,7 +2517,7 @@ static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev) - u16 idx = cvq->vring.last_avail_idx; - - err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features, -- MLX5_CVQ_MAX_ENT, false, -+ cvq->vring.vring.num, false, - (struct vring_desc *)(uintptr_t)cvq->desc_addr, - (struct vring_avail *)(uintptr_t)cvq->driver_addr, - (struct vring_used *)(uintptr_t)cvq->device_addr); -diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c -index 61bde476cf9c8..e7fc25bfdd237 100644 ---- a/drivers/vdpa/vdpa_sim/vdpa_sim.c -+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c -@@ -120,7 +120,7 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim) - for (i = 0; i < vdpasim->dev_attr.nas; i++) - vhost_iotlb_reset(&vdpasim->iommu[i]); - -- vdpasim->running = true; -+ vdpasim->running = false; - spin_unlock(&vdpasim->iommu_lock); - - vdpasim->features = 0; -@@ -513,6 +513,7 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status) - - spin_lock(&vdpasim->lock); - vdpasim->status = status; -+ vdpasim->running = (status & VIRTIO_CONFIG_S_DRIVER_OK) != 0; - spin_unlock(&vdpasim->lock); - } - -diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c -index 882359dd288c0..aa00379392a0f 100644 ---- a/drivers/video/backlight/da9052_bl.c -+++ b/drivers/video/backlight/da9052_bl.c -@@ -117,6 +117,7 @@ static int da9052_backlight_probe(struct platform_device *pdev) - wleds->led_reg = platform_get_device_id(pdev)->driver_data; - wleds->state = DA9052_WLEDS_OFF; - -+ memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.max_brightness = DA9052_MAX_BRIGHTNESS; - -diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c -index 475f35635bf67..0d43f6326750f 100644 ---- a/drivers/video/backlight/lm3630a_bl.c -+++ b/drivers/video/backlight/lm3630a_bl.c -@@ -231,7 +231,7 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) - if (rval < 0) - goto out_i2c_err; - brightness |= rval; -- goto out; -+ return brightness; - } - - /* disable sleep */ -@@ -242,11 +242,8 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) - rval = lm3630a_read(pchip, REG_BRT_A); - if (rval < 0) - goto out_i2c_err; -- brightness = rval; -+ return rval; - --out: -- bl->props.brightness = brightness; -- return bl->props.brightness; - out_i2c_err: - dev_err(pchip->dev, "i2c failed to access register\n"); - return 0; -@@ -306,7 +303,7 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) - if (rval < 0) - goto out_i2c_err; - brightness |= rval; -- goto out; -+ return brightness; - } - - /* disable sleep */ -@@ -317,11 +314,8 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) - rval = lm3630a_read(pchip, REG_BRT_B); - if (rval < 0) - goto out_i2c_err; -- brightness = rval; -+ return rval; - --out: -- bl->props.brightness = brightness; -- return bl->props.brightness; - out_i2c_err: - dev_err(pchip->dev, "i2c failed to access register\n"); - return 0; -@@ -339,6 +333,7 @@ static int lm3630a_backlight_register(struct lm3630a_chip *pchip) - struct backlight_properties props; - const char *label; - -+ memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { - props.brightness = pdata->leda_init_brt; -diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c -index 6580911671a3e..4c9726a7fa720 100644 ---- a/drivers/video/backlight/lm3639_bl.c -+++ b/drivers/video/backlight/lm3639_bl.c -@@ -339,6 +339,7 @@ static int lm3639_probe(struct i2c_client *client, - } - - /* backlight */ -+ memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.brightness = pdata->init_brt_led; - props.max_brightness = pdata->max_brt_led; -diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c -index ba42f3fe0c739..d9b95dbd40d30 100644 ---- a/drivers/video/backlight/lp8788_bl.c -+++ b/drivers/video/backlight/lp8788_bl.c -@@ -191,6 +191,7 @@ static int lp8788_backlight_register(struct lp8788_bl *bl) - int init_brt; - char *name; - -+ memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_PLATFORM; - props.max_brightness = MAX_BRIGHTNESS; - -diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c -index 570a71509d2a9..78d51deab87aa 100644 ---- a/drivers/watchdog/stm32_iwdg.c -+++ b/drivers/watchdog/stm32_iwdg.c -@@ -21,6 +21,8 @@ - #include - #include - -+#define DEFAULT_TIMEOUT 10 -+ - /* IWDG registers */ - #define IWDG_KR 0x00 /* Key register */ - #define IWDG_PR 0x04 /* Prescaler Register */ -@@ -249,6 +251,7 @@ static int stm32_iwdg_probe(struct platform_device *pdev) - wdd->parent = dev; - wdd->info = &stm32_iwdg_info; - wdd->ops = &stm32_iwdg_ops; -+ wdd->timeout = DEFAULT_TIMEOUT; - wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate); - wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler * - 1000) / wdt->rate; -diff --git a/fs/afs/dir.c b/fs/afs/dir.c -index 6e2c967fae6fc..07dc4ec73520c 100644 ---- a/fs/afs/dir.c -+++ b/fs/afs/dir.c -@@ -473,16 +473,6 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode, - continue; - } - -- /* Don't expose silly rename entries to userspace. */ -- if (nlen > 6 && -- dire->u.name[0] == '.' && -- ctx->actor != afs_lookup_filldir && -- ctx->actor != afs_lookup_one_filldir && -- memcmp(dire->u.name, ".__afs", 6) == 0) { -- ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent); -- continue; -- } -- - /* found the next entry */ - if (!dir_emit(ctx, dire->u.name, nlen, - ntohl(dire->u.vnode), -diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c -index 507b44d18572d..4cbf386166209 100644 ---- a/fs/btrfs/block-rsv.c -+++ b/fs/btrfs/block-rsv.c -@@ -512,7 +512,7 @@ struct btrfs_block_rsv *btrfs_use_block_rsv(struct btrfs_trans_handle *trans, - - block_rsv = get_block_rsv(trans, root); - -- if (unlikely(block_rsv->size == 0)) -+ if (unlikely(btrfs_block_rsv_size(block_rsv) == 0)) - goto try_reserve; - again: - ret = btrfs_block_rsv_use_bytes(block_rsv, blocksize); -diff --git a/fs/btrfs/block-rsv.h b/fs/btrfs/block-rsv.h -index 578c3497a455c..df87c4949d065 100644 ---- a/fs/btrfs/block-rsv.h -+++ b/fs/btrfs/block-rsv.h -@@ -101,4 +101,36 @@ static inline bool btrfs_block_rsv_full(const struct btrfs_block_rsv *rsv) - return data_race(rsv->full); - } - -+/* -+ * Get the reserved mount of a block reserve in a context where getting a stale -+ * value is acceptable, instead of accessing it directly and trigger data race -+ * warning from KCSAN. -+ */ -+static inline u64 btrfs_block_rsv_reserved(struct btrfs_block_rsv *rsv) -+{ -+ u64 ret; -+ -+ spin_lock(&rsv->lock); -+ ret = rsv->reserved; -+ spin_unlock(&rsv->lock); -+ -+ return ret; -+} -+ -+/* -+ * Get the size of a block reserve in a context where getting a stale value is -+ * acceptable, instead of accessing it directly and trigger data race warning -+ * from KCSAN. -+ */ -+static inline u64 btrfs_block_rsv_size(struct btrfs_block_rsv *rsv) -+{ -+ u64 ret; -+ -+ spin_lock(&rsv->lock); -+ ret = rsv->size; -+ spin_unlock(&rsv->lock); -+ -+ return ret; -+} -+ - #endif /* BTRFS_BLOCK_RSV_H */ -diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c -index 2635fb4bffa06..8b75f436a9a3c 100644 ---- a/fs/btrfs/space-info.c -+++ b/fs/btrfs/space-info.c -@@ -847,7 +847,7 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info, - static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info, - struct btrfs_space_info *space_info) - { -- u64 global_rsv_size = fs_info->global_block_rsv.reserved; -+ const u64 global_rsv_size = btrfs_block_rsv_reserved(&fs_info->global_block_rsv); - u64 ordered, delalloc; - u64 total = writable_total_bytes(fs_info, space_info); - u64 thresh; -@@ -948,8 +948,8 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info, - ordered = percpu_counter_read_positive(&fs_info->ordered_bytes) >> 1; - delalloc = percpu_counter_read_positive(&fs_info->delalloc_bytes); - if (ordered >= delalloc) -- used += fs_info->delayed_refs_rsv.reserved + -- fs_info->delayed_block_rsv.reserved; -+ used += btrfs_block_rsv_reserved(&fs_info->delayed_refs_rsv) + -+ btrfs_block_rsv_reserved(&fs_info->delayed_block_rsv); - else - used += space_info->bytes_may_use - global_rsv_size; - -@@ -1164,7 +1164,7 @@ static void btrfs_preempt_reclaim_metadata_space(struct work_struct *work) - enum btrfs_flush_state flush; - u64 delalloc_size = 0; - u64 to_reclaim, block_rsv_size; -- u64 global_rsv_size = global_rsv->reserved; -+ const u64 global_rsv_size = btrfs_block_rsv_reserved(global_rsv); - - loops++; - -@@ -1176,9 +1176,9 @@ static void btrfs_preempt_reclaim_metadata_space(struct work_struct *work) - * assume it's tied up in delalloc reservations. - */ - block_rsv_size = global_rsv_size + -- delayed_block_rsv->reserved + -- delayed_refs_rsv->reserved + -- trans_rsv->reserved; -+ btrfs_block_rsv_reserved(delayed_block_rsv) + -+ btrfs_block_rsv_reserved(delayed_refs_rsv) + -+ btrfs_block_rsv_reserved(trans_rsv); - if (block_rsv_size < space_info->bytes_may_use) - delalloc_size = space_info->bytes_may_use - block_rsv_size; - -@@ -1198,16 +1198,16 @@ static void btrfs_preempt_reclaim_metadata_space(struct work_struct *work) - to_reclaim = delalloc_size; - flush = FLUSH_DELALLOC; - } else if (space_info->bytes_pinned > -- (delayed_block_rsv->reserved + -- delayed_refs_rsv->reserved)) { -+ (btrfs_block_rsv_reserved(delayed_block_rsv) + -+ btrfs_block_rsv_reserved(delayed_refs_rsv))) { - to_reclaim = space_info->bytes_pinned; - flush = COMMIT_TRANS; -- } else if (delayed_block_rsv->reserved > -- delayed_refs_rsv->reserved) { -- to_reclaim = delayed_block_rsv->reserved; -+ } else if (btrfs_block_rsv_reserved(delayed_block_rsv) > -+ btrfs_block_rsv_reserved(delayed_refs_rsv)) { -+ to_reclaim = btrfs_block_rsv_reserved(delayed_block_rsv); - flush = FLUSH_DELAYED_ITEMS_NR; - } else { -- to_reclaim = delayed_refs_rsv->reserved; -+ to_reclaim = btrfs_block_rsv_reserved(delayed_refs_rsv); - flush = FLUSH_DELAYED_REFS_NR; - } - -diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c -index eb4d69f53337f..3ec203bbd5593 100644 ---- a/fs/f2fs/checkpoint.c -+++ b/fs/f2fs/checkpoint.c -@@ -70,7 +70,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, - .old_blkaddr = index, - .new_blkaddr = index, - .encrypted_page = NULL, -- .is_por = !is_meta, -+ .is_por = !is_meta ? 1 : 0, - }; - int err; - -@@ -234,8 +234,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, - .op = REQ_OP_READ, - .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD, - .encrypted_page = NULL, -- .in_list = false, -- .is_por = (type == META_POR), -+ .in_list = 0, -+ .is_por = (type == META_POR) ? 1 : 0, - }; - struct blk_plug plug; - int err; -diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c -index 967262c37da52..df6dfd7de6d0d 100644 ---- a/fs/f2fs/compress.c -+++ b/fs/f2fs/compress.c -@@ -1249,10 +1249,11 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, - .page = NULL, - .encrypted_page = NULL, - .compressed_page = NULL, -- .submitted = false, -+ .submitted = 0, - .io_type = io_type, - .io_wbc = wbc, -- .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode), -+ .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ? -+ 1 : 0, - }; - struct dnode_of_data dn; - struct node_info ni; -@@ -1387,8 +1388,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, - add_compr_block_stat(inode, cc->valid_nr_cpages); - - set_inode_flag(cc->inode, FI_APPEND_WRITE); -- if (cc->cluster_idx == 0) -- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); - - f2fs_put_dnode(&dn); - if (quota_inode) -@@ -1436,6 +1435,8 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page) - struct f2fs_sb_info *sbi = bio->bi_private; - struct compress_io_ctx *cic = - (struct compress_io_ctx *)page_private(page); -+ enum count_type type = WB_DATA_TYPE(page, -+ f2fs_is_compressed_page(page)); - int i; - - if (unlikely(bio->bi_status)) -@@ -1443,7 +1444,7 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page) - - f2fs_compress_free_page(page); - -- dec_page_count(sbi, F2FS_WB_DATA); -+ dec_page_count(sbi, type); - - if (atomic_dec_return(&cic->pending_pages)) - return; -@@ -1459,12 +1460,14 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page) - } - - static int f2fs_write_raw_pages(struct compress_ctx *cc, -- int *submitted, -+ int *submitted_p, - struct writeback_control *wbc, - enum iostat_type io_type) - { - struct address_space *mapping = cc->inode->i_mapping; -- int _submitted, compr_blocks, ret, i; -+ struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); -+ int submitted, compr_blocks, i; -+ int ret = 0; - - compr_blocks = f2fs_compressed_blocks(cc); - -@@ -1479,6 +1482,10 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, - if (compr_blocks < 0) - return compr_blocks; - -+ /* overwrite compressed cluster w/ normal cluster */ -+ if (compr_blocks > 0) -+ f2fs_lock_op(sbi); -+ - for (i = 0; i < cc->cluster_size; i++) { - if (!cc->rpages[i]) - continue; -@@ -1503,7 +1510,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, - if (!clear_page_dirty_for_io(cc->rpages[i])) - goto continue_unlock; - -- ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted, -+ ret = f2fs_write_single_data_page(cc->rpages[i], &submitted, - NULL, NULL, wbc, io_type, - compr_blocks, false); - if (ret) { -@@ -1511,26 +1518,29 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, - unlock_page(cc->rpages[i]); - ret = 0; - } else if (ret == -EAGAIN) { -+ ret = 0; - /* - * for quota file, just redirty left pages to - * avoid deadlock caused by cluster update race - * from foreground operation. - */ - if (IS_NOQUOTA(cc->inode)) -- return 0; -- ret = 0; -+ goto out; - f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT); - goto retry_write; - } -- return ret; -+ goto out; - } - -- *submitted += _submitted; -+ *submitted_p += submitted; - } - -- f2fs_balance_fs(F2FS_M_SB(mapping), true); -+out: -+ if (compr_blocks > 0) -+ f2fs_unlock_op(sbi); - -- return 0; -+ f2fs_balance_fs(sbi, true); -+ return ret; - } - - int f2fs_write_multi_pages(struct compress_ctx *cc, -@@ -1833,16 +1843,18 @@ void f2fs_put_page_dic(struct page *page, bool in_task) - * check whether cluster blocks are contiguous, and add extent cache entry - * only if cluster blocks are logically and physically contiguous. - */ --unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) -+unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn, -+ unsigned int ofs_in_node) - { -- bool compressed = f2fs_data_blkaddr(dn) == COMPRESS_ADDR; -+ bool compressed = data_blkaddr(dn->inode, dn->node_page, -+ ofs_in_node) == COMPRESS_ADDR; - int i = compressed ? 1 : 0; - block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page, -- dn->ofs_in_node + i); -+ ofs_in_node + i); - - for (i += 1; i < F2FS_I(dn->inode)->i_cluster_size; i++) { - block_t blkaddr = data_blkaddr(dn->inode, dn->node_page, -- dn->ofs_in_node + i); -+ ofs_in_node + i); - - if (!__is_valid_data_blkaddr(blkaddr)) - break; -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index 8b561af379743..b83b8ac29f430 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -50,7 +50,7 @@ void f2fs_destroy_bioset(void) - bioset_exit(&f2fs_bioset); - } - --static bool __is_cp_guaranteed(struct page *page) -+bool f2fs_is_cp_guaranteed(struct page *page) - { - struct address_space *mapping = page->mapping; - struct inode *inode; -@@ -67,8 +67,6 @@ static bool __is_cp_guaranteed(struct page *page) - S_ISDIR(inode->i_mode)) - return true; - -- if (f2fs_is_compressed_page(page)) -- return false; - if ((S_ISREG(inode->i_mode) && IS_NOQUOTA(inode)) || - page_private_gcing(page)) - return true; -@@ -327,7 +325,7 @@ static void f2fs_write_end_io(struct bio *bio) - - bio_for_each_segment_all(bvec, bio, iter_all) { - struct page *page = bvec->bv_page; -- enum count_type type = WB_DATA_TYPE(page); -+ enum count_type type = WB_DATA_TYPE(page, false); - - if (page_private_dummy(page)) { - clear_page_private_dummy(page); -@@ -733,7 +731,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) - wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE); - - inc_page_count(fio->sbi, is_read_io(fio->op) ? -- __read_io_type(page) : WB_DATA_TYPE(fio->page)); -+ __read_io_type(page) : WB_DATA_TYPE(fio->page, false)); - - __submit_bio(fio->sbi, bio, fio->type); - return 0; -@@ -941,7 +939,7 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio) - if (fio->io_wbc) - wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE); - -- inc_page_count(fio->sbi, WB_DATA_TYPE(page)); -+ inc_page_count(fio->sbi, WB_DATA_TYPE(page, false)); - - *fio->last_block = fio->new_blkaddr; - *fio->bio = bio; -@@ -955,6 +953,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) - enum page_type btype = PAGE_TYPE_OF_BIO(fio->type); - struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp; - struct page *bio_page; -+ enum count_type type; - - f2fs_bug_on(sbi, is_read_io(fio->op)); - -@@ -982,9 +981,10 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) - bio_page = fio->page; - - /* set submitted = true as a return value */ -- fio->submitted = true; -+ fio->submitted = 1; - -- inc_page_count(sbi, WB_DATA_TYPE(bio_page)); -+ type = WB_DATA_TYPE(bio_page, fio->compressed_page); -+ inc_page_count(sbi, type); - - if (io->bio && - (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio, -@@ -997,8 +997,9 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) - if (F2FS_IO_ALIGNED(sbi) && - (fio->type == DATA || fio->type == NODE) && - fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) { -- dec_page_count(sbi, WB_DATA_TYPE(bio_page)); -- fio->retry = true; -+ dec_page_count(sbi, WB_DATA_TYPE(bio_page, -+ fio->compressed_page)); -+ fio->retry = 1; - goto skip; - } - io->bio = __bio_alloc(fio, BIO_MAX_VECS); -@@ -1102,18 +1103,12 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, - return 0; - } - --static void __set_data_blkaddr(struct dnode_of_data *dn) -+static void __set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr) - { -- struct f2fs_node *rn = F2FS_NODE(dn->node_page); -- __le32 *addr_array; -- int base = 0; -- -- if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode)) -- base = get_extra_isize(dn->inode); -+ __le32 *addr = get_dnode_addr(dn->inode, dn->node_page); - -- /* Get physical address of data block */ -- addr_array = blkaddr_in_node(rn); -- addr_array[base + dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr); -+ dn->data_blkaddr = blkaddr; -+ addr[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr); - } - - /* -@@ -1122,18 +1117,17 @@ static void __set_data_blkaddr(struct dnode_of_data *dn) - * ->node_page - * update block addresses in the node page - */ --void f2fs_set_data_blkaddr(struct dnode_of_data *dn) -+void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr) - { - f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true); -- __set_data_blkaddr(dn); -+ __set_data_blkaddr(dn, blkaddr); - if (set_page_dirty(dn->node_page)) - dn->node_changed = true; - } - - void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr) - { -- dn->data_blkaddr = blkaddr; -- f2fs_set_data_blkaddr(dn); -+ f2fs_set_data_blkaddr(dn, blkaddr); - f2fs_update_read_extent_cache(dn); - } - -@@ -1148,7 +1142,8 @@ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count) - - if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) - return -EPERM; -- if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count)))) -+ err = inc_valid_block_count(sbi, dn->inode, &count, true); -+ if (unlikely(err)) - return err; - - trace_f2fs_reserve_new_blocks(dn->inode, dn->nid, -@@ -1160,8 +1155,7 @@ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count) - block_t blkaddr = f2fs_data_blkaddr(dn); - - if (blkaddr == NULL_ADDR) { -- dn->data_blkaddr = NEW_ADDR; -- __set_data_blkaddr(dn); -+ __set_data_blkaddr(dn, NEW_ADDR); - count--; - } - } -@@ -1419,13 +1413,12 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) - return err; - - dn->data_blkaddr = f2fs_data_blkaddr(dn); -- if (dn->data_blkaddr != NULL_ADDR) -- goto alloc; -- -- if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count)))) -- return err; -+ if (dn->data_blkaddr == NULL_ADDR) { -+ err = inc_valid_block_count(sbi, dn->inode, &count, true); -+ if (unlikely(err)) -+ return err; -+ } - --alloc: - set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); - old_blkaddr = dn->data_blkaddr; - f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr, -@@ -2739,8 +2732,6 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) - f2fs_outplace_write_data(&dn, fio); - trace_f2fs_do_write_data_page(page, OPU); - set_inode_flag(inode, FI_APPEND_WRITE); -- if (page->index == 0) -- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); - out_writepage: - f2fs_put_dnode(&dn); - out: -@@ -2776,10 +2767,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, - .old_blkaddr = NULL_ADDR, - .page = page, - .encrypted_page = NULL, -- .submitted = false, -+ .submitted = 0, - .compr_blocks = compr_blocks, -- .need_lock = LOCK_RETRY, -- .post_read = f2fs_post_read_required(inode), -+ .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY, -+ .post_read = f2fs_post_read_required(inode) ? 1 : 0, - .io_type = io_type, - .io_wbc = wbc, - .bio = bio, -@@ -2819,9 +2810,6 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, - - zero_user_segment(page, offset, PAGE_SIZE); - write: -- if (f2fs_is_drop_cache(inode)) -- goto out; -- - /* Dentry/quota blocks are controlled by checkpoint */ - if (S_ISDIR(inode->i_mode) || quota_inode) { - /* -@@ -2858,6 +2846,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, - if (err == -EAGAIN) { - err = f2fs_do_write_data_page(&fio); - if (err == -EAGAIN) { -+ f2fs_bug_on(sbi, compr_blocks); - fio.need_lock = LOCK_REQ; - err = f2fs_do_write_data_page(&fio); - } -@@ -2902,7 +2891,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, - } - - if (submitted) -- *submitted = fio.submitted ? 1 : 0; -+ *submitted = fio.submitted; - - return 0; - -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index e5a9498b89c06..5ae1c4aa3ae92 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -74,6 +74,11 @@ struct f2fs_fault_info { - - extern const char *f2fs_fault_name[FAULT_MAX]; - #define IS_FAULT_SET(fi, type) ((fi)->inject_type & BIT(type)) -+ -+/* maximum retry count for injected failure */ -+#define DEFAULT_FAILURE_RETRY_COUNT 8 -+#else -+#define DEFAULT_FAILURE_RETRY_COUNT 1 - #endif - - /* -@@ -764,8 +769,6 @@ enum { - FI_UPDATE_WRITE, /* inode has in-place-update data */ - FI_NEED_IPU, /* used for ipu per file */ - FI_ATOMIC_FILE, /* indicate atomic file */ -- FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */ -- FI_DROP_CACHE, /* drop dirty page cache */ - FI_DATA_EXIST, /* indicate data exists */ - FI_INLINE_DOTS, /* indicate inline dot dentries */ - FI_SKIP_WRITES, /* should skip data page writeback */ -@@ -1067,7 +1070,8 @@ struct f2fs_sm_info { - * f2fs monitors the number of several block types such as on-writeback, - * dirty dentry blocks, dirty node blocks, and dirty meta blocks. - */ --#define WB_DATA_TYPE(p) (__is_cp_guaranteed(p) ? F2FS_WB_CP_DATA : F2FS_WB_DATA) -+#define WB_DATA_TYPE(p, f) \ -+ (f || f2fs_is_cp_guaranteed(p) ? F2FS_WB_CP_DATA : F2FS_WB_DATA) - enum count_type { - F2FS_DIRTY_DENTS, - F2FS_DIRTY_DATA, -@@ -1183,19 +1187,19 @@ struct f2fs_io_info { - struct page *encrypted_page; /* encrypted page */ - struct page *compressed_page; /* compressed page */ - struct list_head list; /* serialize IOs */ -- bool submitted; /* indicate IO submission */ -- int need_lock; /* indicate we need to lock cp_rwsem */ -- bool in_list; /* indicate fio is in io_list */ -- bool is_por; /* indicate IO is from recovery or not */ -- bool retry; /* need to reallocate block address */ -- int compr_blocks; /* # of compressed block addresses */ -- bool encrypted; /* indicate file is encrypted */ -- bool post_read; /* require post read */ -+ unsigned int compr_blocks; /* # of compressed block addresses */ -+ unsigned int need_lock:8; /* indicate we need to lock cp_rwsem */ -+ unsigned int version:8; /* version of the node */ -+ unsigned int submitted:1; /* indicate IO submission */ -+ unsigned int in_list:1; /* indicate fio is in io_list */ -+ unsigned int is_por:1; /* indicate IO is from recovery or not */ -+ unsigned int retry:1; /* need to reallocate block address */ -+ unsigned int encrypted:1; /* indicate file is encrypted */ -+ unsigned int post_read:1; /* require post read */ - enum iostat_type io_type; /* io type */ - struct writeback_control *io_wbc; /* writeback control */ - struct bio **bio; /* bio for ipu */ - sector_t *last_block; /* last block number in bio */ -- unsigned char version; /* version of the node */ - }; - - struct bio_entry { -@@ -2287,7 +2291,7 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi, - - static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool); - static inline int inc_valid_block_count(struct f2fs_sb_info *sbi, -- struct inode *inode, blkcnt_t *count) -+ struct inode *inode, blkcnt_t *count, bool partial) - { - blkcnt_t diff = 0, release = 0; - block_t avail_user_block_count; -@@ -2328,6 +2332,11 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi, - avail_user_block_count = 0; - } - if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) { -+ if (!partial) { -+ spin_unlock(&sbi->stat_lock); -+ goto enospc; -+ } -+ - diff = sbi->total_valid_block_count - avail_user_block_count; - if (diff > *count) - diff = *count; -@@ -3247,22 +3256,13 @@ static inline bool f2fs_is_cow_file(struct inode *inode) - return is_inode_flag_set(inode, FI_COW_FILE); - } - --static inline bool f2fs_is_first_block_written(struct inode *inode) --{ -- return is_inode_flag_set(inode, FI_FIRST_BLOCK_WRITTEN); --} -- --static inline bool f2fs_is_drop_cache(struct inode *inode) --{ -- return is_inode_flag_set(inode, FI_DROP_CACHE); --} -- -+static inline __le32 *get_dnode_addr(struct inode *inode, -+ struct page *node_page); - static inline void *inline_data_addr(struct inode *inode, struct page *page) - { -- struct f2fs_inode *ri = F2FS_INODE(page); -- int extra_size = get_extra_isize(inode); -+ __le32 *addr = get_dnode_addr(inode, page); - -- return (void *)&(ri->i_addr[extra_size + DEF_INLINE_RESERVED_SIZE]); -+ return (void *)(addr + DEF_INLINE_RESERVED_SIZE); - } - - static inline int f2fs_has_inline_dentry(struct inode *inode) -@@ -3397,6 +3397,17 @@ static inline int get_inline_xattr_addrs(struct inode *inode) - return F2FS_I(inode)->i_inline_xattr_size; - } - -+static inline __le32 *get_dnode_addr(struct inode *inode, -+ struct page *node_page) -+{ -+ int base = 0; -+ -+ if (IS_INODE(node_page) && f2fs_has_extra_attr(inode)) -+ base = get_extra_isize(inode); -+ -+ return blkaddr_in_node(F2FS_NODE(node_page)) + base; -+} -+ - #define f2fs_get_inode_mode(i) \ - ((is_inode_flag_set(i, FI_ACL_MODE)) ? \ - (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) -@@ -3761,6 +3772,7 @@ void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi); - */ - int __init f2fs_init_bioset(void); - void f2fs_destroy_bioset(void); -+bool f2fs_is_cp_guaranteed(struct page *page); - int f2fs_init_bio_entry_cache(void); - void f2fs_destroy_bio_entry_cache(void); - void f2fs_submit_bio(struct f2fs_sb_info *sbi, -@@ -3779,7 +3791,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio); - struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, - block_t blk_addr, sector_t *sector); - int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr); --void f2fs_set_data_blkaddr(struct dnode_of_data *dn); -+void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr); - void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr); - int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count); - int f2fs_reserve_new_block(struct dnode_of_data *dn); -@@ -4246,7 +4258,8 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc); - void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, - bool in_task); - void f2fs_put_page_dic(struct page *page, bool in_task); --unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn); -+unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn, -+ unsigned int ofs_in_node); - int f2fs_init_compress_ctx(struct compress_ctx *cc); - void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); - void f2fs_init_compress_info(struct f2fs_sb_info *sbi); -@@ -4303,7 +4316,8 @@ static inline void f2fs_put_page_dic(struct page *page, bool in_task) - { - WARN_ON_ONCE(1); - } --static inline unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) { return 0; } -+static inline unsigned int f2fs_cluster_blocks_are_contiguous( -+ struct dnode_of_data *dn, unsigned int ofs_in_node) { return 0; } - static inline bool f2fs_sanity_check_cluster(struct dnode_of_data *dn) { return false; } - static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; } - static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { } -@@ -4360,15 +4374,24 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode) - { - struct f2fs_inode_info *fi = F2FS_I(inode); - -- if (!f2fs_compressed_file(inode)) -+ f2fs_down_write(&F2FS_I(inode)->i_sem); -+ -+ if (!f2fs_compressed_file(inode)) { -+ f2fs_up_write(&F2FS_I(inode)->i_sem); - return true; -- if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode)) -+ } -+ if (f2fs_is_mmap_file(inode) || -+ (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))) { -+ f2fs_up_write(&F2FS_I(inode)->i_sem); - return false; -+ } - - fi->i_flags &= ~F2FS_COMPR_FL; - stat_dec_compr_inode(inode); - clear_inode_flag(inode, FI_COMPRESSED_FILE); - f2fs_mark_inode_dirty_sync(inode, true); -+ -+ f2fs_up_write(&F2FS_I(inode)->i_sem); - return true; - } - -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index 46e4960a9dcf7..2fbc8d89c600b 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -560,20 +560,14 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) - void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) - { - struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); -- struct f2fs_node *raw_node; - int nr_free = 0, ofs = dn->ofs_in_node, len = count; - __le32 *addr; -- int base = 0; - bool compressed_cluster = false; - int cluster_index = 0, valid_blocks = 0; - int cluster_size = F2FS_I(dn->inode)->i_cluster_size; - bool released = !atomic_read(&F2FS_I(dn->inode)->i_compr_blocks); - -- if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode)) -- base = get_extra_isize(dn->inode); -- -- raw_node = F2FS_NODE(dn->node_page); -- addr = blkaddr_in_node(raw_node) + base + ofs; -+ addr = get_dnode_addr(dn->inode, dn->node_page) + ofs; - - /* Assumption: truncateion starts with cluster */ - for (; count > 0; count--, addr++, dn->ofs_in_node++, cluster_index++) { -@@ -591,8 +585,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) - if (blkaddr == NULL_ADDR) - continue; - -- dn->data_blkaddr = NULL_ADDR; -- f2fs_set_data_blkaddr(dn); -+ f2fs_set_data_blkaddr(dn, NULL_ADDR); - - if (__is_valid_data_blkaddr(blkaddr)) { - if (!f2fs_is_valid_blkaddr(sbi, blkaddr, -@@ -602,9 +595,6 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) - valid_blocks++; - } - -- if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page)) -- clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN); -- - f2fs_invalidate_blocks(sbi, blkaddr); - - if (!released || blkaddr != COMPRESS_ADDR) -@@ -1497,8 +1487,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, - } - - f2fs_invalidate_blocks(sbi, dn->data_blkaddr); -- dn->data_blkaddr = NEW_ADDR; -- f2fs_set_data_blkaddr(dn); -+ f2fs_set_data_blkaddr(dn, NEW_ADDR); - } - - f2fs_update_read_extent_cache_range(dn, start, 0, index - start); -@@ -3449,8 +3438,7 @@ static int release_compress_blocks(struct dnode_of_data *dn, pgoff_t count) - if (blkaddr != NEW_ADDR) - continue; - -- dn->data_blkaddr = NULL_ADDR; -- f2fs_set_data_blkaddr(dn); -+ f2fs_set_data_blkaddr(dn, NULL_ADDR); - } - - f2fs_i_compr_blocks_update(dn->inode, compr_blocks, false); -@@ -3474,7 +3462,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) - int ret; - int writecount; - -- if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) -+ if (!f2fs_sb_has_compression(sbi)) - return -EOPNOTSUPP; - - if (!f2fs_compressed_file(inode)) -@@ -3487,7 +3475,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) - if (ret) - return ret; - -- f2fs_balance_fs(F2FS_I_SB(inode), true); -+ f2fs_balance_fs(sbi, true); - - inode_lock(inode); - -@@ -3573,10 +3561,10 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) - return ret; - } - --static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) -+static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, -+ unsigned int *reserved_blocks) - { - struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); -- unsigned int reserved_blocks = 0; - int cluster_size = F2FS_I(dn->inode)->i_cluster_size; - block_t blkaddr; - int i; -@@ -3599,41 +3587,53 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) - blkcnt_t reserved; - int ret; - -- for (i = 0; i < cluster_size; i++, dn->ofs_in_node++) { -- blkaddr = f2fs_data_blkaddr(dn); -+ for (i = 0; i < cluster_size; i++) { -+ blkaddr = data_blkaddr(dn->inode, dn->node_page, -+ dn->ofs_in_node + i); - - if (i == 0) { -- if (blkaddr == COMPRESS_ADDR) -- continue; -- dn->ofs_in_node += cluster_size; -- goto next; -+ if (blkaddr != COMPRESS_ADDR) { -+ dn->ofs_in_node += cluster_size; -+ goto next; -+ } -+ continue; - } - -- if (__is_valid_data_blkaddr(blkaddr)) { -+ /* -+ * compressed cluster was not released due to it -+ * fails in release_compress_blocks(), so NEW_ADDR -+ * is a possible case. -+ */ -+ if (blkaddr == NEW_ADDR || -+ __is_valid_data_blkaddr(blkaddr)) { - compr_blocks++; - continue; - } -- -- dn->data_blkaddr = NEW_ADDR; -- f2fs_set_data_blkaddr(dn); - } - - reserved = cluster_size - compr_blocks; -- ret = inc_valid_block_count(sbi, dn->inode, &reserved); -- if (ret) -+ -+ /* for the case all blocks in cluster were reserved */ -+ if (reserved == 1) -+ goto next; -+ -+ ret = inc_valid_block_count(sbi, dn->inode, &reserved, false); -+ if (unlikely(ret)) - return ret; - -- if (reserved != cluster_size - compr_blocks) -- return -ENOSPC; -+ for (i = 0; i < cluster_size; i++, dn->ofs_in_node++) { -+ if (f2fs_data_blkaddr(dn) == NULL_ADDR) -+ f2fs_set_data_blkaddr(dn, NEW_ADDR); -+ } - - f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true); - -- reserved_blocks += reserved; -+ *reserved_blocks += reserved; - next: - count -= cluster_size; - } - -- return reserved_blocks; -+ return 0; - } - - static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) -@@ -3644,7 +3644,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) - unsigned int reserved_blocks = 0; - int ret; - -- if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) -+ if (!f2fs_sb_has_compression(sbi)) - return -EOPNOTSUPP; - - if (!f2fs_compressed_file(inode)) -@@ -3657,10 +3657,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) - if (ret) - return ret; - -- if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) -- goto out; -- -- f2fs_balance_fs(F2FS_I_SB(inode), true); -+ f2fs_balance_fs(sbi, true); - - inode_lock(inode); - -@@ -3669,6 +3666,9 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) - goto unlock_inode; - } - -+ if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) -+ goto unlock_inode; -+ - f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - filemap_invalidate_lock(inode->i_mapping); - -@@ -3694,7 +3694,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) - count = min(end_offset - dn.ofs_in_node, last_idx - page_idx); - count = round_up(count, F2FS_I(inode)->i_cluster_size); - -- ret = reserve_compress_blocks(&dn, count); -+ ret = reserve_compress_blocks(&dn, count, &reserved_blocks); - - f2fs_put_dnode(&dn); - -@@ -3702,23 +3702,21 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) - break; - - page_idx += count; -- reserved_blocks += ret; - } - - filemap_invalidate_unlock(inode->i_mapping); - f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - -- if (ret >= 0) { -+ if (!ret) { - clear_inode_flag(inode, FI_COMPRESS_RELEASED); - inode->i_ctime = current_time(inode); - f2fs_mark_inode_dirty_sync(inode, true); - } - unlock_inode: - inode_unlock(inode); --out: - mnt_drop_write_file(filp); - -- if (ret >= 0) { -+ if (!ret) { - ret = put_user(reserved_blocks, (u64 __user *)arg); - } else if (reserved_blocks && - atomic_read(&F2FS_I(inode)->i_compr_blocks)) { -@@ -3967,16 +3965,20 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg) - sizeof(option))) - return -EFAULT; - -- if (!f2fs_compressed_file(inode) || -- option.log_cluster_size < MIN_COMPRESS_LOG_SIZE || -- option.log_cluster_size > MAX_COMPRESS_LOG_SIZE || -- option.algorithm >= COMPRESS_MAX) -+ if (option.log_cluster_size < MIN_COMPRESS_LOG_SIZE || -+ option.log_cluster_size > MAX_COMPRESS_LOG_SIZE || -+ option.algorithm >= COMPRESS_MAX) - return -EINVAL; - - file_start_write(filp); - inode_lock(inode); - - f2fs_down_write(&F2FS_I(inode)->i_sem); -+ if (!f2fs_compressed_file(inode)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ - if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) { - ret = -EBUSY; - goto out; -@@ -4066,7 +4068,7 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg) - if (!f2fs_compressed_file(inode)) - return -EINVAL; - -- f2fs_balance_fs(F2FS_I_SB(inode), true); -+ f2fs_balance_fs(sbi, true); - - file_start_write(filp); - inode_lock(inode); -@@ -4138,7 +4140,7 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg) - if (!f2fs_compressed_file(inode)) - return -EINVAL; - -- f2fs_balance_fs(F2FS_I_SB(inode), true); -+ f2fs_balance_fs(sbi, true); - - file_start_write(filp); - inode_lock(inode); -diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c -index ec7212f7a9b73..d4662ccb94c8f 100644 ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -1187,8 +1187,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index) - .op = REQ_OP_READ, - .op_flags = 0, - .encrypted_page = NULL, -- .in_list = false, -- .retry = false, -+ .in_list = 0, -+ .retry = 0, - }; - int err; - -@@ -1276,8 +1276,8 @@ static int move_data_block(struct inode *inode, block_t bidx, - .op = REQ_OP_READ, - .op_flags = 0, - .encrypted_page = NULL, -- .in_list = false, -- .retry = false, -+ .in_list = 0, -+ .retry = 0, - }; - struct dnode_of_data dn; - struct f2fs_summary sum; -@@ -1410,8 +1410,6 @@ static int move_data_block(struct inode *inode, block_t bidx, - - f2fs_update_data_blkaddr(&dn, newaddr); - set_inode_flag(inode, FI_APPEND_WRITE); -- if (page->index == 0) -- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); - put_page_out: - f2fs_put_page(fio.encrypted_page, 1); - recover_block: -diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c -index 0010579f17368..869bb6ec107cc 100644 ---- a/fs/f2fs/inode.c -+++ b/fs/f2fs/inode.c -@@ -59,49 +59,31 @@ void f2fs_set_inode_flags(struct inode *inode) - S_ENCRYPTED|S_VERITY|S_CASEFOLD); - } - --static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) -+static void __get_inode_rdev(struct inode *inode, struct page *node_page) - { -- int extra_size = get_extra_isize(inode); -+ __le32 *addr = get_dnode_addr(inode, node_page); - - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || - S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { -- if (ri->i_addr[extra_size]) -- inode->i_rdev = old_decode_dev( -- le32_to_cpu(ri->i_addr[extra_size])); -+ if (addr[0]) -+ inode->i_rdev = old_decode_dev(le32_to_cpu(addr[0])); - else -- inode->i_rdev = new_decode_dev( -- le32_to_cpu(ri->i_addr[extra_size + 1])); -+ inode->i_rdev = new_decode_dev(le32_to_cpu(addr[1])); - } - } - --static int __written_first_block(struct f2fs_sb_info *sbi, -- struct f2fs_inode *ri) -+static void __set_inode_rdev(struct inode *inode, struct page *node_page) - { -- block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]); -- -- if (!__is_valid_data_blkaddr(addr)) -- return 1; -- if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) { -- f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); -- return -EFSCORRUPTED; -- } -- return 0; --} -- --static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) --{ -- int extra_size = get_extra_isize(inode); -+ __le32 *addr = get_dnode_addr(inode, node_page); - - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - if (old_valid_dev(inode->i_rdev)) { -- ri->i_addr[extra_size] = -- cpu_to_le32(old_encode_dev(inode->i_rdev)); -- ri->i_addr[extra_size + 1] = 0; -+ addr[0] = cpu_to_le32(old_encode_dev(inode->i_rdev)); -+ addr[1] = 0; - } else { -- ri->i_addr[extra_size] = 0; -- ri->i_addr[extra_size + 1] = -- cpu_to_le32(new_encode_dev(inode->i_rdev)); -- ri->i_addr[extra_size + 2] = 0; -+ addr[0] = 0; -+ addr[1] = cpu_to_le32(new_encode_dev(inode->i_rdev)); -+ addr[2] = 0; - } - } - } -@@ -336,7 +318,6 @@ static int do_read_inode(struct inode *inode) - struct page *node_page; - struct f2fs_inode *ri; - projid_t i_projid; -- int err; - - /* Check if ino is within scope */ - if (f2fs_check_nid_range(sbi, inode->i_ino)) -@@ -415,17 +396,7 @@ static int do_read_inode(struct inode *inode) - } - - /* get rdev by using inline_info */ -- __get_inode_rdev(inode, ri); -- -- if (S_ISREG(inode->i_mode)) { -- err = __written_first_block(sbi, ri); -- if (err < 0) { -- f2fs_put_page(node_page, 1); -- return err; -- } -- if (!err) -- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); -- } -+ __get_inode_rdev(inode, node_page); - - if (!f2fs_need_inode_block_update(sbi, inode->i_ino)) - fi->last_disk_size = inode->i_size; -@@ -697,7 +668,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page) - } - } - -- __set_inode_rdev(inode, ri); -+ __set_inode_rdev(inode, node_page); - - /* deleted inode */ - if (inode->i_nlink == 0) -diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c -index c6d0e07096326..fcf22a50ff5db 100644 ---- a/fs/f2fs/node.c -+++ b/fs/f2fs/node.c -@@ -850,21 +850,29 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) - - if (is_inode_flag_set(dn->inode, FI_COMPRESSED_FILE) && - f2fs_sb_has_readonly(sbi)) { -- unsigned int c_len = f2fs_cluster_blocks_are_contiguous(dn); -+ unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size; -+ unsigned int ofs_in_node = dn->ofs_in_node; -+ pgoff_t fofs = index; -+ unsigned int c_len; - block_t blkaddr; - -+ /* should align fofs and ofs_in_node to cluster_size */ -+ if (fofs % cluster_size) { -+ fofs = round_down(fofs, cluster_size); -+ ofs_in_node = round_down(ofs_in_node, cluster_size); -+ } -+ -+ c_len = f2fs_cluster_blocks_are_contiguous(dn, ofs_in_node); - if (!c_len) - goto out; - -- blkaddr = f2fs_data_blkaddr(dn); -+ blkaddr = data_blkaddr(dn->inode, dn->node_page, ofs_in_node); - if (blkaddr == COMPRESS_ADDR) - blkaddr = data_blkaddr(dn->inode, dn->node_page, -- dn->ofs_in_node + 1); -+ ofs_in_node + 1); - - f2fs_update_read_extent_tree_range_compressed(dn->inode, -- index, blkaddr, -- F2FS_I(dn->inode)->i_cluster_size, -- c_len); -+ fofs, blkaddr, cluster_size, c_len); - } - out: - return 0; -@@ -1587,7 +1595,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, - .op_flags = wbc_to_write_flags(wbc), - .page = page, - .encrypted_page = NULL, -- .submitted = false, -+ .submitted = 0, - .io_type = io_type, - .io_wbc = wbc, - }; -diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c -index 53a6487f91e44..f5efc37a2b513 100644 ---- a/fs/f2fs/recovery.c -+++ b/fs/f2fs/recovery.c -@@ -582,6 +582,19 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, - return 0; - } - -+static int f2fs_reserve_new_block_retry(struct dnode_of_data *dn) -+{ -+ int i, err = 0; -+ -+ for (i = DEFAULT_FAILURE_RETRY_COUNT; i > 0; i--) { -+ err = f2fs_reserve_new_block(dn); -+ if (!err) -+ break; -+ } -+ -+ return err; -+} -+ - static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, - struct page *page) - { -@@ -683,14 +696,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, - */ - if (dest == NEW_ADDR) { - f2fs_truncate_data_blocks_range(&dn, 1); -- do { -- err = f2fs_reserve_new_block(&dn); -- if (err == -ENOSPC) { -- f2fs_bug_on(sbi, 1); -- break; -- } -- } while (err && -- IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); -+ -+ err = f2fs_reserve_new_block_retry(&dn); - if (err) - goto err; - continue; -@@ -698,16 +705,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, - - /* dest is valid block, try to recover from src to dest */ - if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { -- - if (src == NULL_ADDR) { -- do { -- err = f2fs_reserve_new_block(&dn); -- if (err == -ENOSPC) { -- f2fs_bug_on(sbi, 1); -- break; -- } -- } while (err && -- IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); -+ err = f2fs_reserve_new_block_retry(&dn); - if (err) - goto err; - } -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index 16bf9d5c8d4f9..aa1ba2fdfe00d 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -247,7 +247,7 @@ static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, - } else { - blkcnt_t count = 1; - -- err = inc_valid_block_count(sbi, inode, &count); -+ err = inc_valid_block_count(sbi, inode, &count, true); - if (err) { - f2fs_put_dnode(&dn); - return err; -@@ -3312,10 +3312,10 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, - struct f2fs_bio_info *io; - - if (F2FS_IO_ALIGNED(sbi)) -- fio->retry = false; -+ fio->retry = 0; - - INIT_LIST_HEAD(&fio->list); -- fio->in_list = true; -+ fio->in_list = 1; - io = sbi->write_io[fio->type] + fio->temp; - spin_lock(&io->io_lock); - list_add_tail(&fio->list, &io->io_list); -@@ -3396,7 +3396,7 @@ void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page, - .new_blkaddr = page->index, - .page = page, - .encrypted_page = NULL, -- .in_list = false, -+ .in_list = 0, - }; - - if (unlikely(page->index >= MAIN_BLKADDR(sbi))) -diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h -index f3951e8ad3948..aa9ad85e0901d 100644 ---- a/fs/f2fs/segment.h -+++ b/fs/f2fs/segment.h -@@ -586,23 +586,22 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, - unsigned int node_blocks, unsigned int dent_blocks) - { - -- unsigned int segno, left_blocks; -+ unsigned segno, left_blocks; - int i; - -- /* check current node segment */ -+ /* check current node sections in the worst case. */ - for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) { - segno = CURSEG_I(sbi, i)->segno; -- left_blocks = f2fs_usable_blks_in_seg(sbi, segno) - -- get_seg_entry(sbi, segno)->ckpt_valid_blocks; -- -+ left_blocks = CAP_BLKS_PER_SEC(sbi) - -+ get_ckpt_valid_blocks(sbi, segno, true); - if (node_blocks > left_blocks) - return false; - } - -- /* check current data segment */ -+ /* check current data section for dentry blocks. */ - segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno; -- left_blocks = f2fs_usable_blks_in_seg(sbi, segno) - -- get_seg_entry(sbi, segno)->ckpt_valid_blocks; -+ left_blocks = CAP_BLKS_PER_SEC(sbi) - -+ get_ckpt_valid_blocks(sbi, segno, true); - if (dent_blocks > left_blocks) - return false; - return true; -@@ -651,7 +650,7 @@ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, - - if (free_secs > upper_secs) - return false; -- else if (free_secs <= lower_secs) -+ if (free_secs <= lower_secs) - return true; - return !curseg_space; - } -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 0c0d0671febea..c529ce5d986cc 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -649,7 +649,7 @@ static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) - #ifdef CONFIG_F2FS_FS_ZSTD - static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) - { -- unsigned int level; -+ int level; - int len = 4; - - if (strlen(str) == len) { -@@ -663,9 +663,15 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) - f2fs_info(sbi, "wrong format, e.g. :"); - return -EINVAL; - } -- if (kstrtouint(str + 1, 10, &level)) -+ if (kstrtoint(str + 1, 10, &level)) - return -EINVAL; - -+ /* f2fs does not support negative compress level now */ -+ if (level < 0) { -+ f2fs_info(sbi, "do not support negative compress level: %d", level); -+ return -ERANGE; -+ } -+ - if (!f2fs_is_compress_level_valid(COMPRESS_ZSTD, level)) { - f2fs_info(sbi, "invalid zstd compress level: %d", level); - return -EINVAL; -diff --git a/fs/fcntl.c b/fs/fcntl.c -index 146c9ab0cd4b7..0964e5dbf0cac 100644 ---- a/fs/fcntl.c -+++ b/fs/fcntl.c -@@ -267,7 +267,7 @@ static int f_getowner_uids(struct file *filp, unsigned long arg) - } - #endif - --static bool rw_hint_valid(enum rw_hint hint) -+static bool rw_hint_valid(u64 hint) - { - switch (hint) { - case RWH_WRITE_LIFE_NOT_SET: -@@ -287,19 +287,17 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd, - { - struct inode *inode = file_inode(file); - u64 __user *argp = (u64 __user *)arg; -- enum rw_hint hint; -- u64 h; -+ u64 hint; - - switch (cmd) { - case F_GET_RW_HINT: -- h = inode->i_write_hint; -- if (copy_to_user(argp, &h, sizeof(*argp))) -+ hint = inode->i_write_hint; -+ if (copy_to_user(argp, &hint, sizeof(*argp))) - return -EFAULT; - return 0; - case F_SET_RW_HINT: -- if (copy_from_user(&h, argp, sizeof(h))) -+ if (copy_from_user(&hint, argp, sizeof(hint))) - return -EFAULT; -- hint = (enum rw_hint) h; - if (!rw_hint_valid(hint)) - return -EINVAL; - -diff --git a/fs/fhandle.c b/fs/fhandle.c -index f2bc27d1975e1..a8c25557c8c12 100644 ---- a/fs/fhandle.c -+++ b/fs/fhandle.c -@@ -37,7 +37,7 @@ static long do_sys_name_to_handle(const struct path *path, - if (f_handle.handle_bytes > MAX_HANDLE_SZ) - return -EINVAL; - -- handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes, -+ handle = kzalloc(sizeof(struct file_handle) + f_handle.handle_bytes, - GFP_KERNEL); - if (!handle) - return -ENOMEM; -diff --git a/fs/nfs/export.c b/fs/nfs/export.c -index 01596f2d0a1ed..9fe9586a51b71 100644 ---- a/fs/nfs/export.c -+++ b/fs/nfs/export.c -@@ -156,7 +156,10 @@ const struct export_operations nfs_export_ops = { - .fh_to_dentry = nfs_fh_to_dentry, - .get_parent = nfs_get_parent, - .fetch_iversion = nfs_fetch_iversion, -- .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK| -- EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS| -- EXPORT_OP_NOATOMIC_ATTR, -+ .flags = EXPORT_OP_NOWCC | -+ EXPORT_OP_NOSUBTREECHK | -+ EXPORT_OP_CLOSE_BEFORE_UNLINK | -+ EXPORT_OP_REMOTE_FS | -+ EXPORT_OP_NOATOMIC_ATTR | -+ EXPORT_OP_FLUSH_ON_CLOSE, - }; -diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c -index 81bbafab18a99..4376881be7918 100644 ---- a/fs/nfs/flexfilelayout/flexfilelayout.c -+++ b/fs/nfs/flexfilelayout/flexfilelayout.c -@@ -2016,7 +2016,7 @@ static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg) - for (idx = 0; idx < flseg->mirror_array_cnt; idx++) { - mirror = flseg->mirror_array[idx]; - mirror_ds = mirror->mirror_ds; -- if (!mirror_ds) -+ if (IS_ERR_OR_NULL(mirror_ds)) - continue; - ds = mirror->mirror_ds->ds; - if (!ds) -diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h -index b59876b01a1e3..0282d93c8bccb 100644 ---- a/fs/nfs/nfs42.h -+++ b/fs/nfs/nfs42.h -@@ -55,11 +55,14 @@ int nfs42_proc_removexattr(struct inode *inode, const char *name); - * They would be 7 bytes long in the eventual buffer ("user.x\0"), and - * 8 bytes long XDR-encoded. - * -- * Include the trailing eof word as well. -+ * Include the trailing eof word as well and make the result a multiple -+ * of 4 bytes. - */ - static inline u32 nfs42_listxattr_xdrsize(u32 buflen) - { -- return ((buflen / (XATTR_USER_PREFIX_LEN + 2)) * 8) + 4; -+ u32 size = 8 * buflen / (XATTR_USER_PREFIX_LEN + 2) + 4; -+ -+ return (size + 3) & ~3; - } - #endif /* CONFIG_NFS_V4_2 */ - #endif /* __LINUX_FS_NFS_NFS4_2_H */ -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index ec3f0103e1a7f..7cc74f7451d67 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -10592,29 +10592,33 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = { - static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) - { - ssize_t error, error2, error3; -+ size_t left = size; - -- error = generic_listxattr(dentry, list, size); -+ error = generic_listxattr(dentry, list, left); - if (error < 0) - return error; - if (list) { - list += error; -- size -= error; -+ left -= error; - } - -- error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size); -+ error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, left); - if (error2 < 0) - return error2; - - if (list) { - list += error2; -- size -= error2; -+ left -= error2; - } - -- error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, size); -+ error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); - if (error3 < 0) - return error3; - -- return error + error2 + error3; -+ error += error2 + error3; -+ if (size && error > size) -+ return -ERANGE; -+ return error; - } - - static void nfs4_enable_swap(struct inode *inode) -diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c -index 620329b7e6aeb..0b1c1d2e076c1 100644 ---- a/fs/nfs/nfsroot.c -+++ b/fs/nfs/nfsroot.c -@@ -175,10 +175,10 @@ static int __init root_nfs_cat(char *dest, const char *src, - size_t len = strlen(dest); - - if (len && dest[len - 1] != ',') -- if (strlcat(dest, ",", destlen) > destlen) -+ if (strlcat(dest, ",", destlen) >= destlen) - return -1; - -- if (strlcat(dest, src, destlen) > destlen) -+ if (strlcat(dest, src, destlen) >= destlen) - return -1; - return 0; - } -diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c -index 697acf5c3c681..ee9c923192e08 100644 ---- a/fs/nfsd/filecache.c -+++ b/fs/nfsd/filecache.c -@@ -74,70 +74,9 @@ static struct list_lru nfsd_file_lru; - static unsigned long nfsd_file_flags; - static struct fsnotify_group *nfsd_file_fsnotify_group; - static struct delayed_work nfsd_filecache_laundrette; --static struct rhashtable nfsd_file_rhash_tbl -+static struct rhltable nfsd_file_rhltable - ____cacheline_aligned_in_smp; - --enum nfsd_file_lookup_type { -- NFSD_FILE_KEY_INODE, -- NFSD_FILE_KEY_FULL, --}; -- --struct nfsd_file_lookup_key { -- struct inode *inode; -- struct net *net; -- const struct cred *cred; -- unsigned char need; -- bool gc; -- enum nfsd_file_lookup_type type; --}; -- --/* -- * The returned hash value is based solely on the address of an in-code -- * inode, a pointer to a slab-allocated object. The entropy in such a -- * pointer is concentrated in its middle bits. -- */ --static u32 nfsd_file_inode_hash(const struct inode *inode, u32 seed) --{ -- unsigned long ptr = (unsigned long)inode; -- u32 k; -- -- k = ptr >> L1_CACHE_SHIFT; -- k &= 0x00ffffff; -- return jhash2(&k, 1, seed); --} -- --/** -- * nfsd_file_key_hashfn - Compute the hash value of a lookup key -- * @data: key on which to compute the hash value -- * @len: rhash table's key_len parameter (unused) -- * @seed: rhash table's random seed of the day -- * -- * Return value: -- * Computed 32-bit hash value -- */ --static u32 nfsd_file_key_hashfn(const void *data, u32 len, u32 seed) --{ -- const struct nfsd_file_lookup_key *key = data; -- -- return nfsd_file_inode_hash(key->inode, seed); --} -- --/** -- * nfsd_file_obj_hashfn - Compute the hash value of an nfsd_file -- * @data: object on which to compute the hash value -- * @len: rhash table's key_len parameter (unused) -- * @seed: rhash table's random seed of the day -- * -- * Return value: -- * Computed 32-bit hash value -- */ --static u32 nfsd_file_obj_hashfn(const void *data, u32 len, u32 seed) --{ -- const struct nfsd_file *nf = data; -- -- return nfsd_file_inode_hash(nf->nf_inode, seed); --} -- - static bool - nfsd_match_cred(const struct cred *c1, const struct cred *c2) - { -@@ -158,53 +97,16 @@ nfsd_match_cred(const struct cred *c1, const struct cred *c2) - return true; - } - --/** -- * nfsd_file_obj_cmpfn - Match a cache item against search criteria -- * @arg: search criteria -- * @ptr: cache item to check -- * -- * Return values: -- * %0 - Item matches search criteria -- * %1 - Item does not match search criteria -- */ --static int nfsd_file_obj_cmpfn(struct rhashtable_compare_arg *arg, -- const void *ptr) --{ -- const struct nfsd_file_lookup_key *key = arg->key; -- const struct nfsd_file *nf = ptr; -- -- switch (key->type) { -- case NFSD_FILE_KEY_INODE: -- if (nf->nf_inode != key->inode) -- return 1; -- break; -- case NFSD_FILE_KEY_FULL: -- if (nf->nf_inode != key->inode) -- return 1; -- if (nf->nf_may != key->need) -- return 1; -- if (nf->nf_net != key->net) -- return 1; -- if (!nfsd_match_cred(nf->nf_cred, key->cred)) -- return 1; -- if (!!test_bit(NFSD_FILE_GC, &nf->nf_flags) != key->gc) -- return 1; -- if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) -- return 1; -- break; -- } -- return 0; --} -- - static const struct rhashtable_params nfsd_file_rhash_params = { - .key_len = sizeof_field(struct nfsd_file, nf_inode), - .key_offset = offsetof(struct nfsd_file, nf_inode), -- .head_offset = offsetof(struct nfsd_file, nf_rhash), -- .hashfn = nfsd_file_key_hashfn, -- .obj_hashfn = nfsd_file_obj_hashfn, -- .obj_cmpfn = nfsd_file_obj_cmpfn, -- /* Reduce resizing churn on light workloads */ -- .min_size = 512, /* buckets */ -+ .head_offset = offsetof(struct nfsd_file, nf_rlist), -+ -+ /* -+ * Start with a single page hash table to reduce resizing churn -+ * on light workloads. -+ */ -+ .min_size = 256, - .automatic_shrinking = true, - }; - -@@ -307,27 +209,27 @@ nfsd_file_mark_find_or_create(struct nfsd_file *nf, struct inode *inode) - } - - static struct nfsd_file * --nfsd_file_alloc(struct nfsd_file_lookup_key *key, unsigned int may) -+nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need, -+ bool want_gc) - { - struct nfsd_file *nf; - - nf = kmem_cache_alloc(nfsd_file_slab, GFP_KERNEL); -- if (nf) { -- INIT_LIST_HEAD(&nf->nf_lru); -- nf->nf_birthtime = ktime_get(); -- nf->nf_file = NULL; -- nf->nf_cred = get_current_cred(); -- nf->nf_net = key->net; -- nf->nf_flags = 0; -- __set_bit(NFSD_FILE_HASHED, &nf->nf_flags); -- __set_bit(NFSD_FILE_PENDING, &nf->nf_flags); -- if (key->gc) -- __set_bit(NFSD_FILE_GC, &nf->nf_flags); -- nf->nf_inode = key->inode; -- refcount_set(&nf->nf_ref, 1); -- nf->nf_may = key->need; -- nf->nf_mark = NULL; -- } -+ if (unlikely(!nf)) -+ return NULL; -+ -+ INIT_LIST_HEAD(&nf->nf_lru); -+ nf->nf_birthtime = ktime_get(); -+ nf->nf_file = NULL; -+ nf->nf_cred = get_current_cred(); -+ nf->nf_net = net; -+ nf->nf_flags = want_gc ? -+ BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING) | BIT(NFSD_FILE_GC) : -+ BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING); -+ nf->nf_inode = inode; -+ refcount_set(&nf->nf_ref, 1); -+ nf->nf_may = need; -+ nf->nf_mark = NULL; - return nf; - } - -@@ -352,8 +254,8 @@ static void - nfsd_file_hash_remove(struct nfsd_file *nf) - { - trace_nfsd_file_unhash(nf); -- rhashtable_remove_fast(&nfsd_file_rhash_tbl, &nf->nf_rhash, -- nfsd_file_rhash_params); -+ rhltable_remove(&nfsd_file_rhltable, &nf->nf_rlist, -+ nfsd_file_rhash_params); - } - - static bool -@@ -380,10 +282,8 @@ nfsd_file_free(struct nfsd_file *nf) - if (nf->nf_mark) - nfsd_file_mark_put(nf->nf_mark); - if (nf->nf_file) { -- get_file(nf->nf_file); -- filp_close(nf->nf_file, NULL); - nfsd_file_check_write_error(nf); -- fput(nf->nf_file); -+ filp_close(nf->nf_file, NULL); - } - - /* -@@ -402,13 +302,23 @@ nfsd_file_check_writeback(struct nfsd_file *nf) - struct file *file = nf->nf_file; - struct address_space *mapping; - -- if (!file || !(file->f_mode & FMODE_WRITE)) -+ /* File not open for write? */ -+ if (!(file->f_mode & FMODE_WRITE)) -+ return false; -+ -+ /* -+ * Some filesystems (e.g. NFS) flush all dirty data on close. -+ * On others, there is no need to wait for writeback. -+ */ -+ if (!(file_inode(file)->i_sb->s_export_op->flags & EXPORT_OP_FLUSH_ON_CLOSE)) - return false; -+ - mapping = file->f_mapping; - return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) || - mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK); - } - -+ - static bool nfsd_file_lru_add(struct nfsd_file *nf) - { - set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); -@@ -431,7 +341,7 @@ static bool nfsd_file_lru_remove(struct nfsd_file *nf) - struct nfsd_file * - nfsd_file_get(struct nfsd_file *nf) - { -- if (likely(refcount_inc_not_zero(&nf->nf_ref))) -+ if (nf && refcount_inc_not_zero(&nf->nf_ref)) - return nf; - return NULL; - } -@@ -492,49 +402,26 @@ nfsd_file_dispose_list(struct list_head *dispose) - } - } - --static void --nfsd_file_list_remove_disposal(struct list_head *dst, -- struct nfsd_fcache_disposal *l) --{ -- spin_lock(&l->lock); -- list_splice_init(&l->freeme, dst); -- spin_unlock(&l->lock); --} -- --static void --nfsd_file_list_add_disposal(struct list_head *files, struct net *net) --{ -- struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- struct nfsd_fcache_disposal *l = nn->fcache_disposal; -- -- spin_lock(&l->lock); -- list_splice_tail_init(files, &l->freeme); -- spin_unlock(&l->lock); -- queue_work(nfsd_filecache_wq, &l->work); --} -- --static void --nfsd_file_list_add_pernet(struct list_head *dst, struct list_head *src, -- struct net *net) --{ -- struct nfsd_file *nf, *tmp; -- -- list_for_each_entry_safe(nf, tmp, src, nf_lru) { -- if (nf->nf_net == net) -- list_move_tail(&nf->nf_lru, dst); -- } --} -- -+/** -+ * nfsd_file_dispose_list_delayed - move list of dead files to net's freeme list -+ * @dispose: list of nfsd_files to be disposed -+ * -+ * Transfers each file to the "freeme" list for its nfsd_net, to eventually -+ * be disposed of by the per-net garbage collector. -+ */ - static void - nfsd_file_dispose_list_delayed(struct list_head *dispose) - { -- LIST_HEAD(list); -- struct nfsd_file *nf; -- - while(!list_empty(dispose)) { -- nf = list_first_entry(dispose, struct nfsd_file, nf_lru); -- nfsd_file_list_add_pernet(&list, dispose, nf->nf_net); -- nfsd_file_list_add_disposal(&list, nf->nf_net); -+ struct nfsd_file *nf = list_first_entry(dispose, -+ struct nfsd_file, nf_lru); -+ struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id); -+ struct nfsd_fcache_disposal *l = nn->fcache_disposal; -+ -+ spin_lock(&l->lock); -+ list_move_tail(&nf->nf_lru, &l->freeme); -+ spin_unlock(&l->lock); -+ queue_work(nfsd_filecache_wq, &l->work); - } - } - -@@ -678,8 +565,8 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) - * @inode: inode on which to close out nfsd_files - * @dispose: list on which to gather nfsd_files to close out - * -- * An nfsd_file represents a struct file being held open on behalf of nfsd. An -- * open file however can block other activity (such as leases), or cause -+ * An nfsd_file represents a struct file being held open on behalf of nfsd. -+ * An open file however can block other activity (such as leases), or cause - * undesirable behavior (e.g. spurious silly-renames when reexporting NFS). - * - * This function is intended to find open nfsd_files when this sort of -@@ -692,20 +579,17 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) - static void - nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose) - { -- struct nfsd_file_lookup_key key = { -- .type = NFSD_FILE_KEY_INODE, -- .inode = inode, -- }; -+ struct rhlist_head *tmp, *list; - struct nfsd_file *nf; - - rcu_read_lock(); -- do { -- nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, -- nfsd_file_rhash_params); -- if (!nf) -- break; -+ list = rhltable_lookup(&nfsd_file_rhltable, &inode, -+ nfsd_file_rhash_params); -+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) { -+ if (!test_bit(NFSD_FILE_GC, &nf->nf_flags)) -+ continue; - nfsd_file_cond_queue(nf, dispose); -- } while (1); -+ } - rcu_read_unlock(); - } - -@@ -758,8 +642,8 @@ nfsd_file_close_inode_sync(struct inode *inode) - * nfsd_file_delayed_close - close unused nfsd_files - * @work: dummy - * -- * Walk the LRU list and destroy any entries that have not been used since -- * the last scan. -+ * Scrape the freeme list for this nfsd_net, and then dispose of them -+ * all. - */ - static void - nfsd_file_delayed_close(struct work_struct *work) -@@ -768,7 +652,10 @@ nfsd_file_delayed_close(struct work_struct *work) - struct nfsd_fcache_disposal *l = container_of(work, - struct nfsd_fcache_disposal, work); - -- nfsd_file_list_remove_disposal(&head, l); -+ spin_lock(&l->lock); -+ list_splice_init(&l->freeme, &head); -+ spin_unlock(&l->lock); -+ - nfsd_file_dispose_list(&head); - } - -@@ -829,7 +716,7 @@ nfsd_file_cache_init(void) - if (test_and_set_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1) - return 0; - -- ret = rhashtable_init(&nfsd_file_rhash_tbl, &nfsd_file_rhash_params); -+ ret = rhltable_init(&nfsd_file_rhltable, &nfsd_file_rhash_params); - if (ret) - return ret; - -@@ -897,7 +784,7 @@ nfsd_file_cache_init(void) - nfsd_file_mark_slab = NULL; - destroy_workqueue(nfsd_filecache_wq); - nfsd_filecache_wq = NULL; -- rhashtable_destroy(&nfsd_file_rhash_tbl); -+ rhltable_destroy(&nfsd_file_rhltable); - goto out; - } - -@@ -906,7 +793,8 @@ nfsd_file_cache_init(void) - * @net: net-namespace to shut down the cache (may be NULL) - * - * Walk the nfsd_file cache and close out any that match @net. If @net is NULL, -- * then close out everything. Called when an nfsd instance is being shut down. -+ * then close out everything. Called when an nfsd instance is being shut down, -+ * and when the exports table is flushed. - */ - static void - __nfsd_file_cache_purge(struct net *net) -@@ -915,7 +803,7 @@ __nfsd_file_cache_purge(struct net *net) - struct nfsd_file *nf; - LIST_HEAD(dispose); - -- rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter); -+ rhltable_walk_enter(&nfsd_file_rhltable, &iter); - do { - rhashtable_walk_start(&iter); - -@@ -1021,7 +909,7 @@ nfsd_file_cache_shutdown(void) - nfsd_file_mark_slab = NULL; - destroy_workqueue(nfsd_filecache_wq); - nfsd_filecache_wq = NULL; -- rhashtable_destroy(&nfsd_file_rhash_tbl); -+ rhltable_destroy(&nfsd_file_rhltable); - - for_each_possible_cpu(i) { - per_cpu(nfsd_file_cache_hits, i) = 0; -@@ -1032,6 +920,35 @@ nfsd_file_cache_shutdown(void) - } - } - -+static struct nfsd_file * -+nfsd_file_lookup_locked(const struct net *net, const struct cred *cred, -+ struct inode *inode, unsigned char need, -+ bool want_gc) -+{ -+ struct rhlist_head *tmp, *list; -+ struct nfsd_file *nf; -+ -+ list = rhltable_lookup(&nfsd_file_rhltable, &inode, -+ nfsd_file_rhash_params); -+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) { -+ if (nf->nf_may != need) -+ continue; -+ if (nf->nf_net != net) -+ continue; -+ if (!nfsd_match_cred(nf->nf_cred, cred)) -+ continue; -+ if (test_bit(NFSD_FILE_GC, &nf->nf_flags) != want_gc) -+ continue; -+ if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) -+ continue; -+ -+ if (!nfsd_file_get(nf)) -+ continue; -+ return nf; -+ } -+ return NULL; -+} -+ - /** - * nfsd_file_is_cached - are there any cached open files for this inode? - * @inode: inode to check -@@ -1046,15 +963,20 @@ nfsd_file_cache_shutdown(void) - bool - nfsd_file_is_cached(struct inode *inode) - { -- struct nfsd_file_lookup_key key = { -- .type = NFSD_FILE_KEY_INODE, -- .inode = inode, -- }; -+ struct rhlist_head *tmp, *list; -+ struct nfsd_file *nf; - bool ret = false; - -- if (rhashtable_lookup_fast(&nfsd_file_rhash_tbl, &key, -- nfsd_file_rhash_params) != NULL) -- ret = true; -+ rcu_read_lock(); -+ list = rhltable_lookup(&nfsd_file_rhltable, &inode, -+ nfsd_file_rhash_params); -+ rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) -+ if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) { -+ ret = true; -+ break; -+ } -+ rcu_read_unlock(); -+ - trace_nfsd_file_is_cached(inode, (int)ret); - return ret; - } -@@ -1064,14 +986,12 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, - unsigned int may_flags, struct file *file, - struct nfsd_file **pnf, bool want_gc) - { -- struct nfsd_file_lookup_key key = { -- .type = NFSD_FILE_KEY_FULL, -- .need = may_flags & NFSD_FILE_MAY_MASK, -- .net = SVC_NET(rqstp), -- .gc = want_gc, -- }; -+ unsigned char need = may_flags & NFSD_FILE_MAY_MASK; -+ struct net *net = SVC_NET(rqstp); -+ struct nfsd_file *new, *nf; -+ const struct cred *cred; - bool open_retry = true; -- struct nfsd_file *nf; -+ struct inode *inode; - __be32 status; - int ret; - -@@ -1079,81 +999,88 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, - may_flags|NFSD_MAY_OWNER_OVERRIDE); - if (status != nfs_ok) - return status; -- key.inode = d_inode(fhp->fh_dentry); -- key.cred = get_current_cred(); -+ inode = d_inode(fhp->fh_dentry); -+ cred = get_current_cred(); - - retry: - rcu_read_lock(); -- nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, -- nfsd_file_rhash_params); -- if (nf) -- nf = nfsd_file_get(nf); -+ nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc); - rcu_read_unlock(); - - if (nf) { -+ /* -+ * If the nf is on the LRU then it holds an extra reference -+ * that must be put if it's removed. It had better not be -+ * the last one however, since we should hold another. -+ */ - if (nfsd_file_lru_remove(nf)) - WARN_ON_ONCE(refcount_dec_and_test(&nf->nf_ref)); - goto wait_for_construction; - } - -- nf = nfsd_file_alloc(&key, may_flags); -- if (!nf) { -+ new = nfsd_file_alloc(net, inode, need, want_gc); -+ if (!new) { - status = nfserr_jukebox; -- goto out_status; -+ goto out; - } - -- ret = rhashtable_lookup_insert_key(&nfsd_file_rhash_tbl, -- &key, &nf->nf_rhash, -- nfsd_file_rhash_params); -+ rcu_read_lock(); -+ spin_lock(&inode->i_lock); -+ nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc); -+ if (unlikely(nf)) { -+ spin_unlock(&inode->i_lock); -+ rcu_read_unlock(); -+ nfsd_file_slab_free(&new->nf_rcu); -+ goto wait_for_construction; -+ } -+ nf = new; -+ ret = rhltable_insert(&nfsd_file_rhltable, &nf->nf_rlist, -+ nfsd_file_rhash_params); -+ spin_unlock(&inode->i_lock); -+ rcu_read_unlock(); - if (likely(ret == 0)) - goto open_file; - -- nfsd_file_slab_free(&nf->nf_rcu); -- nf = NULL; - if (ret == -EEXIST) - goto retry; -- trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, ret); -+ trace_nfsd_file_insert_err(rqstp, inode, may_flags, ret); - status = nfserr_jukebox; -- goto out_status; -+ goto construction_err; - - wait_for_construction: - wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE); - - /* Did construction of this file fail? */ - if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { -- trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf); -+ trace_nfsd_file_cons_err(rqstp, inode, may_flags, nf); - if (!open_retry) { - status = nfserr_jukebox; -- goto out; -+ goto construction_err; - } - open_retry = false; -- if (refcount_dec_and_test(&nf->nf_ref)) -- nfsd_file_free(nf); - goto retry; - } -- - this_cpu_inc(nfsd_file_cache_hits); - - status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); -+ if (status != nfs_ok) { -+ nfsd_file_put(nf); -+ nf = NULL; -+ } -+ - out: - if (status == nfs_ok) { - this_cpu_inc(nfsd_file_acquisitions); - nfsd_file_check_write_error(nf); - *pnf = nf; -- } else { -- if (refcount_dec_and_test(&nf->nf_ref)) -- nfsd_file_free(nf); -- nf = NULL; - } -- --out_status: -- put_cred(key.cred); -- trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status); -+ put_cred(cred); -+ trace_nfsd_file_acquire(rqstp, inode, may_flags, nf, status); - return status; - - open_file: - trace_nfsd_file_alloc(nf); -- nf->nf_mark = nfsd_file_mark_find_or_create(nf, key.inode); -+ nf->nf_mark = nfsd_file_mark_find_or_create(nf, inode); - if (nf->nf_mark) { - if (file) { - get_file(file); -@@ -1171,13 +1098,16 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, - * If construction failed, or we raced with a call to unlink() - * then unhash. - */ -- if (status == nfs_ok && key.inode->i_nlink == 0) -- status = nfserr_jukebox; -- if (status != nfs_ok) -+ if (status != nfs_ok || inode->i_nlink == 0) - nfsd_file_unhash(nf); -- clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags); -- smp_mb__after_atomic(); -- wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); -+ clear_and_wake_up_bit(NFSD_FILE_PENDING, &nf->nf_flags); -+ if (status == nfs_ok) -+ goto out; -+ -+construction_err: -+ if (refcount_dec_and_test(&nf->nf_ref)) -+ nfsd_file_free(nf); -+ nf = NULL; - goto out; - } - -@@ -1193,8 +1123,11 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, - * seconds after the final nfsd_file_put() in case the caller - * wants to re-use it. - * -- * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in -- * network byte order is returned. -+ * Return values: -+ * %nfs_ok - @pnf points to an nfsd_file with its reference -+ * count boosted. -+ * -+ * On error, an nfsstat value in network byte order is returned. - */ - __be32 - nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, -@@ -1214,8 +1147,11 @@ nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, - * but not garbage-collected. The object is unhashed after the - * final nfsd_file_put(). - * -- * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in -- * network byte order is returned. -+ * Return values: -+ * %nfs_ok - @pnf points to an nfsd_file with its reference -+ * count boosted. -+ * -+ * On error, an nfsstat value in network byte order is returned. - */ - __be32 - nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, -@@ -1236,8 +1172,11 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, - * and @file is non-NULL, use it to instantiate a new nfsd_file instead of - * opening a new one. - * -- * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in -- * network byte order is returned. -+ * Return values: -+ * %nfs_ok - @pnf points to an nfsd_file with its reference -+ * count boosted. -+ * -+ * On error, an nfsstat value in network byte order is returned. - */ - __be32 - nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp, -@@ -1268,7 +1207,7 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) - lru = list_lru_count(&nfsd_file_lru); - - rcu_read_lock(); -- ht = &nfsd_file_rhash_tbl; -+ ht = &nfsd_file_rhltable.ht; - count = atomic_read(&ht->nelems); - tbl = rht_dereference_rcu(ht->tbl, ht); - buckets = tbl->size; -@@ -1284,7 +1223,7 @@ int nfsd_file_cache_stats_show(struct seq_file *m, void *v) - evictions += per_cpu(nfsd_file_evictions, i); - } - -- seq_printf(m, "total entries: %u\n", count); -+ seq_printf(m, "total inodes: %u\n", count); - seq_printf(m, "hash buckets: %u\n", buckets); - seq_printf(m, "lru entries: %lu\n", lru); - seq_printf(m, "cache hits: %lu\n", hits); -diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h -index 41516a4263ea5..e54165a3224f0 100644 ---- a/fs/nfsd/filecache.h -+++ b/fs/nfsd/filecache.h -@@ -29,9 +29,8 @@ struct nfsd_file_mark { - * never be dereferenced, only used for comparison. - */ - struct nfsd_file { -- struct rhash_head nf_rhash; -- struct list_head nf_lru; -- struct rcu_head nf_rcu; -+ struct rhlist_head nf_rlist; -+ void *nf_inode; - struct file *nf_file; - const struct cred *nf_cred; - struct net *nf_net; -@@ -40,10 +39,12 @@ struct nfsd_file { - #define NFSD_FILE_REFERENCED (2) - #define NFSD_FILE_GC (3) - unsigned long nf_flags; -- struct inode *nf_inode; /* don't deref */ - refcount_t nf_ref; - unsigned char nf_may; -+ - struct nfsd_file_mark *nf_mark; -+ struct list_head nf_lru; -+ struct rcu_head nf_rcu; - ktime_t nf_birthtime; - }; - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index b9d694ec25d19..e4522e86e984e 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -602,9 +602,7 @@ put_nfs4_file(struct nfs4_file *fi) - static struct nfsd_file * - __nfs4_get_fd(struct nfs4_file *f, int oflag) - { -- if (f->fi_fds[oflag]) -- return nfsd_file_get(f->fi_fds[oflag]); -- return NULL; -+ return nfsd_file_get(f->fi_fds[oflag]); - } - - static struct nfsd_file * -diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c -index 597f14a80512f..4ed9fef14adc2 100644 ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -2541,6 +2541,20 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode, - return p; - } - -+static __be32 nfsd4_encode_nfstime4(struct xdr_stream *xdr, -+ struct timespec64 *tv) -+{ -+ __be32 *p; -+ -+ p = xdr_reserve_space(xdr, XDR_UNIT * 3); -+ if (!p) -+ return nfserr_resource; -+ -+ p = xdr_encode_hyper(p, (s64)tv->tv_sec); -+ *p = cpu_to_be32(tv->tv_nsec); -+ return nfs_ok; -+} -+ - /* - * ctime (in NFSv4, time_metadata) is not writeable, and the client - * doesn't really care what resolution could theoretically be stored by -@@ -3346,11 +3360,14 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, - p = xdr_encode_hyper(p, dummy64); - } - if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { -- p = xdr_reserve_space(xdr, 12); -- if (!p) -- goto out_resource; -- p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec); -- *p++ = cpu_to_be32(stat.atime.tv_nsec); -+ status = nfsd4_encode_nfstime4(xdr, &stat.atime); -+ if (status) -+ goto out; -+ } -+ if (bmval1 & FATTR4_WORD1_TIME_CREATE) { -+ status = nfsd4_encode_nfstime4(xdr, &stat.btime); -+ if (status) -+ goto out; - } - if (bmval1 & FATTR4_WORD1_TIME_DELTA) { - p = xdr_reserve_space(xdr, 12); -@@ -3359,25 +3376,14 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, - p = encode_time_delta(p, d_inode(dentry)); - } - if (bmval1 & FATTR4_WORD1_TIME_METADATA) { -- p = xdr_reserve_space(xdr, 12); -- if (!p) -- goto out_resource; -- p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec); -- *p++ = cpu_to_be32(stat.ctime.tv_nsec); -+ status = nfsd4_encode_nfstime4(xdr, &stat.ctime); -+ if (status) -+ goto out; - } - if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { -- p = xdr_reserve_space(xdr, 12); -- if (!p) -- goto out_resource; -- p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec); -- *p++ = cpu_to_be32(stat.mtime.tv_nsec); -- } -- if (bmval1 & FATTR4_WORD1_TIME_CREATE) { -- p = xdr_reserve_space(xdr, 12); -- if (!p) -- goto out_resource; -- p = xdr_encode_hyper(p, (s64)stat.btime.tv_sec); -- *p++ = cpu_to_be32(stat.btime.tv_nsec); -+ status = nfsd4_encode_nfstime4(xdr, &stat.mtime); -+ if (status) -+ goto out; - } - if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { - u64 ino = stat.ino; -diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c -index ffbadb8b3032d..ea3f104371d62 100644 ---- a/fs/pstore/inode.c -+++ b/fs/pstore/inode.c -@@ -182,25 +182,21 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) - { - struct pstore_private *p = d_inode(dentry)->i_private; - struct pstore_record *record = p->record; -- int rc = 0; - - if (!record->psi->erase) - return -EPERM; - - /* Make sure we can't race while removing this file. */ -- mutex_lock(&records_list_lock); -- if (!list_empty(&p->list)) -- list_del_init(&p->list); -- else -- rc = -ENOENT; -- p->dentry = NULL; -- mutex_unlock(&records_list_lock); -- if (rc) -- return rc; -- -- mutex_lock(&record->psi->read_mutex); -- record->psi->erase(record); -- mutex_unlock(&record->psi->read_mutex); -+ scoped_guard(mutex, &records_list_lock) { -+ if (!list_empty(&p->list)) -+ list_del_init(&p->list); -+ else -+ return -ENOENT; -+ p->dentry = NULL; -+ } -+ -+ scoped_guard(mutex, &record->psi->read_mutex) -+ record->psi->erase(record); - - return simple_unlink(dir, dentry); - } -@@ -292,19 +288,16 @@ static struct dentry *psinfo_lock_root(void) - { - struct dentry *root; - -- mutex_lock(&pstore_sb_lock); -+ guard(mutex)(&pstore_sb_lock); - /* - * Having no backend is fine -- no records appear. - * Not being mounted is fine -- nothing to do. - */ -- if (!psinfo || !pstore_sb) { -- mutex_unlock(&pstore_sb_lock); -+ if (!psinfo || !pstore_sb) - return NULL; -- } - - root = pstore_sb->s_root; - inode_lock(d_inode(root)); -- mutex_unlock(&pstore_sb_lock); - - return root; - } -@@ -313,29 +306,25 @@ int pstore_put_backend_records(struct pstore_info *psi) - { - struct pstore_private *pos, *tmp; - struct dentry *root; -- int rc = 0; - - root = psinfo_lock_root(); - if (!root) - return 0; - -- mutex_lock(&records_list_lock); -- list_for_each_entry_safe(pos, tmp, &records_list, list) { -- if (pos->record->psi == psi) { -- list_del_init(&pos->list); -- rc = simple_unlink(d_inode(root), pos->dentry); -- if (WARN_ON(rc)) -- break; -- d_drop(pos->dentry); -- dput(pos->dentry); -- pos->dentry = NULL; -+ scoped_guard(mutex, &records_list_lock) { -+ list_for_each_entry_safe(pos, tmp, &records_list, list) { -+ if (pos->record->psi == psi) { -+ list_del_init(&pos->list); -+ d_invalidate(pos->dentry); -+ simple_unlink(d_inode(root), pos->dentry); -+ pos->dentry = NULL; -+ } - } - } -- mutex_unlock(&records_list_lock); - - inode_unlock(d_inode(root)); - -- return rc; -+ return 0; - } - - /* -@@ -355,20 +344,20 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) - if (WARN_ON(!inode_is_locked(d_inode(root)))) - return -EINVAL; - -- rc = -EEXIST; -+ guard(mutex)(&records_list_lock); -+ - /* Skip records that are already present in the filesystem. */ -- mutex_lock(&records_list_lock); - list_for_each_entry(pos, &records_list, list) { - if (pos->record->type == record->type && - pos->record->id == record->id && - pos->record->psi == record->psi) -- goto fail; -+ return -EEXIST; - } - - rc = -ENOMEM; - inode = pstore_get_inode(root->d_sb); - if (!inode) -- goto fail; -+ return -ENOMEM; - inode->i_mode = S_IFREG | 0444; - inode->i_fop = &pstore_file_operations; - scnprintf(name, sizeof(name), "%s-%s-%llu%s", -@@ -395,7 +384,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) - d_add(dentry, inode); - - list_add(&private->list, &records_list); -- mutex_unlock(&records_list_lock); - - return 0; - -@@ -403,8 +391,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) - free_pstore_private(private); - fail_inode: - iput(inode); --fail: -- mutex_unlock(&records_list_lock); - return rc; - } - -@@ -450,9 +436,8 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent) - if (!sb->s_root) - return -ENOMEM; - -- mutex_lock(&pstore_sb_lock); -- pstore_sb = sb; -- mutex_unlock(&pstore_sb_lock); -+ scoped_guard(mutex, &pstore_sb_lock) -+ pstore_sb = sb; - - pstore_get_records(0); - -@@ -467,17 +452,14 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type, - - static void pstore_kill_sb(struct super_block *sb) - { -- mutex_lock(&pstore_sb_lock); -+ guard(mutex)(&pstore_sb_lock); - WARN_ON(pstore_sb && pstore_sb != sb); - - kill_litter_super(sb); - pstore_sb = NULL; - -- mutex_lock(&records_list_lock); -+ guard(mutex)(&records_list_lock); - INIT_LIST_HEAD(&records_list); -- mutex_unlock(&records_list_lock); -- -- mutex_unlock(&pstore_sb_lock); - } - - static struct file_system_type pstore_fs_type = { -diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c -index b0cf3869d3bf5..b67557647d61f 100644 ---- a/fs/quota/dquot.c -+++ b/fs/quota/dquot.c -@@ -399,15 +399,17 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) - EXPORT_SYMBOL(dquot_mark_dquot_dirty); - - /* Dirtify all the dquots - this can block when journalling */ --static inline int mark_all_dquot_dirty(struct dquot * const *dquot) -+static inline int mark_all_dquot_dirty(struct dquot __rcu * const *dquots) - { - int ret, err, cnt; -+ struct dquot *dquot; - - ret = err = 0; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (dquot[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (dquot) - /* Even in case of error we have to continue */ -- ret = mark_dquot_dirty(dquot[cnt]); -+ ret = mark_dquot_dirty(dquot); - if (!err) - err = ret; - } -@@ -1004,14 +1006,15 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid) - } - EXPORT_SYMBOL(dqget); - --static inline struct dquot **i_dquot(struct inode *inode) -+static inline struct dquot __rcu **i_dquot(struct inode *inode) - { -- return inode->i_sb->s_op->get_dquots(inode); -+ /* Force __rcu for now until filesystems are fixed */ -+ return (struct dquot __rcu **)inode->i_sb->s_op->get_dquots(inode); - } - - static int dqinit_needed(struct inode *inode, int type) - { -- struct dquot * const *dquots; -+ struct dquot __rcu * const *dquots; - int cnt; - - if (IS_NOQUOTA(inode)) -@@ -1084,59 +1087,7 @@ static int add_dquot_ref(struct super_block *sb, int type) - return err; - } - --/* -- * Remove references to dquots from inode and add dquot to list for freeing -- * if we have the last reference to dquot -- */ --static void remove_inode_dquot_ref(struct inode *inode, int type, -- struct list_head *tofree_head) --{ -- struct dquot **dquots = i_dquot(inode); -- struct dquot *dquot = dquots[type]; -- -- if (!dquot) -- return; -- -- dquots[type] = NULL; -- if (list_empty(&dquot->dq_free)) { -- /* -- * The inode still has reference to dquot so it can't be in the -- * free list -- */ -- spin_lock(&dq_list_lock); -- list_add(&dquot->dq_free, tofree_head); -- spin_unlock(&dq_list_lock); -- } else { -- /* -- * Dquot is already in a list to put so we won't drop the last -- * reference here. -- */ -- dqput(dquot); -- } --} -- --/* -- * Free list of dquots -- * Dquots are removed from inodes and no new references can be got so we are -- * the only ones holding reference -- */ --static void put_dquot_list(struct list_head *tofree_head) --{ -- struct list_head *act_head; -- struct dquot *dquot; -- -- act_head = tofree_head->next; -- while (act_head != tofree_head) { -- dquot = list_entry(act_head, struct dquot, dq_free); -- act_head = act_head->next; -- /* Remove dquot from the list so we won't have problems... */ -- list_del_init(&dquot->dq_free); -- dqput(dquot); -- } --} -- --static void remove_dquot_ref(struct super_block *sb, int type, -- struct list_head *tofree_head) -+static void remove_dquot_ref(struct super_block *sb, int type) - { - struct inode *inode; - #ifdef CONFIG_QUOTA_DEBUG -@@ -1153,11 +1104,18 @@ static void remove_dquot_ref(struct super_block *sb, int type, - */ - spin_lock(&dq_data_lock); - if (!IS_NOQUOTA(inode)) { -+ struct dquot __rcu **dquots = i_dquot(inode); -+ struct dquot *dquot = srcu_dereference_check( -+ dquots[type], &dquot_srcu, -+ lockdep_is_held(&dq_data_lock)); -+ - #ifdef CONFIG_QUOTA_DEBUG - if (unlikely(inode_get_rsv_space(inode) > 0)) - reserved = 1; - #endif -- remove_inode_dquot_ref(inode, type, tofree_head); -+ rcu_assign_pointer(dquots[type], NULL); -+ if (dquot) -+ dqput(dquot); - } - spin_unlock(&dq_data_lock); - } -@@ -1174,13 +1132,8 @@ static void remove_dquot_ref(struct super_block *sb, int type, - /* Gather all references from inodes and drop them */ - static void drop_dquot_ref(struct super_block *sb, int type) - { -- LIST_HEAD(tofree_head); -- -- if (sb->dq_op) { -- remove_dquot_ref(sb, type, &tofree_head); -- synchronize_srcu(&dquot_srcu); -- put_dquot_list(&tofree_head); -- } -+ if (sb->dq_op) -+ remove_dquot_ref(sb, type); - } - - static inline -@@ -1513,7 +1466,8 @@ static int inode_quota_active(const struct inode *inode) - static int __dquot_initialize(struct inode *inode, int type) - { - int cnt, init_needed = 0; -- struct dquot **dquots, *got[MAXQUOTAS] = {}; -+ struct dquot __rcu **dquots; -+ struct dquot *got[MAXQUOTAS] = {}; - struct super_block *sb = inode->i_sb; - qsize_t rsv; - int ret = 0; -@@ -1588,7 +1542,7 @@ static int __dquot_initialize(struct inode *inode, int type) - if (!got[cnt]) - continue; - if (!dquots[cnt]) { -- dquots[cnt] = got[cnt]; -+ rcu_assign_pointer(dquots[cnt], got[cnt]); - got[cnt] = NULL; - /* - * Make quota reservation system happy if someone -@@ -1596,12 +1550,16 @@ static int __dquot_initialize(struct inode *inode, int type) - */ - rsv = inode_get_rsv_space(inode); - if (unlikely(rsv)) { -+ struct dquot *dquot = srcu_dereference_check( -+ dquots[cnt], &dquot_srcu, -+ lockdep_is_held(&dq_data_lock)); -+ - spin_lock(&inode->i_lock); - /* Get reservation again under proper lock */ - rsv = __inode_get_rsv_space(inode); -- spin_lock(&dquots[cnt]->dq_dqb_lock); -- dquots[cnt]->dq_dqb.dqb_rsvspace += rsv; -- spin_unlock(&dquots[cnt]->dq_dqb_lock); -+ spin_lock(&dquot->dq_dqb_lock); -+ dquot->dq_dqb.dqb_rsvspace += rsv; -+ spin_unlock(&dquot->dq_dqb_lock); - spin_unlock(&inode->i_lock); - } - } -@@ -1623,7 +1581,7 @@ EXPORT_SYMBOL(dquot_initialize); - - bool dquot_initialize_needed(struct inode *inode) - { -- struct dquot **dquots; -+ struct dquot __rcu **dquots; - int i; - - if (!inode_quota_active(inode)) -@@ -1648,13 +1606,14 @@ EXPORT_SYMBOL(dquot_initialize_needed); - static void __dquot_drop(struct inode *inode) - { - int cnt; -- struct dquot **dquots = i_dquot(inode); -+ struct dquot __rcu **dquots = i_dquot(inode); - struct dquot *put[MAXQUOTAS]; - - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- put[cnt] = dquots[cnt]; -- dquots[cnt] = NULL; -+ put[cnt] = srcu_dereference_check(dquots[cnt], &dquot_srcu, -+ lockdep_is_held(&dq_data_lock)); -+ rcu_assign_pointer(dquots[cnt], NULL); - } - spin_unlock(&dq_data_lock); - dqput_all(put); -@@ -1662,7 +1621,7 @@ static void __dquot_drop(struct inode *inode) - - void dquot_drop(struct inode *inode) - { -- struct dquot * const *dquots; -+ struct dquot __rcu * const *dquots; - int cnt; - - if (IS_NOQUOTA(inode)) -@@ -1735,7 +1694,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) - int cnt, ret = 0, index; - struct dquot_warn warn[MAXQUOTAS]; - int reserve = flags & DQUOT_SPACE_RESERVE; -- struct dquot **dquots; -+ struct dquot __rcu **dquots; -+ struct dquot *dquot; - - if (!inode_quota_active(inode)) { - if (reserve) { -@@ -1755,27 +1715,26 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) - index = srcu_read_lock(&dquot_srcu); - spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; - if (reserve) { -- ret = dquot_add_space(dquots[cnt], 0, number, flags, -- &warn[cnt]); -+ ret = dquot_add_space(dquot, 0, number, flags, &warn[cnt]); - } else { -- ret = dquot_add_space(dquots[cnt], number, 0, flags, -- &warn[cnt]); -+ ret = dquot_add_space(dquot, number, 0, flags, &warn[cnt]); - } - if (ret) { - /* Back out changes we already did */ - for (cnt--; cnt >= 0; cnt--) { -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; -- spin_lock(&dquots[cnt]->dq_dqb_lock); -+ spin_lock(&dquot->dq_dqb_lock); - if (reserve) -- dquot_free_reserved_space(dquots[cnt], -- number); -+ dquot_free_reserved_space(dquot, number); - else -- dquot_decr_space(dquots[cnt], number); -- spin_unlock(&dquots[cnt]->dq_dqb_lock); -+ dquot_decr_space(dquot, number); -+ spin_unlock(&dquot->dq_dqb_lock); - } - spin_unlock(&inode->i_lock); - goto out_flush_warn; -@@ -1805,7 +1764,8 @@ int dquot_alloc_inode(struct inode *inode) - { - int cnt, ret = 0, index; - struct dquot_warn warn[MAXQUOTAS]; -- struct dquot * const *dquots; -+ struct dquot __rcu * const *dquots; -+ struct dquot *dquot; - - if (!inode_quota_active(inode)) - return 0; -@@ -1816,17 +1776,19 @@ int dquot_alloc_inode(struct inode *inode) - index = srcu_read_lock(&dquot_srcu); - spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; -- ret = dquot_add_inodes(dquots[cnt], 1, &warn[cnt]); -+ ret = dquot_add_inodes(dquot, 1, &warn[cnt]); - if (ret) { - for (cnt--; cnt >= 0; cnt--) { -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; - /* Back out changes we already did */ -- spin_lock(&dquots[cnt]->dq_dqb_lock); -- dquot_decr_inodes(dquots[cnt], 1); -- spin_unlock(&dquots[cnt]->dq_dqb_lock); -+ spin_lock(&dquot->dq_dqb_lock); -+ dquot_decr_inodes(dquot, 1); -+ spin_unlock(&dquot->dq_dqb_lock); - } - goto warn_put_all; - } -@@ -1847,7 +1809,8 @@ EXPORT_SYMBOL(dquot_alloc_inode); - */ - int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) - { -- struct dquot **dquots; -+ struct dquot __rcu **dquots; -+ struct dquot *dquot; - int cnt, index; - - if (!inode_quota_active(inode)) { -@@ -1863,9 +1826,8 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) - spin_lock(&inode->i_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (dquots[cnt]) { -- struct dquot *dquot = dquots[cnt]; -- -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (dquot) { - spin_lock(&dquot->dq_dqb_lock); - if (WARN_ON_ONCE(dquot->dq_dqb.dqb_rsvspace < number)) - number = dquot->dq_dqb.dqb_rsvspace; -@@ -1889,7 +1851,8 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); - */ - void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) - { -- struct dquot **dquots; -+ struct dquot __rcu **dquots; -+ struct dquot *dquot; - int cnt, index; - - if (!inode_quota_active(inode)) { -@@ -1905,9 +1868,8 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) - spin_lock(&inode->i_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (dquots[cnt]) { -- struct dquot *dquot = dquots[cnt]; -- -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (dquot) { - spin_lock(&dquot->dq_dqb_lock); - if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number)) - number = dquot->dq_dqb.dqb_curspace; -@@ -1933,7 +1895,8 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) - { - unsigned int cnt; - struct dquot_warn warn[MAXQUOTAS]; -- struct dquot **dquots; -+ struct dquot __rcu **dquots; -+ struct dquot *dquot; - int reserve = flags & DQUOT_SPACE_RESERVE, index; - - if (!inode_quota_active(inode)) { -@@ -1954,17 +1917,18 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) - int wtype; - - warn[cnt].w_type = QUOTA_NL_NOWARN; -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; -- spin_lock(&dquots[cnt]->dq_dqb_lock); -- wtype = info_bdq_free(dquots[cnt], number); -+ spin_lock(&dquot->dq_dqb_lock); -+ wtype = info_bdq_free(dquot, number); - if (wtype != QUOTA_NL_NOWARN) -- prepare_warning(&warn[cnt], dquots[cnt], wtype); -+ prepare_warning(&warn[cnt], dquot, wtype); - if (reserve) -- dquot_free_reserved_space(dquots[cnt], number); -+ dquot_free_reserved_space(dquot, number); - else -- dquot_decr_space(dquots[cnt], number); -- spin_unlock(&dquots[cnt]->dq_dqb_lock); -+ dquot_decr_space(dquot, number); -+ spin_unlock(&dquot->dq_dqb_lock); - } - if (reserve) - *inode_reserved_space(inode) -= number; -@@ -1988,7 +1952,8 @@ void dquot_free_inode(struct inode *inode) - { - unsigned int cnt; - struct dquot_warn warn[MAXQUOTAS]; -- struct dquot * const *dquots; -+ struct dquot __rcu * const *dquots; -+ struct dquot *dquot; - int index; - - if (!inode_quota_active(inode)) -@@ -1999,16 +1964,16 @@ void dquot_free_inode(struct inode *inode) - spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - int wtype; -- - warn[cnt].w_type = QUOTA_NL_NOWARN; -- if (!dquots[cnt]) -+ dquot = srcu_dereference(dquots[cnt], &dquot_srcu); -+ if (!dquot) - continue; -- spin_lock(&dquots[cnt]->dq_dqb_lock); -- wtype = info_idq_free(dquots[cnt], 1); -+ spin_lock(&dquot->dq_dqb_lock); -+ wtype = info_idq_free(dquot, 1); - if (wtype != QUOTA_NL_NOWARN) -- prepare_warning(&warn[cnt], dquots[cnt], wtype); -- dquot_decr_inodes(dquots[cnt], 1); -- spin_unlock(&dquots[cnt]->dq_dqb_lock); -+ prepare_warning(&warn[cnt], dquot, wtype); -+ dquot_decr_inodes(dquot, 1); -+ spin_unlock(&dquot->dq_dqb_lock); - } - spin_unlock(&inode->i_lock); - mark_all_dquot_dirty(dquots); -@@ -2034,8 +1999,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) - qsize_t cur_space; - qsize_t rsv_space = 0; - qsize_t inode_usage = 1; -+ struct dquot __rcu **dquots; - struct dquot *transfer_from[MAXQUOTAS] = {}; -- int cnt, ret = 0; -+ int cnt, index, ret = 0; - char is_valid[MAXQUOTAS] = {}; - struct dquot_warn warn_to[MAXQUOTAS]; - struct dquot_warn warn_from_inodes[MAXQUOTAS]; -@@ -2066,6 +2032,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) - } - cur_space = __inode_get_bytes(inode); - rsv_space = __inode_get_rsv_space(inode); -+ dquots = i_dquot(inode); - /* - * Build the transfer_from list, check limits, and update usage in - * the target structures. -@@ -2080,7 +2047,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) - if (!sb_has_quota_active(inode->i_sb, cnt)) - continue; - is_valid[cnt] = 1; -- transfer_from[cnt] = i_dquot(inode)[cnt]; -+ transfer_from[cnt] = srcu_dereference_check(dquots[cnt], -+ &dquot_srcu, lockdep_is_held(&dq_data_lock)); - ret = dquot_add_inodes(transfer_to[cnt], inode_usage, - &warn_to[cnt]); - if (ret) -@@ -2119,13 +2087,21 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) - rsv_space); - spin_unlock(&transfer_from[cnt]->dq_dqb_lock); - } -- i_dquot(inode)[cnt] = transfer_to[cnt]; -+ rcu_assign_pointer(dquots[cnt], transfer_to[cnt]); - } - spin_unlock(&inode->i_lock); - spin_unlock(&dq_data_lock); - -- mark_all_dquot_dirty(transfer_from); -- mark_all_dquot_dirty(transfer_to); -+ /* -+ * These arrays are local and we hold dquot references so we don't need -+ * the srcu protection but still take dquot_srcu to avoid warning in -+ * mark_all_dquot_dirty(). -+ */ -+ index = srcu_read_lock(&dquot_srcu); -+ mark_all_dquot_dirty((struct dquot __rcu **)transfer_from); -+ mark_all_dquot_dirty((struct dquot __rcu **)transfer_to); -+ srcu_read_unlock(&dquot_srcu, index); -+ - flush_warnings(warn_to); - flush_warnings(warn_from_inodes); - flush_warnings(warn_from_space); -diff --git a/fs/select.c b/fs/select.c -index 0ee55af1a55c2..d4d881d439dcd 100644 ---- a/fs/select.c -+++ b/fs/select.c -@@ -476,7 +476,7 @@ static inline void wait_key_set(poll_table *wait, unsigned long in, - wait->_key |= POLLOUT_SET; - } - --static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) -+static noinline_for_stack int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) - { - ktime_t expire, *to = NULL; - struct poll_wqueues table; -diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h -index 03cb890690e83..a476a406e5997 100644 ---- a/include/drm/drm_fixed.h -+++ b/include/drm/drm_fixed.h -@@ -70,7 +70,6 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) - } - - #define DRM_FIXED_POINT 32 --#define DRM_FIXED_POINT_HALF 16 - #define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT) - #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1) - #define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK) -@@ -89,12 +88,12 @@ static inline int drm_fixp2int(s64 a) - - static inline int drm_fixp2int_round(s64 a) - { -- return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1))); -+ return drm_fixp2int(a + DRM_FIXED_ONE / 2); - } - - static inline int drm_fixp2int_ceil(s64 a) - { -- if (a > 0) -+ if (a >= 0) - return drm_fixp2int(a + DRM_FIXED_ALMOST_ONE); - else - return drm_fixp2int(a - DRM_FIXED_ALMOST_ONE); -diff --git a/include/dt-bindings/clock/r8a779g0-cpg-mssr.h b/include/dt-bindings/clock/r8a779g0-cpg-mssr.h -index 754c54a6eb06a..7850cdc62e285 100644 ---- a/include/dt-bindings/clock/r8a779g0-cpg-mssr.h -+++ b/include/dt-bindings/clock/r8a779g0-cpg-mssr.h -@@ -86,5 +86,6 @@ - #define R8A779G0_CLK_CPEX 74 - #define R8A779G0_CLK_CBFUSA 75 - #define R8A779G0_CLK_R 76 -+#define R8A779G0_CLK_CP 77 - - #endif /* __DT_BINDINGS_CLOCK_R8A779G0_CPG_MSSR_H__ */ -diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h -index 92e7abfe04f92..70b3737052dd2 100644 ---- a/include/linux/dm-io.h -+++ b/include/linux/dm-io.h -@@ -79,7 +79,8 @@ void dm_io_client_destroy(struct dm_io_client *client); - * error occurred doing io to the corresponding region. - */ - int dm_io(struct dm_io_request *io_req, unsigned int num_regions, -- struct dm_io_region *region, unsigned int long *sync_error_bits); -+ struct dm_io_region *region, unsigned int long *sync_error_bits, -+ unsigned short ioprio); - - #endif /* __KERNEL__ */ - #endif /* _LINUX_DM_IO_H */ -diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h -index fe848901fcc3a..218fc5c54e901 100644 ---- a/include/linux/exportfs.h -+++ b/include/linux/exportfs.h -@@ -221,6 +221,7 @@ struct export_operations { - #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply - atomic attribute updates - */ -+#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */ - unsigned long flags; - }; - -diff --git a/include/linux/filter.h b/include/linux/filter.h -index efc42a6e3aed0..face590b24e17 100644 ---- a/include/linux/filter.h -+++ b/include/linux/filter.h -@@ -495,24 +495,27 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) - __BPF_MAP(n, __BPF_DECL_ARGS, __BPF_N, u64, __ur_1, u64, __ur_2, \ - u64, __ur_3, u64, __ur_4, u64, __ur_5) - --#define BPF_CALL_x(x, name, ...) \ -+#define BPF_CALL_x(x, attr, name, ...) \ - static __always_inline \ - u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ - typedef u64 (*btf_##name)(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ -- u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \ -- u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \ -+ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \ -+ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \ - { \ - return ((btf_##name)____##name)(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\ - } \ - static __always_inline \ - u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)) - --#define BPF_CALL_0(name, ...) BPF_CALL_x(0, name, __VA_ARGS__) --#define BPF_CALL_1(name, ...) BPF_CALL_x(1, name, __VA_ARGS__) --#define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__) --#define BPF_CALL_3(name, ...) BPF_CALL_x(3, name, __VA_ARGS__) --#define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__) --#define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__) -+#define __NOATTR -+#define BPF_CALL_0(name, ...) BPF_CALL_x(0, __NOATTR, name, __VA_ARGS__) -+#define BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, name, __VA_ARGS__) -+#define BPF_CALL_2(name, ...) BPF_CALL_x(2, __NOATTR, name, __VA_ARGS__) -+#define BPF_CALL_3(name, ...) BPF_CALL_x(3, __NOATTR, name, __VA_ARGS__) -+#define BPF_CALL_4(name, ...) BPF_CALL_x(4, __NOATTR, name, __VA_ARGS__) -+#define BPF_CALL_5(name, ...) BPF_CALL_x(5, __NOATTR, name, __VA_ARGS__) -+ -+#define NOTRACE_BPF_CALL_1(name, ...) BPF_CALL_x(1, notrace, name, __VA_ARGS__) - - #define bpf_ctx_range(TYPE, MEMBER) \ - offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1 -diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h -index a1484cdb3158e..a8f3058448eaa 100644 ---- a/include/linux/io_uring.h -+++ b/include/linux/io_uring.h -@@ -42,11 +42,11 @@ void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2, - unsigned issue_flags); - void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, - void (*task_work_cb)(struct io_uring_cmd *, unsigned)); --struct sock *io_uring_get_socket(struct file *file); - void __io_uring_cancel(bool cancel_all); - void __io_uring_free(struct task_struct *tsk); - void io_uring_unreg_ringfd(void); - const char *io_uring_get_opcode(u8 opcode); -+bool io_is_uring_fops(struct file *file); - - static inline void io_uring_files_cancel(void) - { -@@ -71,6 +71,10 @@ static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, - { - return -EOPNOTSUPP; - } -+static inline bool io_is_uring_fops(struct file *file) -+{ -+ return false; -+} - static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, - ssize_t ret2, unsigned issue_flags) - { -@@ -79,10 +83,6 @@ static inline void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, - void (*task_work_cb)(struct io_uring_cmd *, unsigned)) - { - } --static inline struct sock *io_uring_get_socket(struct file *file) --{ -- return NULL; --} - static inline void io_uring_task_cancel(void) - { - } -diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h -index f5b687a787a34..37aeea266ebb3 100644 ---- a/include/linux/io_uring_types.h -+++ b/include/linux/io_uring_types.h -@@ -330,9 +330,6 @@ struct io_ring_ctx { - - struct list_head io_buffers_pages; - -- #if defined(CONFIG_UNIX) -- struct socket *ring_sock; -- #endif - /* hashed buffered write serialization */ - struct io_wq_hash *hash_map; - -diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h -index 4657d5c54abef..ca0eee571ad7b 100644 ---- a/include/linux/mlx5/qp.h -+++ b/include/linux/mlx5/qp.h -@@ -269,7 +269,10 @@ struct mlx5_wqe_eth_seg { - union { - struct { - __be16 sz; -- u8 start[2]; -+ union { -+ u8 start[2]; -+ DECLARE_FLEX_ARRAY(u8, data); -+ }; - } inline_hdr; - struct { - __be16 type; -diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h -index 1322652a9d0d9..7dc186ec52a29 100644 ---- a/include/linux/moduleloader.h -+++ b/include/linux/moduleloader.h -@@ -95,6 +95,14 @@ int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *mod); - -+#ifdef CONFIG_MODULES -+void flush_module_init_free_work(void); -+#else -+static inline void flush_module_init_free_work(void) -+{ -+} -+#endif -+ - /* Any cleanup needed when module leaves. */ - void module_arch_cleanup(struct module *mod); - -diff --git a/include/linux/pci.h b/include/linux/pci.h -index eccaf1abea79d..f5d89a4b811f1 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -2355,6 +2355,11 @@ static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev) - return NULL; - } - -+static inline bool pci_dev_is_disconnected(const struct pci_dev *dev) -+{ -+ return dev->error_state == pci_channel_io_perm_failure; -+} -+ - void pci_request_acs(void); - bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags); - bool pci_acs_path_enabled(struct pci_dev *start, -diff --git a/include/linux/poll.h b/include/linux/poll.h -index a9e0e1c2d1f2f..d1ea4f3714a84 100644 ---- a/include/linux/poll.h -+++ b/include/linux/poll.h -@@ -14,11 +14,7 @@ - - /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating - additional memory. */ --#ifdef __clang__ --#define MAX_STACK_ALLOC 768 --#else - #define MAX_STACK_ALLOC 832 --#endif - #define FRONTEND_STACK_ALLOC 256 - #define SELECT_STACK_ALLOC FRONTEND_STACK_ALLOC - #define POLL_STACK_ALLOC FRONTEND_STACK_ALLOC -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index d2507168b9c7b..319698087d66a 100644 ---- a/include/linux/rcupdate.h -+++ b/include/linux/rcupdate.h -@@ -268,6 +268,37 @@ do { \ - cond_resched(); \ - } while (0) - -+/** -+ * rcu_softirq_qs_periodic - Report RCU and RCU-Tasks quiescent states -+ * @old_ts: jiffies at start of processing. -+ * -+ * This helper is for long-running softirq handlers, such as NAPI threads in -+ * networking. The caller should initialize the variable passed in as @old_ts -+ * at the beginning of the softirq handler. When invoked frequently, this macro -+ * will invoke rcu_softirq_qs() every 100 milliseconds thereafter, which will -+ * provide both RCU and RCU-Tasks quiescent states. Note that this macro -+ * modifies its old_ts argument. -+ * -+ * Because regions of code that have disabled softirq act as RCU read-side -+ * critical sections, this macro should be invoked with softirq (and -+ * preemption) enabled. -+ * -+ * The macro is not needed when CONFIG_PREEMPT_RT is defined. RT kernels would -+ * have more chance to invoke schedule() calls and provide necessary quiescent -+ * states. As a contrast, calling cond_resched() only won't achieve the same -+ * effect because cond_resched() does not provide RCU-Tasks quiescent states. -+ */ -+#define rcu_softirq_qs_periodic(old_ts) \ -+do { \ -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT) && \ -+ time_after(jiffies, (old_ts) + HZ / 10)) { \ -+ preempt_disable(); \ -+ rcu_softirq_qs(); \ -+ preempt_enable(); \ -+ (old_ts) = jiffies; \ -+ } \ -+} while (0) -+ - /* - * Infrastructure to implement the synchronize_() primitives in - * TREE_RCU and rcu_barrier_() primitives in TINY_RCU. -diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h -index a674221d151db..c69e09909449f 100644 ---- a/include/net/bluetooth/hci.h -+++ b/include/net/bluetooth/hci.h -@@ -416,7 +416,6 @@ enum { - #define HCI_NCMD_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */ - #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ - #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ --#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */ - #define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */ - #define HCI_LE_AUTOCONN_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */ - -diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h -index 09c978f3d95dc..c50a41f1782a4 100644 ---- a/include/net/bluetooth/hci_core.h -+++ b/include/net/bluetooth/hci_core.h -@@ -81,7 +81,7 @@ struct discovery_state { - u8 last_adv_addr_type; - s8 last_adv_rssi; - u32 last_adv_flags; -- u8 last_adv_data[HCI_MAX_AD_LENGTH]; -+ u8 last_adv_data[HCI_MAX_EXT_AD_LENGTH]; - u8 last_adv_data_len; - bool report_invalid_rssi; - bool result_filtering; -@@ -293,7 +293,7 @@ struct adv_pattern { - __u8 ad_type; - __u8 offset; - __u8 length; -- __u8 value[HCI_MAX_AD_LENGTH]; -+ __u8 value[HCI_MAX_EXT_AD_LENGTH]; - }; - - struct adv_rssi_thresholds { -@@ -549,6 +549,7 @@ struct hci_dev { - __u32 req_status; - __u32 req_result; - struct sk_buff *req_skb; -+ struct sk_buff *req_rsp; - - void *smp_data; - void *smp_bredr_data; -@@ -726,7 +727,7 @@ struct hci_conn { - __u16 le_conn_interval; - __u16 le_conn_latency; - __u16 le_supv_timeout; -- __u8 le_adv_data[HCI_MAX_AD_LENGTH]; -+ __u8 le_adv_data[HCI_MAX_EXT_AD_LENGTH]; - __u8 le_adv_data_len; - __u8 le_per_adv_data[HCI_MAX_PER_AD_LENGTH]; - __u8 le_per_adv_data_len; -@@ -739,6 +740,7 @@ struct hci_conn { - unsigned long flags; - - enum conn_reasons conn_reason; -+ __u8 abort_reason; - - __u32 clock; - __u16 clock_accuracy; -@@ -758,7 +760,6 @@ struct hci_conn { - struct delayed_work auto_accept_work; - struct delayed_work idle_work; - struct delayed_work le_conn_timeout; -- struct work_struct le_scan_cleanup; - - struct device dev; - struct dentry *debugfs; -@@ -1709,6 +1710,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn); - /* Extended advertising support */ - #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV)) - -+/* Maximum advertising length */ -+#define max_adv_len(dev) \ -+ (ext_adv_capable(dev) ? HCI_MAX_EXT_AD_LENGTH : HCI_MAX_AD_LENGTH) -+ - /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 1789: - * - * C24: Mandatory if the LE Controller supports Connection State and either -diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h -index 17f5a4c32f36e..59d15b1a978ab 100644 ---- a/include/net/bluetooth/hci_sync.h -+++ b/include/net/bluetooth/hci_sync.h -@@ -39,8 +39,10 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, - void hci_cmd_sync_init(struct hci_dev *hdev); - void hci_cmd_sync_clear(struct hci_dev *hdev); - void hci_cmd_sync_cancel(struct hci_dev *hdev, int err); --void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err); -+void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err); - -+int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, -+ void *data, hci_cmd_sync_work_destroy_t destroy); - int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, - void *data, hci_cmd_sync_work_destroy_t destroy); - -diff --git a/include/uapi/rdma/irdma-abi.h b/include/uapi/rdma/irdma-abi.h -index a7085e092d348..3a0cde4dcf331 100644 ---- a/include/uapi/rdma/irdma-abi.h -+++ b/include/uapi/rdma/irdma-abi.h -@@ -22,10 +22,15 @@ enum irdma_memreg_type { - IRDMA_MEMREG_TYPE_CQ = 2, - }; - -+enum { -+ IRDMA_ALLOC_UCTX_USE_RAW_ATTR = 1 << 0, -+}; -+ - struct irdma_alloc_ucontext_req { - __u32 rsvd32; - __u8 userspace_ver; - __u8 rsvd8[3]; -+ __aligned_u64 comp_mask; - }; - - struct irdma_alloc_ucontext_resp { -@@ -46,6 +51,7 @@ struct irdma_alloc_ucontext_resp { - __u16 max_hw_sq_chunk; - __u8 hw_rev; - __u8 rsvd2; -+ __aligned_u64 comp_mask; - }; - - struct irdma_alloc_pd_resp { -diff --git a/init/main.c b/init/main.c -index 87a52bdb41d67..ccde19e7275fa 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -89,6 +89,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1473,11 +1474,11 @@ static void mark_readonly(void) - if (rodata_enabled) { - /* - * load_module() results in W+X mappings, which are cleaned -- * up with call_rcu(). Let's make sure that queued work is -+ * up with init_free_wq. Let's make sure that queued work is - * flushed so that we don't hit false positives looking for - * insecure pages which are W+X. - */ -- rcu_barrier(); -+ flush_module_init_free_work(); - mark_rodata_ro(); - rodata_test(); - } else -diff --git a/io_uring/filetable.c b/io_uring/filetable.c -index b80614e7d6051..4660cb89ea9f5 100644 ---- a/io_uring/filetable.c -+++ b/io_uring/filetable.c -@@ -95,12 +95,10 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, - needs_switch = true; - } - -- ret = io_scm_file_account(ctx, file); -- if (!ret) { -- *io_get_tag_slot(ctx->file_data, slot_index) = 0; -- io_fixed_file_set(file_slot, file); -- io_file_bitmap_set(&ctx->file_table, slot_index); -- } -+ *io_get_tag_slot(ctx->file_data, slot_index) = 0; -+ io_fixed_file_set(file_slot, file); -+ io_file_bitmap_set(&ctx->file_table, slot_index); -+ return 0; - err: - if (needs_switch) - io_rsrc_node_switch(ctx, ctx->file_data); -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index 35894955b4549..415248c1f82c6 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -60,7 +60,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -153,19 +152,6 @@ static void __io_submit_flush_completions(struct io_ring_ctx *ctx); - - static struct kmem_cache *req_cachep; - --struct sock *io_uring_get_socket(struct file *file) --{ --#if defined(CONFIG_UNIX) -- if (io_is_uring_fops(file)) { -- struct io_ring_ctx *ctx = file->private_data; -- -- return ctx->ring_sock->sk; -- } --#endif -- return NULL; --} --EXPORT_SYMBOL(io_uring_get_socket); -- - static inline void io_submit_flush_completions(struct io_ring_ctx *ctx) - { - if (!wq_list_empty(&ctx->submit_state.compl_reqs)) -@@ -2641,12 +2627,6 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx) - WARN_ON_ONCE(!list_empty(&ctx->rsrc_ref_list)); - WARN_ON_ONCE(!llist_empty(&ctx->rsrc_put_llist)); - --#if defined(CONFIG_UNIX) -- if (ctx->ring_sock) { -- ctx->ring_sock->file = NULL; /* so that iput() is called */ -- sock_release(ctx->ring_sock); -- } --#endif - WARN_ON_ONCE(!list_empty(&ctx->ltimeout_list)); - - if (ctx->mm_account) { -@@ -3451,32 +3431,12 @@ static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file) - /* - * Allocate an anonymous fd, this is what constitutes the application - * visible backing of an io_uring instance. The application mmaps this -- * fd to gain access to the SQ/CQ ring details. If UNIX sockets are enabled, -- * we have to tie this fd to a socket for file garbage collection purposes. -+ * fd to gain access to the SQ/CQ ring details. - */ - static struct file *io_uring_get_file(struct io_ring_ctx *ctx) - { -- struct file *file; --#if defined(CONFIG_UNIX) -- int ret; -- -- ret = sock_create_kern(&init_net, PF_UNIX, SOCK_RAW, IPPROTO_IP, -- &ctx->ring_sock); -- if (ret) -- return ERR_PTR(ret); --#endif -- -- file = anon_inode_getfile_secure("[io_uring]", &io_uring_fops, ctx, -+ return anon_inode_getfile_secure("[io_uring]", &io_uring_fops, ctx, - O_RDWR | O_CLOEXEC, NULL); --#if defined(CONFIG_UNIX) -- if (IS_ERR(file)) { -- sock_release(ctx->ring_sock); -- ctx->ring_sock = NULL; -- } else { -- ctx->ring_sock->file = file; -- } --#endif -- return file; - } - - static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, -diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h -index 019600570ee49..59e6f755f12c6 100644 ---- a/io_uring/io_uring.h -+++ b/io_uring/io_uring.h -@@ -52,7 +52,6 @@ static inline bool io_req_ffs_set(struct io_kiocb *req) - } - - void __io_req_task_work_add(struct io_kiocb *req, bool allow_local); --bool io_is_uring_fops(struct file *file); - bool io_alloc_async_data(struct io_kiocb *req); - void io_req_task_queue(struct io_kiocb *req); - void io_queue_iowq(struct io_kiocb *req, bool *dont_use); -diff --git a/io_uring/net.c b/io_uring/net.c -index c062ce66af12c..0d4ee3d738fbf 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -183,16 +183,115 @@ static int io_setup_async_msg(struct io_kiocb *req, - return -EAGAIN; - } - -+#ifdef CONFIG_COMPAT -+static int io_compat_msg_copy_hdr(struct io_kiocb *req, -+ struct io_async_msghdr *iomsg, -+ struct compat_msghdr *msg, int ddir) -+{ -+ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); -+ struct compat_iovec __user *uiov; -+ int ret; -+ -+ if (copy_from_user(msg, sr->umsg_compat, sizeof(*msg))) -+ return -EFAULT; -+ -+ uiov = compat_ptr(msg->msg_iov); -+ if (req->flags & REQ_F_BUFFER_SELECT) { -+ compat_ssize_t clen; -+ -+ iomsg->free_iov = NULL; -+ if (msg->msg_iovlen == 0) { -+ sr->len = 0; -+ } else if (msg->msg_iovlen > 1) { -+ return -EINVAL; -+ } else { -+ if (!access_ok(uiov, sizeof(*uiov))) -+ return -EFAULT; -+ if (__get_user(clen, &uiov->iov_len)) -+ return -EFAULT; -+ if (clen < 0) -+ return -EINVAL; -+ sr->len = clen; -+ } -+ -+ return 0; -+ } -+ -+ iomsg->free_iov = iomsg->fast_iov; -+ ret = __import_iovec(ddir, (struct iovec __user *)uiov, msg->msg_iovlen, -+ UIO_FASTIOV, &iomsg->free_iov, -+ &iomsg->msg.msg_iter, true); -+ if (unlikely(ret < 0)) -+ return ret; -+ -+ return 0; -+} -+#endif -+ -+static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg, -+ struct user_msghdr *msg, int ddir) -+{ -+ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); -+ int ret; -+ -+ if (copy_from_user(msg, sr->umsg, sizeof(*sr->umsg))) -+ return -EFAULT; -+ -+ if (req->flags & REQ_F_BUFFER_SELECT) { -+ if (msg->msg_iovlen == 0) { -+ sr->len = iomsg->fast_iov[0].iov_len = 0; -+ iomsg->fast_iov[0].iov_base = NULL; -+ iomsg->free_iov = NULL; -+ } else if (msg->msg_iovlen > 1) { -+ return -EINVAL; -+ } else { -+ if (copy_from_user(iomsg->fast_iov, msg->msg_iov, -+ sizeof(*msg->msg_iov))) -+ return -EFAULT; -+ sr->len = iomsg->fast_iov[0].iov_len; -+ iomsg->free_iov = NULL; -+ } -+ -+ return 0; -+ } -+ -+ iomsg->free_iov = iomsg->fast_iov; -+ ret = __import_iovec(ddir, msg->msg_iov, msg->msg_iovlen, UIO_FASTIOV, -+ &iomsg->free_iov, &iomsg->msg.msg_iter, false); -+ if (unlikely(ret < 0)) -+ return ret; -+ -+ return 0; -+} -+ - static int io_sendmsg_copy_hdr(struct io_kiocb *req, - struct io_async_msghdr *iomsg) - { - struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); -+ struct user_msghdr msg; - int ret; - - iomsg->msg.msg_name = &iomsg->addr; -- iomsg->free_iov = iomsg->fast_iov; -- ret = sendmsg_copy_msghdr(&iomsg->msg, sr->umsg, sr->msg_flags, -- &iomsg->free_iov); -+ iomsg->msg.msg_iter.nr_segs = 0; -+ -+#ifdef CONFIG_COMPAT -+ if (unlikely(req->ctx->compat)) { -+ struct compat_msghdr cmsg; -+ -+ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_SOURCE); -+ if (unlikely(ret)) -+ return ret; -+ -+ return __get_compat_msghdr(&iomsg->msg, &cmsg, NULL); -+ } -+#endif -+ -+ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_SOURCE); -+ if (unlikely(ret)) -+ return ret; -+ -+ ret = __copy_msghdr(&iomsg->msg, &msg, NULL); -+ - /* save msg_control as sys_sendmsg() overwrites it */ - sr->msg_control = iomsg->msg.msg_control_user; - return ret; -@@ -415,142 +514,77 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) - return IOU_OK; - } - --static bool io_recvmsg_multishot_overflow(struct io_async_msghdr *iomsg) -+static int io_recvmsg_mshot_prep(struct io_kiocb *req, -+ struct io_async_msghdr *iomsg, -+ int namelen, size_t controllen) - { -- int hdr; -- -- if (iomsg->namelen < 0) -- return true; -- if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out), -- iomsg->namelen, &hdr)) -- return true; -- if (check_add_overflow(hdr, (int)iomsg->controllen, &hdr)) -- return true; -+ if ((req->flags & (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) == -+ (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) { -+ int hdr; -+ -+ if (unlikely(namelen < 0)) -+ return -EOVERFLOW; -+ if (check_add_overflow(sizeof(struct io_uring_recvmsg_out), -+ namelen, &hdr)) -+ return -EOVERFLOW; -+ if (check_add_overflow(hdr, controllen, &hdr)) -+ return -EOVERFLOW; -+ -+ iomsg->namelen = namelen; -+ iomsg->controllen = controllen; -+ return 0; -+ } - -- return false; -+ return 0; - } - --static int __io_recvmsg_copy_hdr(struct io_kiocb *req, -- struct io_async_msghdr *iomsg) -+static int io_recvmsg_copy_hdr(struct io_kiocb *req, -+ struct io_async_msghdr *iomsg) - { -- struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); - struct user_msghdr msg; - int ret; - -- if (copy_from_user(&msg, sr->umsg, sizeof(*sr->umsg))) -- return -EFAULT; -- -- ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr); -- if (ret) -- return ret; -- -- if (req->flags & REQ_F_BUFFER_SELECT) { -- if (msg.msg_iovlen == 0) { -- sr->len = iomsg->fast_iov[0].iov_len = 0; -- iomsg->fast_iov[0].iov_base = NULL; -- iomsg->free_iov = NULL; -- } else if (msg.msg_iovlen > 1) { -- return -EINVAL; -- } else { -- if (copy_from_user(iomsg->fast_iov, msg.msg_iov, sizeof(*msg.msg_iov))) -- return -EFAULT; -- sr->len = iomsg->fast_iov[0].iov_len; -- iomsg->free_iov = NULL; -- } -- -- if (req->flags & REQ_F_APOLL_MULTISHOT) { -- iomsg->namelen = msg.msg_namelen; -- iomsg->controllen = msg.msg_controllen; -- if (io_recvmsg_multishot_overflow(iomsg)) -- return -EOVERFLOW; -- } -- } else { -- iomsg->free_iov = iomsg->fast_iov; -- ret = __import_iovec(ITER_DEST, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, -- &iomsg->free_iov, &iomsg->msg.msg_iter, -- false); -- if (ret > 0) -- ret = 0; -- } -- -- return ret; --} -+ iomsg->msg.msg_name = &iomsg->addr; -+ iomsg->msg.msg_iter.nr_segs = 0; - - #ifdef CONFIG_COMPAT --static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req, -- struct io_async_msghdr *iomsg) --{ -- struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); -- struct compat_msghdr msg; -- struct compat_iovec __user *uiov; -- int ret; -- -- if (copy_from_user(&msg, sr->umsg_compat, sizeof(msg))) -- return -EFAULT; -- -- ret = __get_compat_msghdr(&iomsg->msg, &msg, &iomsg->uaddr); -- if (ret) -- return ret; -+ if (unlikely(req->ctx->compat)) { -+ struct compat_msghdr cmsg; - -- uiov = compat_ptr(msg.msg_iov); -- if (req->flags & REQ_F_BUFFER_SELECT) { -- compat_ssize_t clen; -- -- iomsg->free_iov = NULL; -- if (msg.msg_iovlen == 0) { -- sr->len = 0; -- } else if (msg.msg_iovlen > 1) { -- return -EINVAL; -- } else { -- if (!access_ok(uiov, sizeof(*uiov))) -- return -EFAULT; -- if (__get_user(clen, &uiov->iov_len)) -- return -EFAULT; -- if (clen < 0) -- return -EINVAL; -- sr->len = clen; -- } -+ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_DEST); -+ if (unlikely(ret)) -+ return ret; - -- if (req->flags & REQ_F_APOLL_MULTISHOT) { -- iomsg->namelen = msg.msg_namelen; -- iomsg->controllen = msg.msg_controllen; -- if (io_recvmsg_multishot_overflow(iomsg)) -- return -EOVERFLOW; -- } -- } else { -- iomsg->free_iov = iomsg->fast_iov; -- ret = __import_iovec(ITER_DEST, (struct iovec __user *)uiov, msg.msg_iovlen, -- UIO_FASTIOV, &iomsg->free_iov, -- &iomsg->msg.msg_iter, true); -- if (ret < 0) -+ ret = __get_compat_msghdr(&iomsg->msg, &cmsg, &iomsg->uaddr); -+ if (unlikely(ret)) - return ret; -- } - -- return 0; --} -+ return io_recvmsg_mshot_prep(req, iomsg, cmsg.msg_namelen, -+ cmsg.msg_controllen); -+ } - #endif - --static int io_recvmsg_copy_hdr(struct io_kiocb *req, -- struct io_async_msghdr *iomsg) --{ -- iomsg->msg.msg_name = &iomsg->addr; -- iomsg->msg.msg_iter.nr_segs = 0; -+ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_DEST); -+ if (unlikely(ret)) -+ return ret; - --#ifdef CONFIG_COMPAT -- if (req->ctx->compat) -- return __io_compat_recvmsg_copy_hdr(req, iomsg); --#endif -+ ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr); -+ if (unlikely(ret)) -+ return ret; - -- return __io_recvmsg_copy_hdr(req, iomsg); -+ return io_recvmsg_mshot_prep(req, iomsg, msg.msg_namelen, -+ msg.msg_controllen); - } - - int io_recvmsg_prep_async(struct io_kiocb *req) - { -+ struct io_async_msghdr *iomsg; - int ret; - - if (!io_msg_alloc_async_prep(req)) - return -ENOMEM; -- ret = io_recvmsg_copy_hdr(req, req->async_data); -+ iomsg = req->async_data; -+ ret = io_recvmsg_copy_hdr(req, iomsg); - if (!ret) - req->flags |= REQ_F_NEED_CLEANUP; - return ret; -diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c -index 7ada0339b3870..ac658cfa89c63 100644 ---- a/io_uring/rsrc.c -+++ b/io_uring/rsrc.c -@@ -494,11 +494,6 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, - err = -EBADF; - break; - } -- err = io_scm_file_account(ctx, file); -- if (err) { -- fput(file); -- break; -- } - *io_get_tag_slot(data, i) = tag; - io_fixed_file_set(file_slot, file); - io_file_bitmap_set(&ctx->file_table, i); -@@ -762,22 +757,12 @@ void __io_sqe_files_unregister(struct io_ring_ctx *ctx) - for (i = 0; i < ctx->nr_user_files; i++) { - struct file *file = io_file_from_index(&ctx->file_table, i); - -- /* skip scm accounted files, they'll be freed by ->ring_sock */ -- if (!file || io_file_need_scm(file)) -+ if (!file) - continue; - io_file_bitmap_clear(&ctx->file_table, i); - fput(file); - } - --#if defined(CONFIG_UNIX) -- if (ctx->ring_sock) { -- struct sock *sock = ctx->ring_sock->sk; -- struct sk_buff *skb; -- -- while ((skb = skb_dequeue(&sock->sk_receive_queue)) != NULL) -- kfree_skb(skb); -- } --#endif - io_free_file_tables(&ctx->file_table); - io_file_table_set_alloc_range(ctx, 0, 0); - io_rsrc_data_free(ctx->file_data); -@@ -805,134 +790,11 @@ int io_sqe_files_unregister(struct io_ring_ctx *ctx) - return ret; - } - --/* -- * Ensure the UNIX gc is aware of our file set, so we are certain that -- * the io_uring can be safely unregistered on process exit, even if we have -- * loops in the file referencing. We account only files that can hold other -- * files because otherwise they can't form a loop and so are not interesting -- * for GC. -- */ --int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file) --{ --#if defined(CONFIG_UNIX) -- struct sock *sk = ctx->ring_sock->sk; -- struct sk_buff_head *head = &sk->sk_receive_queue; -- struct scm_fp_list *fpl; -- struct sk_buff *skb; -- -- if (likely(!io_file_need_scm(file))) -- return 0; -- -- /* -- * See if we can merge this file into an existing skb SCM_RIGHTS -- * file set. If there's no room, fall back to allocating a new skb -- * and filling it in. -- */ -- spin_lock_irq(&head->lock); -- skb = skb_peek(head); -- if (skb && UNIXCB(skb).fp->count < SCM_MAX_FD) -- __skb_unlink(skb, head); -- else -- skb = NULL; -- spin_unlock_irq(&head->lock); -- -- if (!skb) { -- fpl = kzalloc(sizeof(*fpl), GFP_KERNEL); -- if (!fpl) -- return -ENOMEM; -- -- skb = alloc_skb(0, GFP_KERNEL); -- if (!skb) { -- kfree(fpl); -- return -ENOMEM; -- } -- -- fpl->user = get_uid(current_user()); -- fpl->max = SCM_MAX_FD; -- fpl->count = 0; -- -- UNIXCB(skb).fp = fpl; -- skb->sk = sk; -- skb->scm_io_uring = 1; -- skb->destructor = unix_destruct_scm; -- refcount_add(skb->truesize, &sk->sk_wmem_alloc); -- } -- -- fpl = UNIXCB(skb).fp; -- fpl->fp[fpl->count++] = get_file(file); -- unix_inflight(fpl->user, file); -- skb_queue_head(head, skb); -- fput(file); --#endif -- return 0; --} -- - static void io_rsrc_file_put(struct io_ring_ctx *ctx, struct io_rsrc_put *prsrc) - { - struct file *file = prsrc->file; --#if defined(CONFIG_UNIX) -- struct sock *sock = ctx->ring_sock->sk; -- struct sk_buff_head list, *head = &sock->sk_receive_queue; -- struct sk_buff *skb; -- int i; -- -- if (!io_file_need_scm(file)) { -- fput(file); -- return; -- } -- -- __skb_queue_head_init(&list); -- -- /* -- * Find the skb that holds this file in its SCM_RIGHTS. When found, -- * remove this entry and rearrange the file array. -- */ -- skb = skb_dequeue(head); -- while (skb) { -- struct scm_fp_list *fp; - -- fp = UNIXCB(skb).fp; -- for (i = 0; i < fp->count; i++) { -- int left; -- -- if (fp->fp[i] != file) -- continue; -- -- unix_notinflight(fp->user, fp->fp[i]); -- left = fp->count - 1 - i; -- if (left) { -- memmove(&fp->fp[i], &fp->fp[i + 1], -- left * sizeof(struct file *)); -- } -- fp->count--; -- if (!fp->count) { -- kfree_skb(skb); -- skb = NULL; -- } else { -- __skb_queue_tail(&list, skb); -- } -- fput(file); -- file = NULL; -- break; -- } -- -- if (!file) -- break; -- -- __skb_queue_tail(&list, skb); -- -- skb = skb_dequeue(head); -- } -- -- if (skb_peek(&list)) { -- spin_lock_irq(&head->lock); -- while ((skb = __skb_dequeue(&list)) != NULL) -- __skb_queue_tail(head, skb); -- spin_unlock_irq(&head->lock); -- } --#else - fput(file); --#endif - } - - int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, -@@ -986,21 +848,12 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, - goto fail; - - /* -- * Don't allow io_uring instances to be registered. If UNIX -- * isn't enabled, then this causes a reference cycle and this -- * instance can never get freed. If UNIX is enabled we'll -- * handle it just fine, but there's still no point in allowing -- * a ring fd as it doesn't support regular read/write anyway. -+ * Don't allow io_uring instances to be registered. - */ - if (io_is_uring_fops(file)) { - fput(file); - goto fail; - } -- ret = io_scm_file_account(ctx, file); -- if (ret) { -- fput(file); -- goto fail; -- } - file_slot = io_fixed_file_slot(&ctx->file_table, i); - io_fixed_file_set(file_slot, file); - io_file_bitmap_set(&ctx->file_table, i); -diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h -index acaf8dad05401..85f145607c620 100644 ---- a/io_uring/rsrc.h -+++ b/io_uring/rsrc.h -@@ -77,21 +77,6 @@ int io_sqe_files_unregister(struct io_ring_ctx *ctx); - int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, - unsigned nr_args, u64 __user *tags); - --int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file); -- --static inline bool io_file_need_scm(struct file *filp) --{ -- return false; --} -- --static inline int io_scm_file_account(struct io_ring_ctx *ctx, -- struct file *file) --{ -- if (likely(!io_file_need_scm(file))) -- return 0; -- return __io_scm_file_account(ctx, file); --} -- - int io_register_files_update(struct io_ring_ctx *ctx, void __user *arg, - unsigned nr_args); - int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg, -diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c -index 76bf1de261152..44abf88e1bb0d 100644 ---- a/kernel/bpf/core.c -+++ b/kernel/bpf/core.c -@@ -857,7 +857,12 @@ static LIST_HEAD(pack_list); - * CONFIG_MMU=n. Use PAGE_SIZE in these cases. - */ - #ifdef PMD_SIZE --#define BPF_PROG_PACK_SIZE (PMD_SIZE * num_possible_nodes()) -+/* PMD_SIZE is really big for some archs. It doesn't make sense to -+ * reserve too much memory in one allocation. Hardcode BPF_PROG_PACK_SIZE to -+ * 2MiB * num_possible_nodes(). On most architectures PMD_SIZE will be -+ * greater than or equal to 2MB. -+ */ -+#define BPF_PROG_PACK_SIZE (SZ_2M * num_possible_nodes()) - #else - #define BPF_PROG_PACK_SIZE PAGE_SIZE - #endif -diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c -index 0508937048137..806a7c1b364b6 100644 ---- a/kernel/bpf/cpumap.c -+++ b/kernel/bpf/cpumap.c -@@ -306,6 +306,7 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames, - static int cpu_map_kthread_run(void *data) - { - struct bpf_cpu_map_entry *rcpu = data; -+ unsigned long last_qs = jiffies; - - complete(&rcpu->kthread_running); - set_current_state(TASK_INTERRUPTIBLE); -@@ -331,10 +332,12 @@ static int cpu_map_kthread_run(void *data) - if (__ptr_ring_empty(rcpu->queue)) { - schedule(); - sched = 1; -+ last_qs = jiffies; - } else { - __set_current_state(TASK_RUNNING); - } - } else { -+ rcu_softirq_qs_periodic(last_qs); - sched = cond_resched(); - } - -diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c -index f9a87dcc5535b..e051cbb07dac0 100644 ---- a/kernel/bpf/devmap.c -+++ b/kernel/bpf/devmap.c -@@ -131,13 +131,14 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr) - bpf_map_init_from_attr(&dtab->map, attr); - - if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) { -- dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries); -- -- if (!dtab->n_buckets) /* Overflow check */ -+ /* hash table size must be power of 2; roundup_pow_of_two() can -+ * overflow into UB on 32-bit arches, so check that first -+ */ -+ if (dtab->map.max_entries > 1UL << 31) - return -EINVAL; -- } - -- if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) { -+ dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries); -+ - dtab->dev_index_head = dev_map_create_hash(dtab->n_buckets, - dtab->map.numa_node); - if (!dtab->dev_index_head) -diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c -index 88c71de0a0a95..0c74cc9012d5c 100644 ---- a/kernel/bpf/hashtab.c -+++ b/kernel/bpf/hashtab.c -@@ -495,7 +495,13 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) - num_possible_cpus()); - } - -- /* hash table size must be power of 2 */ -+ /* hash table size must be power of 2; roundup_pow_of_two() can overflow -+ * into UB on 32-bit arches, so check that first -+ */ -+ err = -E2BIG; -+ if (htab->map.max_entries > 1UL << 31) -+ goto free_htab; -+ - htab->n_buckets = roundup_pow_of_two(htab->map.max_entries); - - htab->elem_size = sizeof(struct htab_elem) + -@@ -505,10 +511,8 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) - else - htab->elem_size += round_up(htab->map.value_size, 8); - -- err = -E2BIG; -- /* prevent zero size kmalloc and check for u32 overflow */ -- if (htab->n_buckets == 0 || -- htab->n_buckets > U32_MAX / sizeof(struct bucket)) -+ /* check for u32 overflow */ -+ if (htab->n_buckets > U32_MAX / sizeof(struct bucket)) - goto free_htab; - - err = -ENOMEM; -diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c -index 83f8f67e933df..758510b46d87b 100644 ---- a/kernel/bpf/helpers.c -+++ b/kernel/bpf/helpers.c -@@ -328,7 +328,7 @@ static inline void __bpf_spin_lock_irqsave(struct bpf_spin_lock *lock) - __this_cpu_write(irqsave_flags, flags); - } - --notrace BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock) -+NOTRACE_BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock) - { - __bpf_spin_lock_irqsave(lock); - return 0; -@@ -350,7 +350,7 @@ static inline void __bpf_spin_unlock_irqrestore(struct bpf_spin_lock *lock) - local_irq_restore(flags); - } - --notrace BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock) -+NOTRACE_BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock) - { - __bpf_spin_unlock_irqrestore(lock); - return 0; -diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c -index f86db3cf72123..f0fd936cef319 100644 ---- a/kernel/bpf/stackmap.c -+++ b/kernel/bpf/stackmap.c -@@ -94,11 +94,14 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) - } else if (value_size / 8 > sysctl_perf_event_max_stack) - return ERR_PTR(-EINVAL); - -- /* hash table size must be power of 2 */ -- n_buckets = roundup_pow_of_two(attr->max_entries); -- if (!n_buckets) -+ /* hash table size must be power of 2; roundup_pow_of_two() can overflow -+ * into UB on 32-bit arches, so check that first -+ */ -+ if (attr->max_entries > 1UL << 31) - return ERR_PTR(-E2BIG); - -+ n_buckets = roundup_pow_of_two(attr->max_entries); -+ - cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap); - smap = bpf_map_area_alloc(cost, bpf_map_attr_numa_node(attr)); - if (!smap) -diff --git a/kernel/module/main.c b/kernel/module/main.c -index 7a376e26de85b..554aba47ab689 100644 ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -2434,6 +2434,11 @@ static void do_free_init(struct work_struct *w) - } - } - -+void flush_module_init_free_work(void) -+{ -+ flush_work(&init_free_wq); -+} -+ - #undef MODULE_PARAM_PREFIX - #define MODULE_PARAM_PREFIX "module." - /* Default value for module->async_probe_requested */ -@@ -2524,8 +2529,8 @@ static noinline int do_init_module(struct module *mod) - * Note that module_alloc() on most architectures creates W+X page - * mappings which won't be cleaned up until do_free_init() runs. Any - * code such as mark_rodata_ro() which depends on those mappings to -- * be cleaned up needs to sync with the queued work - ie -- * rcu_barrier() -+ * be cleaned up needs to sync with the queued work by invoking -+ * flush_module_init_free_work(). - */ - if (llist_add(&freeinit->node, &init_free_list)) - schedule_work(&init_free_wq); -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index cc53fb77f77cc..981cdb00b8722 100644 ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -1797,10 +1797,23 @@ static bool console_waiter; - */ - static void console_lock_spinning_enable(void) - { -+ /* -+ * Do not use spinning in panic(). The panic CPU wants to keep the lock. -+ * Non-panic CPUs abandon the flush anyway. -+ * -+ * Just keep the lockdep annotation. The panic-CPU should avoid -+ * taking console_owner_lock because it might cause a deadlock. -+ * This looks like the easiest way how to prevent false lockdep -+ * reports without handling races a lockless way. -+ */ -+ if (panic_in_progress()) -+ goto lockdep; -+ - raw_spin_lock(&console_owner_lock); - console_owner = current; - raw_spin_unlock(&console_owner_lock); - -+lockdep: - /* The waiter may spin on us after setting console_owner */ - spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); - } -@@ -1824,6 +1837,22 @@ static int console_lock_spinning_disable_and_check(void) - { - int waiter; - -+ /* -+ * Ignore spinning waiters during panic() because they might get stopped -+ * or blocked at any time, -+ * -+ * It is safe because nobody is allowed to start spinning during panic -+ * in the first place. If there has been a waiter then non panic CPUs -+ * might stay spinning. They would get stopped anyway. The panic context -+ * will never start spinning and an interrupted spin on panic CPU will -+ * never continue. -+ */ -+ if (panic_in_progress()) { -+ /* Keep lockdep happy. */ -+ spin_release(&console_owner_dep_map, _THIS_IP_); -+ return 0; -+ } -+ - raw_spin_lock(&console_owner_lock); - waiter = READ_ONCE(console_waiter); - console_owner = NULL; -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 9d7464a90f85d..61f9503a5fe9c 100644 ---- a/kernel/rcu/tree.c -+++ b/kernel/rcu/tree.c -@@ -4465,13 +4465,16 @@ static void __init rcu_start_exp_gp_kworkers(void) - rcu_exp_gp_kworker = kthread_create_worker(0, gp_kworker_name); - if (IS_ERR_OR_NULL(rcu_exp_gp_kworker)) { - pr_err("Failed to create %s!\n", gp_kworker_name); -+ rcu_exp_gp_kworker = NULL; - return; - } - - rcu_exp_par_gp_kworker = kthread_create_worker(0, par_gp_kworker_name); - if (IS_ERR_OR_NULL(rcu_exp_par_gp_kworker)) { - pr_err("Failed to create %s!\n", par_gp_kworker_name); -+ rcu_exp_par_gp_kworker = NULL; - kthread_destroy_worker(rcu_exp_gp_kworker); -+ rcu_exp_gp_kworker = NULL; - return; - } - -diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h -index 6d2cbed96b462..75e8d9652f7bb 100644 ---- a/kernel/rcu/tree_exp.h -+++ b/kernel/rcu/tree_exp.h -@@ -427,7 +427,12 @@ static void sync_rcu_exp_select_node_cpus(struct kthread_work *wp) - __sync_rcu_exp_select_node_cpus(rewp); - } - --static inline bool rcu_gp_par_worker_started(void) -+static inline bool rcu_exp_worker_started(void) -+{ -+ return !!READ_ONCE(rcu_exp_gp_kworker); -+} -+ -+static inline bool rcu_exp_par_worker_started(void) - { - return !!READ_ONCE(rcu_exp_par_gp_kworker); - } -@@ -477,7 +482,12 @@ static void sync_rcu_exp_select_node_cpus(struct work_struct *wp) - __sync_rcu_exp_select_node_cpus(rewp); - } - --static inline bool rcu_gp_par_worker_started(void) -+static inline bool rcu_exp_worker_started(void) -+{ -+ return !!READ_ONCE(rcu_gp_wq); -+} -+ -+static inline bool rcu_exp_par_worker_started(void) - { - return !!READ_ONCE(rcu_par_gp_wq); - } -@@ -540,7 +550,7 @@ static void sync_rcu_exp_select_cpus(void) - rnp->exp_need_flush = false; - if (!READ_ONCE(rnp->expmask)) - continue; /* Avoid early boot non-existent wq. */ -- if (!rcu_gp_par_worker_started() || -+ if (!rcu_exp_par_worker_started() || - rcu_scheduler_active != RCU_SCHEDULER_RUNNING || - rcu_is_last_leaf_node(rnp)) { - /* No worker started yet or last leaf, do direct call. */ -@@ -910,7 +920,7 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp) - */ - void synchronize_rcu_expedited(void) - { -- bool boottime = (rcu_scheduler_active == RCU_SCHEDULER_INIT); -+ bool use_worker; - unsigned long flags; - struct rcu_exp_work rew; - struct rcu_node *rnp; -@@ -921,6 +931,9 @@ void synchronize_rcu_expedited(void) - lock_is_held(&rcu_sched_lock_map), - "Illegal synchronize_rcu_expedited() in RCU read-side critical section"); - -+ use_worker = (rcu_scheduler_active != RCU_SCHEDULER_INIT) && -+ rcu_exp_worker_started(); -+ - /* Is the state is such that the call is a grace period? */ - if (rcu_blocking_is_gp()) { - // Note well that this code runs with !PREEMPT && !SMP. -@@ -950,7 +963,7 @@ void synchronize_rcu_expedited(void) - return; /* Someone else did our work for us. */ - - /* Ensure that load happens before action based on it. */ -- if (unlikely(boottime)) { -+ if (unlikely(!use_worker)) { - /* Direct call during scheduler init and early_initcalls(). */ - rcu_exp_sel_wait_wake(s); - } else { -@@ -968,7 +981,7 @@ void synchronize_rcu_expedited(void) - /* Let the next expedited grace period start. */ - mutex_unlock(&rcu_state.exp_mutex); - -- if (likely(!boottime)) -+ if (likely(use_worker)) - synchronize_rcu_expedited_destroy_work(&rew); - } - EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 2558ab9033bee..91c101ecfef9f 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6656,7 +6656,7 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu - if (!available_idle_cpu(cpu)) { - idle = false; - if (*idle_cpu == -1) { -- if (sched_idle_cpu(cpu) && cpumask_test_cpu(cpu, p->cpus_ptr)) { -+ if (sched_idle_cpu(cpu) && cpumask_test_cpu(cpu, cpus)) { - *idle_cpu = cpu; - break; - } -@@ -6664,7 +6664,7 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu - } - break; - } -- if (*idle_cpu == -1 && cpumask_test_cpu(cpu, p->cpus_ptr)) -+ if (*idle_cpu == -1 && cpumask_test_cpu(cpu, cpus)) - *idle_cpu = cpu; - } - -@@ -6678,13 +6678,19 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu - /* - * Scan the local SMT mask for idle CPUs. - */ --static int select_idle_smt(struct task_struct *p, int target) -+static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target) - { - int cpu; - - for_each_cpu_and(cpu, cpu_smt_mask(target), p->cpus_ptr) { - if (cpu == target) - continue; -+ /* -+ * Check if the CPU is in the LLC scheduling domain of @target. -+ * Due to isolcpus, there is no guarantee that all the siblings are in the domain. -+ */ -+ if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) -+ continue; - if (available_idle_cpu(cpu) || sched_idle_cpu(cpu)) - return cpu; - } -@@ -6708,7 +6714,7 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma - return __select_idle_cpu(core, p); - } - --static inline int select_idle_smt(struct task_struct *p, int target) -+static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target) - { - return -1; - } -@@ -6970,7 +6976,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) - has_idle_core = test_idle_cores(target); - - if (!has_idle_core && cpus_share_cache(prev, target)) { -- i = select_idle_smt(p, prev); -+ i = select_idle_smt(p, sd, prev); - if ((unsigned int)i < nr_cpumask_bits) - return i; - } -diff --git a/kernel/time/time_test.c b/kernel/time/time_test.c -index 831e8e779acef..f7c3de01197c9 100644 ---- a/kernel/time/time_test.c -+++ b/kernel/time/time_test.c -@@ -73,7 +73,7 @@ static void time64_to_tm_test_date_range(struct kunit *test) - - days = div_s64(secs, 86400); - -- #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %ld", \ -+ #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %lld", \ - year, month, mdday, yday, days - - KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG); -diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 221c8c404973a..b158cbef4d8dc 100644 ---- a/kernel/time/timekeeping.c -+++ b/kernel/time/timekeeping.c -@@ -1180,13 +1180,15 @@ static int adjust_historical_crosststamp(struct system_time_snapshot *history, - } - - /* -- * cycle_between - true if test occurs chronologically between before and after -+ * timestamp_in_interval - true if ts is chronologically in [start, end] -+ * -+ * True if ts occurs chronologically at or after start, and before or at end. - */ --static bool cycle_between(u64 before, u64 test, u64 after) -+static bool timestamp_in_interval(u64 start, u64 end, u64 ts) - { -- if (test > before && test < after) -+ if (ts >= start && ts <= end) - return true; -- if (test < before && before > after) -+ if (start > end && (ts >= start || ts <= end)) - return true; - return false; - } -@@ -1246,7 +1248,7 @@ int get_device_system_crosststamp(int (*get_time_fn) - */ - now = tk_clock_read(&tk->tkr_mono); - interval_start = tk->tkr_mono.cycle_last; -- if (!cycle_between(interval_start, cycles, now)) { -+ if (!timestamp_in_interval(interval_start, now, cycles)) { - clock_was_set_seq = tk->clock_was_set_seq; - cs_was_changed_seq = tk->cs_was_changed_seq; - cycles = interval_start; -@@ -1259,10 +1261,8 @@ int get_device_system_crosststamp(int (*get_time_fn) - tk_core.timekeeper.offs_real); - base_raw = tk->tkr_raw.base; - -- nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, -- system_counterval.cycles); -- nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, -- system_counterval.cycles); -+ nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, cycles); -+ nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, cycles); - } while (read_seqcount_retry(&tk_core.seq, seq)); - - xtstamp->sys_realtime = ktime_add_ns(base_real, nsec_real); -@@ -1277,13 +1277,13 @@ int get_device_system_crosststamp(int (*get_time_fn) - bool discontinuity; - - /* -- * Check that the counter value occurs after the provided -+ * Check that the counter value is not before the provided - * history reference and that the history doesn't cross a - * clocksource change - */ - if (!history_begin || -- !cycle_between(history_begin->cycles, -- system_counterval.cycles, cycles) || -+ !timestamp_in_interval(history_begin->cycles, -+ cycles, system_counterval.cycles) || - history_begin->cs_was_changed_seq != cs_was_changed_seq) - return -EINVAL; - partial_history_cycles = cycles - system_counterval.cycles; -diff --git a/lib/cmdline_kunit.c b/lib/cmdline_kunit.c -index d4572dbc91453..705b82736be08 100644 ---- a/lib/cmdline_kunit.c -+++ b/lib/cmdline_kunit.c -@@ -124,7 +124,7 @@ static void cmdline_do_one_range_test(struct kunit *test, const char *in, - n, e[0], r[0]); - - p = memchr_inv(&r[1], 0, sizeof(r) - sizeof(r[0])); -- KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %u out of bound", n, p - r); -+ KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %td out of bound", n, p - r); - } - - static void cmdline_test_range(struct kunit *test) -diff --git a/lib/memcpy_kunit.c b/lib/memcpy_kunit.c -index 2b5cc70ac53fc..dbedd99aa6163 100644 ---- a/lib/memcpy_kunit.c -+++ b/lib/memcpy_kunit.c -@@ -32,7 +32,7 @@ struct some_bytes { - BUILD_BUG_ON(sizeof(instance.data) != 32); \ - for (size_t i = 0; i < sizeof(instance.data); i++) { \ - KUNIT_ASSERT_EQ_MSG(test, instance.data[i], v, \ -- "line %d: '%s' not initialized to 0x%02x @ %d (saw 0x%02x)\n", \ -+ "line %d: '%s' not initialized to 0x%02x @ %zu (saw 0x%02x)\n", \ - __LINE__, #instance, v, i, instance.data[i]); \ - } \ - } while (0) -@@ -41,7 +41,7 @@ struct some_bytes { - BUILD_BUG_ON(sizeof(one) != sizeof(two)); \ - for (size_t i = 0; i < sizeof(one); i++) { \ - KUNIT_EXPECT_EQ_MSG(test, one.data[i], two.data[i], \ -- "line %d: %s.data[%d] (0x%02x) != %s.data[%d] (0x%02x)\n", \ -+ "line %d: %s.data[%zu] (0x%02x) != %s.data[%zu] (0x%02x)\n", \ - __LINE__, #one, i, one.data[i], #two, i, two.data[i]); \ - } \ - kunit_info(test, "ok: " TEST_OP "() " name "\n"); \ -diff --git a/lib/test_blackhole_dev.c b/lib/test_blackhole_dev.c -index 4c40580a99a36..f247089d63c08 100644 ---- a/lib/test_blackhole_dev.c -+++ b/lib/test_blackhole_dev.c -@@ -29,7 +29,6 @@ static int __init test_blackholedev_init(void) - { - struct ipv6hdr *ip6h; - struct sk_buff *skb; -- struct ethhdr *ethh; - struct udphdr *uh; - int data_len; - int ret; -@@ -61,7 +60,7 @@ static int __init test_blackholedev_init(void) - ip6h->saddr = in6addr_loopback; - ip6h->daddr = in6addr_loopback; - /* Ether */ -- ethh = (struct ethhdr *)skb_push(skb, sizeof(struct ethhdr)); -+ skb_push(skb, sizeof(struct ethhdr)); - skb_set_mac_header(skb, 0); - - skb->protocol = htons(ETH_P_IPV6); -diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c -index f1b7510359e4b..3f9ff02baafe3 100644 ---- a/net/bluetooth/af_bluetooth.c -+++ b/net/bluetooth/af_bluetooth.c -@@ -264,14 +264,11 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - if (flags & MSG_OOB) - return -EOPNOTSUPP; - -- lock_sock(sk); -- - skb = skb_recv_datagram(sk, flags, &err); - if (!skb) { - if (sk->sk_shutdown & RCV_SHUTDOWN) - err = 0; - -- release_sock(sk); - return err; - } - -@@ -297,8 +294,6 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - - skb_free_datagram(sk, skb); - -- release_sock(sk); -- - if (flags & MSG_TRUNC) - copied = skblen; - -@@ -521,10 +516,11 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) - if (sk->sk_state == BT_LISTEN) - return -EINVAL; - -- lock_sock(sk); -+ spin_lock(&sk->sk_receive_queue.lock); - skb = skb_peek(&sk->sk_receive_queue); - amount = skb ? skb->len : 0; -- release_sock(sk); -+ spin_unlock(&sk->sk_receive_queue.lock); -+ - err = put_user(amount, (int __user *)arg); - break; - -diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c -index 8a85f6cdfbc16..1bc51e2b05a34 100644 ---- a/net/bluetooth/eir.c -+++ b/net/bluetooth/eir.c -@@ -13,48 +13,33 @@ - - #define PNP_INFO_SVCLASS_ID 0x1200 - --static u8 eir_append_name(u8 *eir, u16 eir_len, u8 type, u8 *data, u8 data_len) --{ -- u8 name[HCI_MAX_SHORT_NAME_LENGTH + 1]; -- -- /* If data is already NULL terminated just pass it directly */ -- if (data[data_len - 1] == '\0') -- return eir_append_data(eir, eir_len, type, data, data_len); -- -- memcpy(name, data, HCI_MAX_SHORT_NAME_LENGTH); -- name[HCI_MAX_SHORT_NAME_LENGTH] = '\0'; -- -- return eir_append_data(eir, eir_len, type, name, sizeof(name)); --} -- - u8 eir_append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len) - { - size_t short_len; - size_t complete_len; - -- /* no space left for name (+ NULL + type + len) */ -- if ((HCI_MAX_AD_LENGTH - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 3) -+ /* no space left for name (+ type + len) */ -+ if ((max_adv_len(hdev) - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 2) - return ad_len; - - /* use complete name if present and fits */ - complete_len = strnlen(hdev->dev_name, sizeof(hdev->dev_name)); - if (complete_len && complete_len <= HCI_MAX_SHORT_NAME_LENGTH) -- return eir_append_name(ptr, ad_len, EIR_NAME_COMPLETE, -- hdev->dev_name, complete_len + 1); -+ return eir_append_data(ptr, ad_len, EIR_NAME_COMPLETE, -+ hdev->dev_name, complete_len); - - /* use short name if present */ - short_len = strnlen(hdev->short_name, sizeof(hdev->short_name)); - if (short_len) -- return eir_append_name(ptr, ad_len, EIR_NAME_SHORT, -+ return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, - hdev->short_name, -- short_len == HCI_MAX_SHORT_NAME_LENGTH ? -- short_len : short_len + 1); -+ short_len); - - /* use shortened full name if present, we already know that name - * is longer then HCI_MAX_SHORT_NAME_LENGTH - */ - if (complete_len) -- return eir_append_name(ptr, ad_len, EIR_NAME_SHORT, -+ return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, - hdev->dev_name, - HCI_MAX_SHORT_NAME_LENGTH); - -diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c -index 12d36875358b9..bac5a369d2bef 100644 ---- a/net/bluetooth/hci_conn.c -+++ b/net/bluetooth/hci_conn.c -@@ -175,57 +175,6 @@ static void hci_conn_cleanup(struct hci_conn *conn) - hci_dev_put(hdev); - } - --static void le_scan_cleanup(struct work_struct *work) --{ -- struct hci_conn *conn = container_of(work, struct hci_conn, -- le_scan_cleanup); -- struct hci_dev *hdev = conn->hdev; -- struct hci_conn *c = NULL; -- -- BT_DBG("%s hcon %p", hdev->name, conn); -- -- hci_dev_lock(hdev); -- -- /* Check that the hci_conn is still around */ -- rcu_read_lock(); -- list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) { -- if (c == conn) -- break; -- } -- rcu_read_unlock(); -- -- if (c == conn) { -- hci_connect_le_scan_cleanup(conn, 0x00); -- hci_conn_cleanup(conn); -- } -- -- hci_dev_unlock(hdev); -- hci_dev_put(hdev); -- hci_conn_put(conn); --} -- --static void hci_connect_le_scan_remove(struct hci_conn *conn) --{ -- BT_DBG("%s hcon %p", conn->hdev->name, conn); -- -- /* We can't call hci_conn_del/hci_conn_cleanup here since that -- * could deadlock with another hci_conn_del() call that's holding -- * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work). -- * Instead, grab temporary extra references to the hci_dev and -- * hci_conn and perform the necessary cleanup in a separate work -- * callback. -- */ -- -- hci_dev_hold(conn->hdev); -- hci_conn_get(conn); -- -- /* Even though we hold a reference to the hdev, many other -- * things might get cleaned up meanwhile, including the hdev's -- * own workqueue, so we can't use that for scheduling. -- */ -- schedule_work(&conn->le_scan_cleanup); --} -- - static void hci_acl_create_connection(struct hci_conn *conn) - { - struct hci_dev *hdev = conn->hdev; -@@ -672,13 +621,6 @@ static void hci_conn_timeout(struct work_struct *work) - if (refcnt > 0) - return; - -- /* LE connections in scanning state need special handling */ -- if (conn->state == BT_CONNECT && conn->type == LE_LINK && -- test_bit(HCI_CONN_SCANNING, &conn->flags)) { -- hci_connect_le_scan_remove(conn); -- return; -- } -- - hci_abort_conn(conn, hci_proto_disconn_ind(conn)); - } - -@@ -1050,7 +992,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, - INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept); - INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle); - INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout); -- INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup); - - atomic_set(&conn->refcnt, 0); - -@@ -2837,81 +2778,46 @@ u32 hci_conn_get_phy(struct hci_conn *conn) - return phys; - } - --int hci_abort_conn(struct hci_conn *conn, u8 reason) -+static int abort_conn_sync(struct hci_dev *hdev, void *data) - { -- int r = 0; -+ struct hci_conn *conn; -+ u16 handle = PTR_ERR(data); - -- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) -+ conn = hci_conn_hash_lookup_handle(hdev, handle); -+ if (!conn) - return 0; - -- switch (conn->state) { -- case BT_CONNECTED: -- case BT_CONFIG: -- if (conn->type == AMP_LINK) { -- struct hci_cp_disconn_phy_link cp; -+ return hci_abort_conn_sync(hdev, conn, conn->abort_reason); -+} - -- cp.phy_handle = HCI_PHY_HANDLE(conn->handle); -- cp.reason = reason; -- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK, -- sizeof(cp), &cp); -- } else { -- struct hci_cp_disconnect dc; -+int hci_abort_conn(struct hci_conn *conn, u8 reason) -+{ -+ struct hci_dev *hdev = conn->hdev; - -- dc.handle = cpu_to_le16(conn->handle); -- dc.reason = reason; -- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, -- sizeof(dc), &dc); -- } -+ /* If abort_reason has already been set it means the connection is -+ * already being aborted so don't attempt to overwrite it. -+ */ -+ if (conn->abort_reason) -+ return 0; - -- conn->state = BT_DISCONN; -+ bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason); - -- break; -- case BT_CONNECT: -- if (conn->type == LE_LINK) { -- if (test_bit(HCI_CONN_SCANNING, &conn->flags)) -- break; -- r = hci_send_cmd(conn->hdev, -- HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); -- } else if (conn->type == ACL_LINK) { -- if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) -- break; -- r = hci_send_cmd(conn->hdev, -- HCI_OP_CREATE_CONN_CANCEL, -- 6, &conn->dst); -- } -- break; -- case BT_CONNECT2: -- if (conn->type == ACL_LINK) { -- struct hci_cp_reject_conn_req rej; -- -- bacpy(&rej.bdaddr, &conn->dst); -- rej.reason = reason; -- -- r = hci_send_cmd(conn->hdev, -- HCI_OP_REJECT_CONN_REQ, -- sizeof(rej), &rej); -- } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) { -- struct hci_cp_reject_sync_conn_req rej; -- -- bacpy(&rej.bdaddr, &conn->dst); -- -- /* SCO rejection has its own limited set of -- * allowed error values (0x0D-0x0F) which isn't -- * compatible with most values passed to this -- * function. To be safe hard-code one of the -- * values that's suitable for SCO. -- */ -- rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES; -+ conn->abort_reason = reason; - -- r = hci_send_cmd(conn->hdev, -- HCI_OP_REJECT_SYNC_CONN_REQ, -- sizeof(rej), &rej); -+ /* If the connection is pending check the command opcode since that -+ * might be blocking on hci_cmd_sync_work while waiting its respective -+ * event so we need to hci_cmd_sync_cancel to cancel it. -+ */ -+ if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) { -+ switch (hci_skb_event(hdev->sent_cmd)) { -+ case HCI_EV_LE_CONN_COMPLETE: -+ case HCI_EV_LE_ENHANCED_CONN_COMPLETE: -+ case HCI_EVT_LE_CIS_ESTABLISHED: -+ hci_cmd_sync_cancel(hdev, ECANCELED); -+ break; - } -- break; -- default: -- conn->state = BT_CLOSED; -- break; - } - -- return r; -+ return hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle), -+ NULL); - } -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index a8932d449eb63..70f24dc75b596 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -908,7 +908,7 @@ int hci_get_dev_info(void __user *arg) - else - flags = hdev->flags; - -- strcpy(di.name, hdev->name); -+ strscpy(di.name, hdev->name, sizeof(di.name)); - di.bdaddr = hdev->bdaddr; - di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4); - di.flags = flags; -@@ -1491,11 +1491,12 @@ static void hci_cmd_timeout(struct work_struct *work) - struct hci_dev *hdev = container_of(work, struct hci_dev, - cmd_timer.work); - -- if (hdev->sent_cmd) { -- struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; -- u16 opcode = __le16_to_cpu(sent->opcode); -+ if (hdev->req_skb) { -+ u16 opcode = hci_skb_opcode(hdev->req_skb); - - bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); -+ -+ hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT); - } else { - bt_dev_err(hdev, "command tx timeout"); - } -@@ -2791,6 +2792,7 @@ void hci_release_dev(struct hci_dev *hdev) - - ida_simple_remove(&hci_index_ida, hdev->id); - kfree_skb(hdev->sent_cmd); -+ kfree_skb(hdev->req_skb); - kfree_skb(hdev->recv_event); - kfree(hdev); - } -@@ -2822,6 +2824,23 @@ int hci_unregister_suspend_notifier(struct hci_dev *hdev) - return ret; - } - -+/* Cancel ongoing command synchronously: -+ * -+ * - Cancel command timer -+ * - Reset command counter -+ * - Cancel command request -+ */ -+static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err) -+{ -+ bt_dev_dbg(hdev, "err 0x%2.2x", err); -+ -+ cancel_delayed_work_sync(&hdev->cmd_timer); -+ cancel_delayed_work_sync(&hdev->ncmd_timer); -+ atomic_set(&hdev->cmd_cnt, 1); -+ -+ hci_cmd_sync_cancel_sync(hdev, -err); -+} -+ - /* Suspend HCI device */ - int hci_suspend_dev(struct hci_dev *hdev) - { -@@ -2838,6 +2857,9 @@ int hci_suspend_dev(struct hci_dev *hdev) - if (mgmt_powering_down(hdev)) - return 0; - -+ /* Cancel potentially blocking sync operation before suspend */ -+ hci_cancel_cmd_sync(hdev, -EHOSTDOWN); -+ - hci_req_sync_lock(hdev); - ret = hci_suspend_sync(hdev); - hci_req_sync_unlock(hdev); -@@ -3100,21 +3122,33 @@ int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, - EXPORT_SYMBOL(__hci_cmd_send); - - /* Get data from the previously sent command */ --void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) -+static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode) - { - struct hci_command_hdr *hdr; - -- if (!hdev->sent_cmd) -+ if (!skb || skb->len < HCI_COMMAND_HDR_SIZE) - return NULL; - -- hdr = (void *) hdev->sent_cmd->data; -+ hdr = (void *)skb->data; - - if (hdr->opcode != cpu_to_le16(opcode)) - return NULL; - -- BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); -+ return skb->data + HCI_COMMAND_HDR_SIZE; -+} -+ -+/* Get data from the previously sent command */ -+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) -+{ -+ void *data; -+ -+ /* Check if opcode matches last sent command */ -+ data = hci_cmd_data(hdev->sent_cmd, opcode); -+ if (!data) -+ /* Check if opcode matches last request */ -+ data = hci_cmd_data(hdev->req_skb, opcode); - -- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; -+ return data; - } - - /* Get data from last received event */ -@@ -4010,17 +4044,19 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, - if (!status && !hci_req_is_complete(hdev)) - return; - -+ skb = hdev->req_skb; -+ - /* If this was the last command in a request the complete -- * callback would be found in hdev->sent_cmd instead of the -+ * callback would be found in hdev->req_skb instead of the - * command queue (hdev->cmd_q). - */ -- if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) { -- *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; -+ if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) { -+ *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; - return; - } - -- if (bt_cb(hdev->sent_cmd)->hci.req_complete) { -- *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; -+ if (skb && bt_cb(skb)->hci.req_complete) { -+ *req_complete = bt_cb(skb)->hci.req_complete; - return; - } - -@@ -4116,6 +4152,36 @@ static void hci_rx_work(struct work_struct *work) - } - } - -+static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb) -+{ -+ int err; -+ -+ bt_dev_dbg(hdev, "skb %p", skb); -+ -+ kfree_skb(hdev->sent_cmd); -+ -+ hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); -+ if (!hdev->sent_cmd) { -+ skb_queue_head(&hdev->cmd_q, skb); -+ queue_work(hdev->workqueue, &hdev->cmd_work); -+ return; -+ } -+ -+ err = hci_send_frame(hdev, skb); -+ if (err < 0) { -+ hci_cmd_sync_cancel_sync(hdev, err); -+ return; -+ } -+ -+ if (hci_req_status_pend(hdev) && -+ !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) { -+ kfree_skb(hdev->req_skb); -+ hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL); -+ } -+ -+ atomic_dec(&hdev->cmd_cnt); -+} -+ - static void hci_cmd_work(struct work_struct *work) - { - struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); -@@ -4130,30 +4196,15 @@ static void hci_cmd_work(struct work_struct *work) - if (!skb) - return; - -- kfree_skb(hdev->sent_cmd); -- -- hdev->sent_cmd = skb_clone(skb, GFP_KERNEL); -- if (hdev->sent_cmd) { -- int res; -- if (hci_req_status_pend(hdev)) -- hci_dev_set_flag(hdev, HCI_CMD_PENDING); -- atomic_dec(&hdev->cmd_cnt); -- -- res = hci_send_frame(hdev, skb); -- if (res < 0) -- __hci_cmd_sync_cancel(hdev, -res); -- -- rcu_read_lock(); -- if (test_bit(HCI_RESET, &hdev->flags) || -- hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) -- cancel_delayed_work(&hdev->cmd_timer); -- else -- queue_delayed_work(hdev->workqueue, &hdev->cmd_timer, -- HCI_CMD_TIMEOUT); -- rcu_read_unlock(); -- } else { -- skb_queue_head(&hdev->cmd_q, skb); -- queue_work(hdev->workqueue, &hdev->cmd_work); -- } -+ hci_send_cmd_sync(hdev, skb); -+ -+ rcu_read_lock(); -+ if (test_bit(HCI_RESET, &hdev->flags) || -+ hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) -+ cancel_delayed_work(&hdev->cmd_timer); -+ else -+ queue_delayed_work(hdev->workqueue, &hdev->cmd_timer, -+ HCI_CMD_TIMEOUT); -+ rcu_read_unlock(); - } - } -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index 452d839c152fc..b150dee88f35c 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -1761,7 +1761,7 @@ static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, - { - struct discovery_state *d = &hdev->discovery; - -- if (len > HCI_MAX_AD_LENGTH) -+ if (len > max_adv_len(hdev)) - return; - - bacpy(&d->last_adv_addr, bdaddr); -@@ -3567,8 +3567,6 @@ static void hci_remote_name_evt(struct hci_dev *hdev, void *data, - - bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); - -- hci_conn_check_pending(hdev); -- - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); -@@ -4331,7 +4329,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, void *data, - * (since for this kind of commands there will not be a command - * complete event). - */ -- if (ev->status || (hdev->sent_cmd && !hci_skb_event(hdev->sent_cmd))) { -+ if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) { - hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, - req_complete_skb); - if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { -@@ -6242,8 +6240,9 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, - return; - } - -- if (!ext_adv && len > HCI_MAX_AD_LENGTH) { -- bt_dev_err_ratelimited(hdev, "legacy adv larger than 31 bytes"); -+ if (len > max_adv_len(hdev)) { -+ bt_dev_err_ratelimited(hdev, -+ "adv larger than maximum supported"); - return; - } - -@@ -6308,7 +6307,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, - */ - conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved, - type); -- if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) { -+ if (!ext_adv && conn && type == LE_ADV_IND && -+ len <= max_adv_len(hdev)) { - /* Store report for later inclusion by - * mgmt_device_connected - */ -@@ -6449,7 +6449,7 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data, - info->length + 1)) - break; - -- if (info->length <= HCI_MAX_AD_LENGTH) { -+ if (info->length <= max_adv_len(hdev)) { - rssi = info->data[info->length]; - process_adv_report(hdev, info->type, &info->bdaddr, - info->bdaddr_type, NULL, 0, rssi, -@@ -7149,10 +7149,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, void *data, - bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent); - - /* Only match event if command OGF is for LE */ -- if (hdev->sent_cmd && -- hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) == 0x08 && -- hci_skb_event(hdev->sent_cmd) == ev->subevent) { -- *opcode = hci_skb_opcode(hdev->sent_cmd); -+ if (hdev->req_skb && -+ hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 && -+ hci_skb_event(hdev->req_skb) == ev->subevent) { -+ *opcode = hci_skb_opcode(hdev->req_skb); - hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete, - req_complete_skb); - } -@@ -7539,10 +7539,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) - } - - /* Only match event if command OGF is not for LE */ -- if (hdev->sent_cmd && -- hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) != 0x08 && -- hci_skb_event(hdev->sent_cmd) == event) { -- hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->sent_cmd), -+ if (hdev->req_skb && -+ hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 && -+ hci_skb_event(hdev->req_skb) == event) { -+ hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb), - status, &req_complete, &req_complete_skb); - req_evt = event; - } -diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c -index f7e006a363829..4468647df6722 100644 ---- a/net/bluetooth/hci_request.c -+++ b/net/bluetooth/hci_request.c -@@ -916,7 +916,7 @@ void hci_request_setup(struct hci_dev *hdev) - - void hci_request_cancel_all(struct hci_dev *hdev) - { -- __hci_cmd_sync_cancel(hdev, ENODEV); -+ hci_cmd_sync_cancel_sync(hdev, ENODEV); - - cancel_interleave_scan(hdev); - } -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index a337340464567..65b2ad34179f8 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -31,6 +31,10 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode, - hdev->req_result = result; - hdev->req_status = HCI_REQ_DONE; - -+ /* Free the request command so it is not used as response */ -+ kfree_skb(hdev->req_skb); -+ hdev->req_skb = NULL; -+ - if (skb) { - struct sock *sk = hci_skb_sk(skb); - -@@ -38,7 +42,7 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode, - if (sk) - sock_put(sk); - -- hdev->req_skb = skb_get(skb); -+ hdev->req_rsp = skb_get(skb); - } - - wake_up_interruptible(&hdev->req_wait_q); -@@ -186,8 +190,8 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, - - hdev->req_status = 0; - hdev->req_result = 0; -- skb = hdev->req_skb; -- hdev->req_skb = NULL; -+ skb = hdev->req_rsp; -+ hdev->req_rsp = NULL; - - bt_dev_dbg(hdev, "end: err %d", err); - -@@ -651,7 +655,7 @@ void hci_cmd_sync_clear(struct hci_dev *hdev) - mutex_unlock(&hdev->cmd_sync_work_lock); - } - --void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err) -+void hci_cmd_sync_cancel(struct hci_dev *hdev, int err) - { - bt_dev_dbg(hdev, "err 0x%2.2x", err); - -@@ -659,15 +663,17 @@ void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err) - hdev->req_result = err; - hdev->req_status = HCI_REQ_CANCELED; - -- cancel_delayed_work_sync(&hdev->cmd_timer); -- cancel_delayed_work_sync(&hdev->ncmd_timer); -- atomic_set(&hdev->cmd_cnt, 1); -- -- wake_up_interruptible(&hdev->req_wait_q); -+ queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work); - } - } -+EXPORT_SYMBOL(hci_cmd_sync_cancel); - --void hci_cmd_sync_cancel(struct hci_dev *hdev, int err) -+/* Cancel ongoing command request synchronously: -+ * -+ * - Set result and mark status to HCI_REQ_CANCELED -+ * - Wakeup command sync thread -+ */ -+void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err) - { - bt_dev_dbg(hdev, "err 0x%2.2x", err); - -@@ -675,13 +681,17 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err) - hdev->req_result = err; - hdev->req_status = HCI_REQ_CANCELED; - -- queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work); -+ wake_up_interruptible(&hdev->req_wait_q); - } - } --EXPORT_SYMBOL(hci_cmd_sync_cancel); -+EXPORT_SYMBOL(hci_cmd_sync_cancel_sync); - --int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, -- void *data, hci_cmd_sync_work_destroy_t destroy) -+/* Submit HCI command to be run in as cmd_sync_work: -+ * -+ * - hdev must _not_ be unregistered -+ */ -+int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, -+ void *data, hci_cmd_sync_work_destroy_t destroy) - { - struct hci_cmd_sync_work_entry *entry; - int err = 0; -@@ -711,6 +721,23 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, - mutex_unlock(&hdev->unregister_lock); - return err; - } -+EXPORT_SYMBOL(hci_cmd_sync_submit); -+ -+/* Queue HCI command: -+ * -+ * - hdev must be running -+ */ -+int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, -+ void *data, hci_cmd_sync_work_destroy_t destroy) -+{ -+ /* Only queue command if hdev is running which means it had been opened -+ * and is either on init phase or is already up. -+ */ -+ if (!test_bit(HCI_RUNNING, &hdev->flags)) -+ return -ENETDOWN; -+ -+ return hci_cmd_sync_submit(hdev, func, data, destroy); -+} - EXPORT_SYMBOL(hci_cmd_sync_queue); - - int hci_update_eir_sync(struct hci_dev *hdev) -@@ -4856,6 +4883,11 @@ int hci_dev_open_sync(struct hci_dev *hdev) - hdev->sent_cmd = NULL; - } - -+ if (hdev->req_skb) { -+ kfree_skb(hdev->req_skb); -+ hdev->req_skb = NULL; -+ } -+ - clear_bit(HCI_RUNNING, &hdev->flags); - hci_sock_dev_event(hdev, HCI_DEV_CLOSE); - -@@ -5017,6 +5049,12 @@ int hci_dev_close_sync(struct hci_dev *hdev) - hdev->sent_cmd = NULL; - } - -+ /* Drop last request */ -+ if (hdev->req_skb) { -+ kfree_skb(hdev->req_skb); -+ hdev->req_skb = NULL; -+ } -+ - clear_bit(HCI_RUNNING, &hdev->flags); - hci_sock_dev_event(hdev, HCI_DEV_CLOSE); - -@@ -5209,22 +5247,27 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn, - } - - static int hci_le_connect_cancel_sync(struct hci_dev *hdev, -- struct hci_conn *conn) -+ struct hci_conn *conn, u8 reason) - { -+ /* Return reason if scanning since the connection shall probably be -+ * cleanup directly. -+ */ - if (test_bit(HCI_CONN_SCANNING, &conn->flags)) -- return 0; -+ return reason; - -- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) -+ if (conn->role == HCI_ROLE_SLAVE || -+ test_and_set_bit(HCI_CONN_CANCEL, &conn->flags)) - return 0; - - return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL, - 0, NULL, HCI_CMD_TIMEOUT); - } - --static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn) -+static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, -+ u8 reason) - { - if (conn->type == LE_LINK) -- return hci_le_connect_cancel_sync(hdev, conn); -+ return hci_le_connect_cancel_sync(hdev, conn, reason); - - if (hdev->hci_ver < BLUETOOTH_VER_1_2) - return 0; -@@ -5277,9 +5320,11 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) - case BT_CONFIG: - return hci_disconnect_sync(hdev, conn, reason); - case BT_CONNECT: -- err = hci_connect_cancel_sync(hdev, conn); -+ err = hci_connect_cancel_sync(hdev, conn, reason); - /* Cleanup hci_conn object if it cannot be cancelled as it -- * likelly means the controller and host stack are out of sync. -+ * likelly means the controller and host stack are out of sync -+ * or in case of LE it was still scanning so it can be cleanup -+ * safely. - */ - if (err) { - hci_dev_lock(hdev); -@@ -6194,7 +6239,7 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn) - - done: - if (err == -ETIMEDOUT) -- hci_le_connect_cancel_sync(hdev, conn); -+ hci_le_connect_cancel_sync(hdev, conn, 0x00); - - /* Re-enable advertising after the connection attempt is finished. */ - hci_resume_advertising_sync(hdev); -diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c -index 6d631a2e60166..716f6dc4934b7 100644 ---- a/net/bluetooth/mgmt.c -+++ b/net/bluetooth/mgmt.c -@@ -1039,6 +1039,8 @@ static void rpa_expired(struct work_struct *work) - hci_cmd_sync_queue(hdev, rpa_expired_sync, NULL, NULL); - } - -+static int set_discoverable_sync(struct hci_dev *hdev, void *data); -+ - static void discov_off(struct work_struct *work) - { - struct hci_dev *hdev = container_of(work, struct hci_dev, -@@ -1057,7 +1059,7 @@ static void discov_off(struct work_struct *work) - hci_dev_clear_flag(hdev, HCI_DISCOVERABLE); - hdev->discov_timeout = 0; - -- hci_update_discoverable(hdev); -+ hci_cmd_sync_queue(hdev, set_discoverable_sync, NULL, NULL); - - mgmt_new_settings(hdev); - -@@ -1399,8 +1401,16 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, - goto failed; - } - -- err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd, -- mgmt_set_powered_complete); -+ /* Cancel potentially blocking sync operation before power off */ -+ if (cp->val == 0x00) { -+ hci_cmd_sync_cancel_sync(hdev, -EHOSTDOWN); -+ err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd, -+ mgmt_set_powered_complete); -+ } else { -+ /* Use hci_cmd_sync_submit since hdev might not be running */ -+ err = hci_cmd_sync_submit(hdev, set_powered_sync, cmd, -+ mgmt_set_powered_complete); -+ } - - if (err < 0) - mgmt_pending_remove(cmd); -@@ -3573,18 +3583,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, - return err; - } - --static int abort_conn_sync(struct hci_dev *hdev, void *data) --{ -- struct hci_conn *conn; -- u16 handle = PTR_ERR(data); -- -- conn = hci_conn_hash_lookup_handle(hdev, handle); -- if (!conn) -- return 0; -- -- return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM); --} -- - static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, - u16 len) - { -@@ -3635,8 +3633,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data, - le_addr_type(addr->type)); - - if (conn->conn_reason == CONN_REASON_PAIR_DEVICE) -- hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle), -- NULL); -+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM); - - unlock: - hci_dev_unlock(hdev); -@@ -5381,9 +5378,9 @@ static u8 parse_adv_monitor_pattern(struct adv_monitor *m, u8 pattern_count, - for (i = 0; i < pattern_count; i++) { - offset = patterns[i].offset; - length = patterns[i].length; -- if (offset >= HCI_MAX_AD_LENGTH || -- length > HCI_MAX_AD_LENGTH || -- (offset + length) > HCI_MAX_AD_LENGTH) -+ if (offset >= HCI_MAX_EXT_AD_LENGTH || -+ length > HCI_MAX_EXT_AD_LENGTH || -+ (offset + length) > HCI_MAX_EXT_AD_LENGTH) - return MGMT_STATUS_INVALID_PARAMS; - - p = kmalloc(sizeof(*p), GFP_KERNEL); -@@ -8439,8 +8436,8 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev, - supported_flags = get_supported_adv_flags(hdev); - - rp->supported_flags = cpu_to_le32(supported_flags); -- rp->max_adv_data_len = HCI_MAX_AD_LENGTH; -- rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH; -+ rp->max_adv_data_len = max_adv_len(hdev); -+ rp->max_scan_rsp_len = max_adv_len(hdev); - rp->max_instances = hdev->le_num_of_adv_sets; - rp->num_instances = hdev->adv_instance_cnt; - -@@ -8468,7 +8465,7 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev, - - static u8 calculate_name_len(struct hci_dev *hdev) - { -- u8 buf[HCI_MAX_SHORT_NAME_LENGTH + 3]; -+ u8 buf[HCI_MAX_SHORT_NAME_LENGTH + 2]; /* len + type + name */ - - return eir_append_local_name(hdev, buf, 0); - } -@@ -8476,7 +8473,7 @@ static u8 calculate_name_len(struct hci_dev *hdev) - static u8 tlv_data_max_len(struct hci_dev *hdev, u32 adv_flags, - bool is_adv_data) - { -- u8 max_len = HCI_MAX_AD_LENGTH; -+ u8 max_len = max_adv_len(hdev); - - if (is_adv_data) { - if (adv_flags & (MGMT_ADV_FLAG_DISCOV | -@@ -9764,14 +9761,6 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, - struct mgmt_ev_device_disconnected ev; - struct sock *sk = NULL; - -- /* The connection is still in hci_conn_hash so test for 1 -- * instead of 0 to know if this is the last one. -- */ -- if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { -- cancel_delayed_work(&hdev->power_off); -- queue_work(hdev->req_workqueue, &hdev->power_off.work); -- } -- - if (!mgmt_connected) - return; - -@@ -9828,14 +9817,6 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - { - struct mgmt_ev_connect_failed ev; - -- /* The connection is still in hci_conn_hash so test for 1 -- * instead of 0 to know if this is the last one. -- */ -- if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { -- cancel_delayed_work(&hdev->power_off); -- queue_work(hdev->req_workqueue, &hdev->power_off.work); -- } -- - bacpy(&ev.addr.bdaddr, bdaddr); - ev.addr.type = link_to_bdaddr(link_type, addr_type); - ev.status = mgmt_status(status); -diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c -index 8d6fce9005bdd..4f54c7df3a94f 100644 ---- a/net/bluetooth/rfcomm/core.c -+++ b/net/bluetooth/rfcomm/core.c -@@ -1937,7 +1937,7 @@ static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s) - /* Get data directly from socket receive queue without copying it. */ - while ((skb = skb_dequeue(&sk->sk_receive_queue))) { - skb_orphan(skb); -- if (!skb_linearize(skb)) { -+ if (!skb_linearize(skb) && sk->sk_state != BT_CLOSED) { - s = rfcomm_recv_frame(s, skb); - if (!s) - break; -diff --git a/net/core/dev.c b/net/core/dev.c -index 60619fe8af5fc..65284eeec7de5 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2271,7 +2271,7 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) - rcu_read_lock(); - again: - list_for_each_entry_rcu(ptype, ptype_list, list) { -- if (ptype->ignore_outgoing) -+ if (READ_ONCE(ptype->ignore_outgoing)) - continue; - - /* Never send packets back to the socket -@@ -6645,6 +6645,8 @@ static int napi_threaded_poll(void *data) - void *have; - - while (!napi_thread_wait(napi)) { -+ unsigned long last_qs = jiffies; -+ - for (;;) { - bool repoll = false; - -@@ -6659,6 +6661,7 @@ static int napi_threaded_poll(void *data) - if (!repoll) - break; - -+ rcu_softirq_qs_periodic(last_qs); - cond_resched(); - } - } -diff --git a/net/core/scm.c b/net/core/scm.c -index e762a4b8a1d22..a877c4ef4c256 100644 ---- a/net/core/scm.c -+++ b/net/core/scm.c -@@ -105,7 +105,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) - if (fd < 0 || !(file = fget_raw(fd))) - return -EBADF; - /* don't allow io_uring files */ -- if (io_uring_get_socket(file)) { -+ if (io_is_uring_fops(file)) { - fput(file); - return -EINVAL; - } -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index d4bd10f8723df..e38a4c7449f62 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -6500,6 +6500,14 @@ static struct skb_ext *skb_ext_maybe_cow(struct skb_ext *old, - for (i = 0; i < sp->len; i++) - xfrm_state_hold(sp->xvec[i]); - } -+#endif -+#ifdef CONFIG_MCTP_FLOWS -+ if (old_active & (1 << SKB_EXT_MCTP)) { -+ struct mctp_flow *flow = skb_ext_get_ptr(old, SKB_EXT_MCTP); -+ -+ if (flow->key) -+ refcount_inc(&flow->key->refs); -+ } - #endif - __skb_ext_put(old); - return new; -diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c -index f7cf74cdd3db1..e6ea6764d10ab 100644 ---- a/net/core/sock_diag.c -+++ b/net/core/sock_diag.c -@@ -190,7 +190,7 @@ int sock_diag_register(const struct sock_diag_handler *hndl) - if (sock_diag_handlers[hndl->family]) - err = -EBUSY; - else -- sock_diag_handlers[hndl->family] = hndl; -+ WRITE_ONCE(sock_diag_handlers[hndl->family], hndl); - mutex_unlock(&sock_diag_table_mutex); - - return err; -@@ -206,7 +206,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) - - mutex_lock(&sock_diag_table_mutex); - BUG_ON(sock_diag_handlers[family] != hnld); -- sock_diag_handlers[family] = NULL; -+ WRITE_ONCE(sock_diag_handlers[family], NULL); - mutex_unlock(&sock_diag_table_mutex); - } - EXPORT_SYMBOL_GPL(sock_diag_unregister); -@@ -224,7 +224,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh) - return -EINVAL; - req->sdiag_family = array_index_nospec(req->sdiag_family, AF_MAX); - -- if (sock_diag_handlers[req->sdiag_family] == NULL) -+ if (READ_ONCE(sock_diag_handlers[req->sdiag_family]) == NULL) - sock_load_diag_module(req->sdiag_family, 0); - - mutex_lock(&sock_diag_table_mutex); -@@ -283,12 +283,12 @@ static int sock_diag_bind(struct net *net, int group) - switch (group) { - case SKNLGRP_INET_TCP_DESTROY: - case SKNLGRP_INET_UDP_DESTROY: -- if (!sock_diag_handlers[AF_INET]) -+ if (!READ_ONCE(sock_diag_handlers[AF_INET])) - sock_load_diag_module(AF_INET, 0); - break; - case SKNLGRP_INET6_TCP_DESTROY: - case SKNLGRP_INET6_UDP_DESTROY: -- if (!sock_diag_handlers[AF_INET6]) -+ if (!READ_ONCE(sock_diag_handlers[AF_INET6])) - sock_load_diag_module(AF_INET6, 0); - break; - } -diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c -index 0b01998780952..e44a039e36afe 100644 ---- a/net/hsr/hsr_framereg.c -+++ b/net/hsr/hsr_framereg.c -@@ -235,6 +235,10 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db, - */ - if (ethhdr->h_proto == htons(ETH_P_PRP) || - ethhdr->h_proto == htons(ETH_P_HSR)) { -+ /* Check if skb contains hsr_ethhdr */ -+ if (skb->mac_len < sizeof(struct hsr_ethhdr)) -+ return NULL; -+ - /* Use the existing sequence_nr from the tag as starting point - * for filtering duplicate frames. - */ -diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c -index b099c31501509..257b50124cee5 100644 ---- a/net/hsr/hsr_main.c -+++ b/net/hsr/hsr_main.c -@@ -148,14 +148,21 @@ static struct notifier_block hsr_nb = { - - static int __init hsr_init(void) - { -- int res; -+ int err; - - BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN); - -- register_netdevice_notifier(&hsr_nb); -- res = hsr_netlink_init(); -+ err = register_netdevice_notifier(&hsr_nb); -+ if (err) -+ return err; -+ -+ err = hsr_netlink_init(); -+ if (err) { -+ unregister_netdevice_notifier(&hsr_nb); -+ return err; -+ } - -- return res; -+ return 0; - } - - static void __exit hsr_exit(void) -diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c -index f7426926a1041..8f690a6e61baa 100644 ---- a/net/ipv4/inet_diag.c -+++ b/net/ipv4/inet_diag.c -@@ -57,7 +57,7 @@ static const struct inet_diag_handler *inet_diag_lock_handler(int proto) - return ERR_PTR(-ENOENT); - } - -- if (!inet_diag_table[proto]) -+ if (!READ_ONCE(inet_diag_table[proto])) - sock_load_diag_module(AF_INET, proto); - - mutex_lock(&inet_diag_table_mutex); -@@ -1419,7 +1419,7 @@ int inet_diag_register(const struct inet_diag_handler *h) - mutex_lock(&inet_diag_table_mutex); - err = -EEXIST; - if (!inet_diag_table[type]) { -- inet_diag_table[type] = h; -+ WRITE_ONCE(inet_diag_table[type], h); - err = 0; - } - mutex_unlock(&inet_diag_table_mutex); -@@ -1436,7 +1436,7 @@ void inet_diag_unregister(const struct inet_diag_handler *h) - return; - - mutex_lock(&inet_diag_table_mutex); -- inet_diag_table[type] = NULL; -+ WRITE_ONCE(inet_diag_table[type], NULL); - mutex_unlock(&inet_diag_table_mutex); - } - EXPORT_SYMBOL_GPL(inet_diag_unregister); -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 56776e1b1de52..0ad25e6783ac7 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -1117,7 +1117,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, - sock_prot_inuse_add(net, sk->sk_prot, -1); - - spin_lock(lock); -- sk_nulls_del_node_init_rcu(sk); -+ __sk_nulls_del_node_init_rcu(sk); - spin_unlock(lock); - - sk->sk_hash = 0; -diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c -index 1d77d992e6e77..340a8f0c29800 100644 ---- a/net/ipv4/inet_timewait_sock.c -+++ b/net/ipv4/inet_timewait_sock.c -@@ -281,12 +281,12 @@ void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo, bool rearm) - } - EXPORT_SYMBOL_GPL(__inet_twsk_schedule); - -+/* Remove all non full sockets (TIME_WAIT and NEW_SYN_RECV) for dead netns */ - void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family) - { -- struct inet_timewait_sock *tw; -- struct sock *sk; - struct hlist_nulls_node *node; - unsigned int slot; -+ struct sock *sk; - - for (slot = 0; slot <= hashinfo->ehash_mask; slot++) { - struct inet_ehash_bucket *head = &hashinfo->ehash[slot]; -@@ -295,38 +295,35 @@ void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family) - rcu_read_lock(); - restart: - sk_nulls_for_each_rcu(sk, node, &head->chain) { -- if (sk->sk_state != TCP_TIME_WAIT) { -- /* A kernel listener socket might not hold refcnt for net, -- * so reqsk_timer_handler() could be fired after net is -- * freed. Userspace listener and reqsk never exist here. -- */ -- if (unlikely(sk->sk_state == TCP_NEW_SYN_RECV && -- hashinfo->pernet)) { -- struct request_sock *req = inet_reqsk(sk); -- -- inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req); -- } -+ int state = inet_sk_state_load(sk); - -+ if ((1 << state) & ~(TCPF_TIME_WAIT | -+ TCPF_NEW_SYN_RECV)) - continue; -- } - -- tw = inet_twsk(sk); -- if ((tw->tw_family != family) || -- refcount_read(&twsk_net(tw)->ns.count)) -+ if (sk->sk_family != family || -+ refcount_read(&sock_net(sk)->ns.count)) - continue; - -- if (unlikely(!refcount_inc_not_zero(&tw->tw_refcnt))) -+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) - continue; - -- if (unlikely((tw->tw_family != family) || -- refcount_read(&twsk_net(tw)->ns.count))) { -- inet_twsk_put(tw); -+ if (unlikely(sk->sk_family != family || -+ refcount_read(&sock_net(sk)->ns.count))) { -+ sock_gen_put(sk); - goto restart; - } - - rcu_read_unlock(); - local_bh_disable(); -- inet_twsk_deschedule_put(tw); -+ if (state == TCP_TIME_WAIT) { -+ inet_twsk_deschedule_put(inet_twsk(sk)); -+ } else { -+ struct request_sock *req = inet_reqsk(sk); -+ -+ inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, -+ req); -+ } - local_bh_enable(); - goto restart_rcu; - } -diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c -index 328f9068c6a43..3445e576b05bc 100644 ---- a/net/ipv4/ip_tunnel.c -+++ b/net/ipv4/ip_tunnel.c -@@ -364,7 +364,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, - bool log_ecn_error) - { - const struct iphdr *iph = ip_hdr(skb); -- int err; -+ int nh, err; - - #ifdef CONFIG_NET_IPGRE_BROADCAST - if (ipv4_is_multicast(iph->daddr)) { -@@ -390,8 +390,21 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, - tunnel->i_seqno = ntohl(tpi->seq) + 1; - } - -+ /* Save offset of outer header relative to skb->head, -+ * because we are going to reset the network header to the inner header -+ * and might change skb->head. -+ */ -+ nh = skb_network_header(skb) - skb->head; -+ - skb_set_network_header(skb, (tunnel->dev->type == ARPHRD_ETHER) ? ETH_HLEN : 0); - -+ if (!pskb_inet_may_pull(skb)) { -+ DEV_STATS_INC(tunnel->dev, rx_length_errors); -+ DEV_STATS_INC(tunnel->dev, rx_errors); -+ goto drop; -+ } -+ iph = (struct iphdr *)(skb->head + nh); -+ - err = IP_ECN_decapsulate(iph, skb); - if (unlikely(err)) { - if (log_ecn_error) -diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c -index d5421c38c2aae..3ed9ed2bffd29 100644 ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -1581,9 +1581,11 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval, - - if (copy_from_sockptr(&olr, optlen, sizeof(int))) - return -EFAULT; -- olr = min_t(unsigned int, olr, sizeof(int)); - if (olr < 0) - return -EINVAL; -+ -+ olr = min_t(unsigned int, olr, sizeof(int)); -+ - if (copy_to_sockptr(optlen, &olr, sizeof(int))) - return -EFAULT; - if (copy_to_sockptr(optval, &val, olr)) -diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c -index 7c63b91edbf7a..ee0efd0efec40 100644 ---- a/net/ipv4/raw.c -+++ b/net/ipv4/raw.c -@@ -348,6 +348,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, - goto error; - skb_reserve(skb, hlen); - -+ skb->protocol = htons(ETH_P_IP); - skb->priority = READ_ONCE(sk->sk_priority); - skb->mark = sockc->mark; - skb->tstamp = sockc->transmit_time; -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 86e7695d91adf..5a165e29f7be4 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -4102,11 +4102,11 @@ int do_tcp_getsockopt(struct sock *sk, int level, - if (copy_from_sockptr(&len, optlen, sizeof(int))) - return -EFAULT; - -- len = min_t(unsigned int, len, sizeof(int)); -- - if (len < 0) - return -EINVAL; - -+ len = min_t(unsigned int, len, sizeof(int)); -+ - switch (optname) { - case TCP_MAXSEG: - val = tp->mss_cache; -diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c -index 42844d20da020..b3bfa1a09df68 100644 ---- a/net/ipv4/tcp_minisocks.c -+++ b/net/ipv4/tcp_minisocks.c -@@ -357,10 +357,6 @@ void tcp_twsk_purge(struct list_head *net_exit_list, int family) - /* Even if tw_refcount == 1, we must clean up kernel reqsk */ - inet_twsk_purge(net->ipv4.tcp_death_row.hashinfo, family); - } else if (!purged_once) { -- /* The last refcount is decremented in tcp_sk_exit_batch() */ -- if (refcount_read(&net->ipv4.tcp_death_row.tw_refcount) == 1) -- continue; -- - inet_twsk_purge(&tcp_hashinfo, family); - purged_once = true; - } -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 87d759bab0012..7856b7a3e0ee9 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2790,11 +2790,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, - if (get_user(len, optlen)) - return -EFAULT; - -- len = min_t(unsigned int, len, sizeof(int)); -- - if (len < 0) - return -EINVAL; - -+ len = min_t(unsigned int, len, sizeof(int)); -+ - switch (optname) { - case UDP_CORK: - val = udp_test_bit(CORK, sk); -diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c -index 7c20038330104..be52b18e08a6b 100644 ---- a/net/ipv6/fib6_rules.c -+++ b/net/ipv6/fib6_rules.c -@@ -449,6 +449,11 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) - + nla_total_size(16); /* src */ - } - -+static void fib6_rule_flush_cache(struct fib_rules_ops *ops) -+{ -+ rt_genid_bump_ipv6(ops->fro_net); -+} -+ - static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = { - .family = AF_INET6, - .rule_size = sizeof(struct fib6_rule), -@@ -461,6 +466,7 @@ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = { - .compare = fib6_rule_compare, - .fill = fib6_rule_fill, - .nlmsg_payload = fib6_rule_nlmsg_payload, -+ .flush_cache = fib6_rule_flush_cache, - .nlgroup = RTNLGRP_IPV6_RULE, - .owner = THIS_MODULE, - .fro_net = &init_net, -diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c -index 566f3b7b957e9..a777695389403 100644 ---- a/net/ipv6/mcast.c -+++ b/net/ipv6/mcast.c -@@ -2722,7 +2722,6 @@ void ipv6_mc_down(struct inet6_dev *idev) - /* Should stop work after group drop. or we will - * start work again in mld_ifc_event() - */ -- synchronize_net(); - mld_query_stop_work(idev); - mld_report_stop_work(idev); - -diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c -index fc3fddeb6f36d..f66b5f74cd83a 100644 ---- a/net/iucv/iucv.c -+++ b/net/iucv/iucv.c -@@ -156,7 +156,7 @@ static char iucv_error_pathid[16] = "INVALID PATHID"; - static LIST_HEAD(iucv_handler_list); - - /* -- * iucv_path_table: an array of iucv_path structures. -+ * iucv_path_table: array of pointers to iucv_path structures. - */ - static struct iucv_path **iucv_path_table; - static unsigned long iucv_max_pathid; -@@ -544,7 +544,7 @@ static int iucv_enable(void) - - cpus_read_lock(); - rc = -ENOMEM; -- alloc_size = iucv_max_pathid * sizeof(struct iucv_path); -+ alloc_size = iucv_max_pathid * sizeof(*iucv_path_table); - iucv_path_table = kzalloc(alloc_size, GFP_KERNEL); - if (!iucv_path_table) - goto out; -diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c -index 65845c59c0655..7d37bf4334d26 100644 ---- a/net/kcm/kcmsock.c -+++ b/net/kcm/kcmsock.c -@@ -1274,10 +1274,11 @@ static int kcm_getsockopt(struct socket *sock, int level, int optname, - if (get_user(len, optlen)) - return -EFAULT; - -- len = min_t(unsigned int, len, sizeof(int)); - if (len < 0) - return -EINVAL; - -+ len = min_t(unsigned int, len, sizeof(int)); -+ - switch (optname) { - case KCM_RECV_DISABLE: - val = kcm->rx_disabled; -diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c -index f011af6601c9c..6146e4e67bbb5 100644 ---- a/net/l2tp/l2tp_ppp.c -+++ b/net/l2tp/l2tp_ppp.c -@@ -1356,11 +1356,11 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, - if (get_user(len, optlen)) - return -EFAULT; - -- len = min_t(unsigned int, len, sizeof(int)); -- - if (len < 0) - return -EINVAL; - -+ len = min_t(unsigned int, len, sizeof(int)); -+ - err = -ENOTCONN; - if (!sk->sk_user_data) - goto end; -diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c -index d5ea5f5bcf3a0..9d33fd2377c88 100644 ---- a/net/mac80211/rate.c -+++ b/net/mac80211/rate.c -@@ -119,7 +119,8 @@ void rate_control_rate_update(struct ieee80211_local *local, - rcu_read_unlock(); - } - -- drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); -+ if (sta->uploaded) -+ drv_sta_rc_update(local, sta->sdata, &sta->sta, changed); - } - - int ieee80211_rate_control_register(const struct rate_control_ops *ops) -diff --git a/net/mctp/route.c b/net/mctp/route.c -index 0144d8ebdaefb..05ab4fddc82e9 100644 ---- a/net/mctp/route.c -+++ b/net/mctp/route.c -@@ -843,6 +843,9 @@ static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb, - /* copy message payload */ - skb_copy_bits(skb, pos, skb_transport_header(skb2), size); - -+ /* we need to copy the extensions, for MCTP flow data */ -+ skb_ext_copy(skb2, skb); -+ - /* do route */ - rc = rt->output(rt, skb2); - if (rc) -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index d3ba947f43761..0a86c019a75de 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -1205,7 +1205,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx) - if (flags & ~NFT_TABLE_F_MASK) - return -EOPNOTSUPP; - -- if (flags == ctx->table->flags) -+ if (flags == (ctx->table->flags & NFT_TABLE_F_MASK)) - return 0; - - if ((nft_table_has_owner(ctx->table) && -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index e1969209b3abb..58eca26162735 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -2240,8 +2240,6 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, - if (m) { - rcu_barrier(); - -- nft_set_pipapo_match_destroy(ctx, set, m); -- - for_each_possible_cpu(cpu) - pipapo_free_scratch(m, cpu); - free_percpu(m->scratch); -@@ -2253,8 +2251,7 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, - if (priv->clone) { - m = priv->clone; - -- if (priv->dirty) -- nft_set_pipapo_match_destroy(ctx, set, m); -+ nft_set_pipapo_match_destroy(ctx, set, m); - - for_each_possible_cpu(cpu) - pipapo_free_scratch(priv->clone, cpu); -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index c3117350f5fbb..7188ca8d84693 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -3981,7 +3981,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, - if (val < 0 || val > 1) - return -EINVAL; - -- po->prot_hook.ignore_outgoing = !!val; -+ WRITE_ONCE(po->prot_hook.ignore_outgoing, !!val); - return 0; - } - case PACKET_TX_HAS_OFF: -@@ -4110,7 +4110,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, - 0); - break; - case PACKET_IGNORE_OUTGOING: -- val = po->prot_hook.ignore_outgoing; -+ val = READ_ONCE(po->prot_hook.ignore_outgoing); - break; - case PACKET_ROLLOVER_STATS: - if (!po->rollover) -diff --git a/net/rds/send.c b/net/rds/send.c -index a4ba45c430d81..0005fb43f2dfa 100644 ---- a/net/rds/send.c -+++ b/net/rds/send.c -@@ -103,13 +103,12 @@ EXPORT_SYMBOL_GPL(rds_send_path_reset); - - static int acquire_in_xmit(struct rds_conn_path *cp) - { -- return test_and_set_bit(RDS_IN_XMIT, &cp->cp_flags) == 0; -+ return test_and_set_bit_lock(RDS_IN_XMIT, &cp->cp_flags) == 0; - } - - static void release_in_xmit(struct rds_conn_path *cp) - { -- clear_bit(RDS_IN_XMIT, &cp->cp_flags); -- smp_mb__after_atomic(); -+ clear_bit_unlock(RDS_IN_XMIT, &cp->cp_flags); - /* - * We don't use wait_on_bit()/wake_up_bit() because our waking is in a - * hot path and finding waiters is very rare. We don't want to walk -diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c -index 8d5eebb2dd1b1..1d4638aa4254f 100644 ---- a/net/sched/sch_taprio.c -+++ b/net/sched/sch_taprio.c -@@ -765,7 +765,8 @@ static const struct nla_policy entry_policy[TCA_TAPRIO_SCHED_ENTRY_MAX + 1] = { - }; - - static const struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = { -- [TCA_TAPRIO_TC_ENTRY_INDEX] = { .type = NLA_U32 }, -+ [TCA_TAPRIO_TC_ENTRY_INDEX] = NLA_POLICY_MAX(NLA_U32, -+ TC_QOPT_MAX_QUEUE), - [TCA_TAPRIO_TC_ENTRY_MAX_SDU] = { .type = NLA_U32 }, - }; - -diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c -index d435bffc61999..97ff11973c493 100644 ---- a/net/sunrpc/addr.c -+++ b/net/sunrpc/addr.c -@@ -284,10 +284,10 @@ char *rpc_sockaddr2uaddr(const struct sockaddr *sap, gfp_t gfp_flags) - } - - if (snprintf(portbuf, sizeof(portbuf), -- ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf)) -+ ".%u.%u", port >> 8, port & 0xff) >= (int)sizeof(portbuf)) - return NULL; - -- if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf)) -+ if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) >= sizeof(addrbuf)) - return NULL; - - return kstrdup(addrbuf, gfp_flags); -diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c -index d79f12c2550ac..cb32ab9a83952 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_xdr.c -+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c -@@ -250,8 +250,8 @@ static int gssx_dec_option_array(struct xdr_stream *xdr, - - creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL); - if (!creds) { -- kfree(oa->data); -- return -ENOMEM; -+ err = -ENOMEM; -+ goto free_oa; - } - - oa->data[0].option.data = CREDS_VALUE; -@@ -265,29 +265,40 @@ static int gssx_dec_option_array(struct xdr_stream *xdr, - - /* option buffer */ - p = xdr_inline_decode(xdr, 4); -- if (unlikely(p == NULL)) -- return -ENOSPC; -+ if (unlikely(p == NULL)) { -+ err = -ENOSPC; -+ goto free_creds; -+ } - - length = be32_to_cpup(p); - p = xdr_inline_decode(xdr, length); -- if (unlikely(p == NULL)) -- return -ENOSPC; -+ if (unlikely(p == NULL)) { -+ err = -ENOSPC; -+ goto free_creds; -+ } - - if (length == sizeof(CREDS_VALUE) && - memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) { - /* We have creds here. parse them */ - err = gssx_dec_linux_creds(xdr, creds); - if (err) -- return err; -+ goto free_creds; - oa->data[0].value.len = 1; /* presence */ - } else { - /* consume uninteresting buffer */ - err = gssx_dec_buffer(xdr, &dummy); - if (err) -- return err; -+ goto free_creds; - } - } - return 0; -+ -+free_creds: -+ kfree(creds); -+free_oa: -+ kfree(oa->data); -+ oa->data = NULL; -+ return err; - } - - static int gssx_dec_status(struct xdr_stream *xdr, -diff --git a/net/unix/garbage.c b/net/unix/garbage.c -index ab2c83d58b62a..9bfffe2a7f020 100644 ---- a/net/unix/garbage.c -+++ b/net/unix/garbage.c -@@ -198,7 +198,7 @@ void wait_for_unix_gc(void) - if (READ_ONCE(unix_tot_inflight) > UNIX_INFLIGHT_TRIGGER_GC && - !READ_ONCE(gc_in_progress)) - unix_gc(); -- wait_event(unix_gc_wait, gc_in_progress == false); -+ wait_event(unix_gc_wait, !READ_ONCE(gc_in_progress)); - } - - /* The external entry point: unix_gc() */ -diff --git a/net/unix/scm.c b/net/unix/scm.c -index e8e2a00bb0f58..d1048b4c2baaf 100644 ---- a/net/unix/scm.c -+++ b/net/unix/scm.c -@@ -34,10 +34,8 @@ struct sock *unix_get_socket(struct file *filp) - /* PF_UNIX ? */ - if (s && sock->ops && sock->ops->family == PF_UNIX) - u_sock = s; -- } else { -- /* Could be an io_uring instance */ -- u_sock = io_uring_get_socket(filp); - } -+ - return u_sock; - } - EXPORT_SYMBOL(unix_get_socket); -diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c -index 5c7ad301d742e..5a8b2ea56564e 100644 ---- a/net/x25/af_x25.c -+++ b/net/x25/af_x25.c -@@ -460,12 +460,12 @@ static int x25_getsockopt(struct socket *sock, int level, int optname, - if (get_user(len, optlen)) - goto out; - -- len = min_t(unsigned int, len, sizeof(int)); -- - rc = -EINVAL; - if (len < 0) - goto out; - -+ len = min_t(unsigned int, len, sizeof(int)); -+ - rc = -EFAULT; - if (put_user(len, optlen)) - goto out; -diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py -index d800b2c0af977..4f414ab706bd8 100755 ---- a/scripts/clang-tools/gen_compile_commands.py -+++ b/scripts/clang-tools/gen_compile_commands.py -@@ -170,7 +170,7 @@ def process_line(root_directory, command_prefix, file_path): - # escape the pound sign '#', either as '\#' or '$(pound)' (depending on the - # kernel version). The compile_commands.json file is not interepreted - # by Make, so this code replaces the escaped version with '#'. -- prefix = command_prefix.replace('\#', '#').replace('$(pound)', '#') -+ prefix = command_prefix.replace(r'\#', '#').replace('$(pound)', '#') - - # Use os.path.abspath() to normalize the path resolving '.' and '..' . - abs_path = os.path.abspath(os.path.join(root_directory, file_path)) -diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l -index cc386e4436834..2c2b3e6f248ca 100644 ---- a/scripts/kconfig/lexer.l -+++ b/scripts/kconfig/lexer.l -@@ -302,8 +302,11 @@ static char *expand_token(const char *in, size_t n) - new_string(); - append_string(in, n); - -- /* get the whole line because we do not know the end of token. */ -- while ((c = input()) != EOF) { -+ /* -+ * get the whole line because we do not know the end of token. -+ * input() returns 0 (not EOF!) when it reachs the end of file. -+ */ -+ while ((c = input()) != 0) { - if (c == '\n') { - unput(c); - break; -diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c -index 4589aac091542..b00bbf18a6f5d 100644 ---- a/sound/core/seq/seq_midi.c -+++ b/sound/core/seq/seq_midi.c -@@ -112,6 +112,12 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i - return 0; - } - -+/* callback for snd_seq_dump_var_event(), bridging to dump_midi() */ -+static int __dump_midi(void *ptr, void *buf, int count) -+{ -+ return dump_midi(ptr, buf, count); -+} -+ - static int event_process_midi(struct snd_seq_event *ev, int direct, - void *private_data, int atomic, int hop) - { -@@ -131,7 +137,7 @@ static int event_process_midi(struct snd_seq_event *ev, int direct, - pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); - return 0; - } -- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); -+ snd_seq_dump_var_event(ev, __dump_midi, substream); - snd_midi_event_reset_decode(msynth->parser); - } else { - if (msynth->parser == NULL) -diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c -index f5cae49500c81..ffd8e7202c334 100644 ---- a/sound/core/seq/seq_virmidi.c -+++ b/sound/core/seq/seq_virmidi.c -@@ -62,6 +62,13 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, - /* - * decode input event and put to read buffer of each opened file - */ -+ -+/* callback for snd_seq_dump_var_event(), bridging to snd_rawmidi_receive() */ -+static int dump_to_rawmidi(void *ptr, void *buf, int count) -+{ -+ return snd_rawmidi_receive(ptr, buf, count); -+} -+ - static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, - struct snd_seq_event *ev, - bool atomic) -@@ -80,7 +87,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, - if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { - if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) - continue; -- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream); -+ snd_seq_dump_var_event(ev, dump_to_rawmidi, vmidi->substream); - snd_midi_event_reset_decode(vmidi->parser); - } else { - len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 75bd7b2fa4ee6..6e759032eba2e 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -3681,6 +3681,7 @@ static void alc285_hp_init(struct hda_codec *codec) - int i, val; - int coef38, coef0d, coef36; - -+ alc_write_coefex_idx(codec, 0x58, 0x00, 0x1888); /* write default value */ - alc_update_coef_idx(codec, 0x4a, 1<<15, 1<<15); /* Reset HP JD */ - coef38 = alc_read_coef_idx(codec, 0x38); /* Amp control */ - coef0d = alc_read_coef_idx(codec, 0x0d); /* Digital Misc control */ -@@ -6692,6 +6693,60 @@ static void alc285_fixup_hp_spectre_x360(struct hda_codec *codec, - } - } - -+static void alc285_fixup_hp_envy_x360(struct hda_codec *codec, -+ const struct hda_fixup *fix, -+ int action) -+{ -+ static const struct coef_fw coefs[] = { -+ WRITE_COEF(0x08, 0x6a0c), WRITE_COEF(0x0d, 0xa023), -+ WRITE_COEF(0x10, 0x0320), WRITE_COEF(0x1a, 0x8c03), -+ WRITE_COEF(0x25, 0x1800), WRITE_COEF(0x26, 0x003a), -+ WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb014), -+ WRITE_COEF(0x2b, 0x1dfe), WRITE_COEF(0x37, 0xfe15), -+ WRITE_COEF(0x38, 0x7909), WRITE_COEF(0x45, 0xd489), -+ WRITE_COEF(0x46, 0x00f4), WRITE_COEF(0x4a, 0x21e0), -+ WRITE_COEF(0x66, 0x03f0), WRITE_COEF(0x67, 0x1000), -+ WRITE_COEF(0x6e, 0x1005), { } -+ }; -+ -+ static const struct hda_pintbl pincfgs[] = { -+ { 0x12, 0xb7a60130 }, /* Internal microphone*/ -+ { 0x14, 0x90170150 }, /* B&O soundbar speakers */ -+ { 0x17, 0x90170153 }, /* Side speakers */ -+ { 0x19, 0x03a11040 }, /* Headset microphone */ -+ { } -+ }; -+ -+ switch (action) { -+ case HDA_FIXUP_ACT_PRE_PROBE: -+ snd_hda_apply_pincfgs(codec, pincfgs); -+ -+ /* Fixes volume control problem for side speakers */ -+ alc295_fixup_disable_dac3(codec, fix, action); -+ -+ /* Fixes no sound from headset speaker */ -+ snd_hda_codec_amp_stereo(codec, 0x21, HDA_OUTPUT, 0, -1, 0); -+ -+ /* Auto-enable headset mic when plugged */ -+ snd_hda_jack_set_gating_jack(codec, 0x19, 0x21); -+ -+ /* Headset mic volume enhancement */ -+ snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREF50); -+ break; -+ case HDA_FIXUP_ACT_INIT: -+ alc_process_coef_fw(codec, coefs); -+ break; -+ case HDA_FIXUP_ACT_BUILD: -+ rename_ctl(codec, "Bass Speaker Playback Volume", -+ "B&O-Tuned Playback Volume"); -+ rename_ctl(codec, "Front Playback Switch", -+ "B&O Soundbar Playback Switch"); -+ rename_ctl(codec, "Bass Speaker Playback Switch", -+ "Side Speaker Playback Switch"); -+ break; -+ } -+} -+ - /* for hda_fixup_thinkpad_acpi() */ - #include "thinkpad_helper.c" - -@@ -7130,6 +7185,7 @@ enum { - ALC280_FIXUP_HP_9480M, - ALC245_FIXUP_HP_X360_AMP, - ALC285_FIXUP_HP_SPECTRE_X360_EB1, -+ ALC285_FIXUP_HP_ENVY_X360, - ALC288_FIXUP_DELL_HEADSET_MODE, - ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, - ALC288_FIXUP_DELL_XPS_13, -@@ -9053,6 +9109,12 @@ static const struct hda_fixup alc269_fixups[] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc285_fixup_hp_spectre_x360_eb1 - }, -+ [ALC285_FIXUP_HP_ENVY_X360] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc285_fixup_hp_envy_x360, -+ .chained = true, -+ .chain_id = ALC285_FIXUP_HP_GPIO_AMP_INIT, -+ }, - [ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc285_fixup_ideapad_s740_coef, -@@ -9594,6 +9656,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - 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, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360), - 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), -@@ -10248,6 +10311,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { - {.id = ALC295_FIXUP_HP_OMEN, .name = "alc295-hp-omen"}, - {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, - {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, -+ {.id = ALC285_FIXUP_HP_ENVY_X360, .name = "alc285-hp-envy-x360"}, - {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, - {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"}, - {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, -diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c -index f19f064a75272..972600d271586 100644 ---- a/sound/soc/amd/acp/acp-sof-mach.c -+++ b/sound/soc/amd/acp/acp-sof-mach.c -@@ -114,16 +114,14 @@ static int acp_sof_probe(struct platform_device *pdev) - card->num_controls = ARRAY_SIZE(acp_controls); - card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; - -- acp_sofdsp_dai_links_create(card); -+ ret = acp_sofdsp_dai_links_create(card); -+ if (ret) -+ return dev_err_probe(&pdev->dev, ret, "Failed to create DAI links\n"); - - ret = devm_snd_soc_register_card(&pdev->dev, card); -- if (ret) { -- dev_err(&pdev->dev, -- "devm_snd_soc_register_card(%s) failed: %d\n", -- card->name, ret); -- return ret; -- } -- -+ if (ret) -+ return dev_err_probe(&pdev->dev, ret, -+ "Failed to register card(%s)\n", card->name); - return 0; - } - -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 28da4e1858d7e..e0f406b6646ba 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -199,6 +199,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "21HY"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "21J2"), -+ } -+ }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "21J0"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -@@ -227,6 +241,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82UU"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index 844d14d4c9a51..aac9140749968 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -3802,6 +3802,16 @@ static const struct dmi_system_id dmi_platform_data[] = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), - DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"), -+ /* -+ * Above strings are too generic, LattePanda BIOS versions for -+ * all 4 hw revisions are: -+ * DF-BI-7-S70CR100-* -+ * DF-BI-7-S70CR110-* -+ * DF-BI-7-S70CR200-* -+ * LP-BS-7-S70CR700-* -+ * Do a partial match for S70CR to avoid false positive matches. -+ */ -+ DMI_MATCH(DMI_BIOS_VERSION, "S70CR"), - }, - .driver_data = (void *)&lattepanda_board_platform_data, - }, -diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c -index b901e4c65e8a5..d215e58c4a7b3 100644 ---- a/sound/soc/codecs/wm8962.c -+++ b/sound/soc/codecs/wm8962.c -@@ -2229,6 +2229,9 @@ SND_SOC_DAPM_PGA_E("HPOUT", SND_SOC_NOPM, 0, 0, NULL, 0, hp_event, - - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), -+ -+SND_SOC_DAPM_PGA("SPKOUTL Output", WM8962_CLASS_D_CONTROL_1, 6, 0, NULL, 0), -+SND_SOC_DAPM_PGA("SPKOUTR Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0), - }; - - static const struct snd_soc_dapm_widget wm8962_dapm_spk_mono_widgets[] = { -@@ -2236,7 +2239,6 @@ SND_SOC_DAPM_MIXER("Speaker Mixer", WM8962_MIXER_ENABLES, 1, 0, - spkmixl, ARRAY_SIZE(spkmixl)), - SND_SOC_DAPM_MUX_E("Speaker PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux, - out_pga_event, SND_SOC_DAPM_POST_PMU), --SND_SOC_DAPM_PGA("Speaker Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0), - SND_SOC_DAPM_OUTPUT("SPKOUT"), - }; - -@@ -2251,9 +2253,6 @@ SND_SOC_DAPM_MUX_E("SPKOUTL PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux, - SND_SOC_DAPM_MUX_E("SPKOUTR PGA", WM8962_PWR_MGMT_2, 3, 0, &spkoutr_mux, - out_pga_event, SND_SOC_DAPM_POST_PMU), - --SND_SOC_DAPM_PGA("SPKOUTR Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0), --SND_SOC_DAPM_PGA("SPKOUTL Output", WM8962_CLASS_D_CONTROL_1, 6, 0, NULL, 0), -- - SND_SOC_DAPM_OUTPUT("SPKOUTL"), - SND_SOC_DAPM_OUTPUT("SPKOUTR"), - }; -@@ -2366,12 +2365,18 @@ static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = { - { "Speaker PGA", "Mixer", "Speaker Mixer" }, - { "Speaker PGA", "DAC", "DACL" }, - -- { "Speaker Output", NULL, "Speaker PGA" }, -- { "Speaker Output", NULL, "SYSCLK" }, -- { "Speaker Output", NULL, "TOCLK" }, -- { "Speaker Output", NULL, "TEMP_SPK" }, -+ { "SPKOUTL Output", NULL, "Speaker PGA" }, -+ { "SPKOUTL Output", NULL, "SYSCLK" }, -+ { "SPKOUTL Output", NULL, "TOCLK" }, -+ { "SPKOUTL Output", NULL, "TEMP_SPK" }, - -- { "SPKOUT", NULL, "Speaker Output" }, -+ { "SPKOUTR Output", NULL, "Speaker PGA" }, -+ { "SPKOUTR Output", NULL, "SYSCLK" }, -+ { "SPKOUTR Output", NULL, "TOCLK" }, -+ { "SPKOUTR Output", NULL, "TEMP_SPK" }, -+ -+ { "SPKOUT", NULL, "SPKOUTL Output" }, -+ { "SPKOUT", NULL, "SPKOUTR Output" }, - }; - - static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = { -@@ -2914,8 +2919,12 @@ static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int s - switch (fll_id) { - case WM8962_FLL_MCLK: - case WM8962_FLL_BCLK: -+ fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT; -+ break; - case WM8962_FLL_OSC: - fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT; -+ snd_soc_component_update_bits(component, WM8962_PLL2, -+ WM8962_OSC_ENA, WM8962_OSC_ENA); - break; - case WM8962_FLL_INT: - snd_soc_component_update_bits(component, WM8962_FLL_CONTROL_1, -@@ -2924,7 +2933,7 @@ static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int s - WM8962_FLL_FRC_NCO, WM8962_FLL_FRC_NCO); - break; - default: -- dev_err(component->dev, "Unknown FLL source %d\n", ret); -+ dev_err(component->dev, "Unknown FLL source %d\n", source); - return -EINVAL; - } - -diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c -index 797d0a48d6066..094445036c20f 100644 ---- a/sound/soc/intel/boards/bytcr_rt5640.c -+++ b/sound/soc/intel/boards/bytcr_rt5640.c -@@ -685,6 +685,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { - BYT_RT5640_SSP0_AIF1 | - BYT_RT5640_MCLK_EN), - }, -+ { /* Chuwi Vi8 dual-boot (CWI506) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"), -+ /* The above are too generic, also match BIOS info */ -+ DMI_MATCH(DMI_BIOS_VERSION, "CHUWI2.D86JHBNR02"), -+ }, -+ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | -+ BYT_RT5640_MONO_SPEAKER | -+ BYT_RT5640_SSP0_AIF1 | -+ BYT_RT5640_MCLK_EN), -+ }, - { - /* Chuwi Vi10 (CWI505) */ - .matches = { -diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c -index 88e611e64d14f..077b9c0b6c4ca 100644 ---- a/sound/soc/meson/aiu.c -+++ b/sound/soc/meson/aiu.c -@@ -218,11 +218,12 @@ static const char * const aiu_spdif_ids[] = { - static int aiu_clk_get(struct device *dev) - { - struct aiu *aiu = dev_get_drvdata(dev); -+ struct clk *pclk; - int ret; - -- aiu->pclk = devm_clk_get(dev, "pclk"); -- if (IS_ERR(aiu->pclk)) -- return dev_err_probe(dev, PTR_ERR(aiu->pclk), "Can't get the aiu pclk\n"); -+ pclk = devm_clk_get_enabled(dev, "pclk"); -+ if (IS_ERR(pclk)) -+ return dev_err_probe(dev, PTR_ERR(pclk), "Can't get the aiu pclk\n"); - - aiu->spdif_mclk = devm_clk_get(dev, "spdif_mclk"); - if (IS_ERR(aiu->spdif_mclk)) -@@ -239,18 +240,6 @@ static int aiu_clk_get(struct device *dev) - if (ret) - return dev_err_probe(dev, ret, "Can't get the spdif clocks\n"); - -- ret = clk_prepare_enable(aiu->pclk); -- if (ret) { -- dev_err(dev, "peripheral clock enable failed\n"); -- return ret; -- } -- -- ret = devm_add_action_or_reset(dev, -- (void(*)(void *))clk_disable_unprepare, -- aiu->pclk); -- if (ret) -- dev_err(dev, "failed to add reset action on pclk"); -- - return ret; - } - -diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h -index 393b6c2307e49..0f94c8bf60818 100644 ---- a/sound/soc/meson/aiu.h -+++ b/sound/soc/meson/aiu.h -@@ -33,7 +33,6 @@ struct aiu_platform_data { - }; - - struct aiu { -- struct clk *pclk; - struct clk *spdif_mclk; - struct aiu_interface i2s; - struct aiu_interface spdif; -diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c -index c040c83637e02..028383f949efd 100644 ---- a/sound/soc/meson/axg-tdm-interface.c -+++ b/sound/soc/meson/axg-tdm-interface.c -@@ -12,6 +12,9 @@ - - #include "axg-tdm.h" - -+/* Maximum bit clock frequency according the datasheets */ -+#define MAX_SCLK 100000000 /* Hz */ -+ - enum { - TDM_IFACE_PAD, - TDM_IFACE_LOOPBACK, -@@ -155,19 +158,27 @@ static int axg_tdm_iface_startup(struct snd_pcm_substream *substream, - return -EINVAL; - } - -- /* Apply component wide rate symmetry */ - if (snd_soc_component_active(dai->component)) { -+ /* Apply component wide rate symmetry */ - ret = snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - iface->rate); -- if (ret < 0) { -- dev_err(dai->dev, -- "can't set iface rate constraint\n"); -- return ret; -- } -+ -+ } else { -+ /* Limit rate according to the slot number and width */ -+ unsigned int max_rate = -+ MAX_SCLK / (iface->slots * iface->slot_width); -+ ret = snd_pcm_hw_constraint_minmax(substream->runtime, -+ SNDRV_PCM_HW_PARAM_RATE, -+ 0, max_rate); - } - -- return 0; -+ if (ret < 0) -+ dev_err(dai->dev, "can't set iface rate constraint\n"); -+ else -+ ret = 0; -+ -+ return ret; - } - - static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream, -@@ -266,8 +277,8 @@ static int axg_tdm_iface_set_sclk(struct snd_soc_dai *dai, - srate = iface->slots * iface->slot_width * params_rate(params); - - if (!iface->mclk_rate) { -- /* If no specific mclk is requested, default to bit clock * 4 */ -- clk_set_rate(iface->mclk, 4 * srate); -+ /* If no specific mclk is requested, default to bit clock * 2 */ -+ clk_set_rate(iface->mclk, 2 * srate); - } else { - /* Check if we can actually get the bit clock from mclk */ - if (iface->mclk_rate % srate) { -diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c -index 9c6b4dac68932..571f65788c592 100644 ---- a/sound/soc/meson/t9015.c -+++ b/sound/soc/meson/t9015.c -@@ -48,7 +48,6 @@ - #define POWER_CFG 0x10 - - struct t9015 { -- struct clk *pclk; - struct regulator *avdd; - }; - -@@ -249,6 +248,7 @@ static int t9015_probe(struct platform_device *pdev) - struct t9015 *priv; - void __iomem *regs; - struct regmap *regmap; -+ struct clk *pclk; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -256,26 +256,14 @@ static int t9015_probe(struct platform_device *pdev) - return -ENOMEM; - platform_set_drvdata(pdev, priv); - -- priv->pclk = devm_clk_get(dev, "pclk"); -- if (IS_ERR(priv->pclk)) -- return dev_err_probe(dev, PTR_ERR(priv->pclk), "failed to get core clock\n"); -+ pclk = devm_clk_get_enabled(dev, "pclk"); -+ if (IS_ERR(pclk)) -+ return dev_err_probe(dev, PTR_ERR(pclk), "failed to get core clock\n"); - - priv->avdd = devm_regulator_get(dev, "AVDD"); - if (IS_ERR(priv->avdd)) - return dev_err_probe(dev, PTR_ERR(priv->avdd), "failed to AVDD\n"); - -- ret = clk_prepare_enable(priv->pclk); -- if (ret) { -- dev_err(dev, "core clock enable failed\n"); -- return ret; -- } -- -- ret = devm_add_action_or_reset(dev, -- (void(*)(void *))clk_disable_unprepare, -- priv->pclk); -- if (ret) -- return ret; -- - ret = device_reset(dev); - if (ret) { - dev_err(dev, "reset failed\n"); -diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c -index 2550bd2a5e78c..2e36a97077b99 100644 ---- a/sound/soc/rockchip/rockchip_i2s_tdm.c -+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c -@@ -27,8 +27,6 @@ - #define DEFAULT_MCLK_FS 256 - #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ - #define MULTIPLEX_CH_MAX 10 --#define CLK_PPM_MIN -1000 --#define CLK_PPM_MAX 1000 - - #define TRCM_TXRX 0 - #define TRCM_TX 1 -@@ -55,20 +53,6 @@ struct rk_i2s_tdm_dev { - struct clk *hclk; - struct clk *mclk_tx; - struct clk *mclk_rx; -- /* The mclk_tx_src is parent of mclk_tx */ -- struct clk *mclk_tx_src; -- /* The mclk_rx_src is parent of mclk_rx */ -- struct clk *mclk_rx_src; -- /* -- * The mclk_root0 and mclk_root1 are root parent and supplies for -- * the different FS. -- * -- * e.g: -- * mclk_root0 is VPLL0, used for FS=48000Hz -- * mclk_root1 is VPLL1, used for FS=44100Hz -- */ -- struct clk *mclk_root0; -- struct clk *mclk_root1; - struct regmap *regmap; - struct regmap *grf; - struct snd_dmaengine_dai_dma_data capture_dma_data; -@@ -78,19 +62,11 @@ struct rk_i2s_tdm_dev { - struct rk_i2s_soc_data *soc_data; - bool is_master_mode; - bool io_multiplex; -- bool mclk_calibrate; - bool tdm_mode; -- unsigned int mclk_rx_freq; -- unsigned int mclk_tx_freq; -- unsigned int mclk_root0_freq; -- unsigned int mclk_root1_freq; -- unsigned int mclk_root0_initial_freq; -- unsigned int mclk_root1_initial_freq; - unsigned int frame_width; - unsigned int clk_trcm; - unsigned int i2s_sdis[CH_GRP_MAX]; - unsigned int i2s_sdos[CH_GRP_MAX]; -- int clk_ppm; - int refcount; - spinlock_t lock; /* xfer lock */ - bool has_playback; -@@ -116,12 +92,6 @@ static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev *i2s_tdm) - { - clk_disable_unprepare(i2s_tdm->mclk_tx); - clk_disable_unprepare(i2s_tdm->mclk_rx); -- if (i2s_tdm->mclk_calibrate) { -- clk_disable_unprepare(i2s_tdm->mclk_tx_src); -- clk_disable_unprepare(i2s_tdm->mclk_rx_src); -- clk_disable_unprepare(i2s_tdm->mclk_root0); -- clk_disable_unprepare(i2s_tdm->mclk_root1); -- } - } - - /** -@@ -144,29 +114,9 @@ static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev *i2s_tdm) - ret = clk_prepare_enable(i2s_tdm->mclk_rx); - if (ret) - goto err_mclk_rx; -- if (i2s_tdm->mclk_calibrate) { -- ret = clk_prepare_enable(i2s_tdm->mclk_tx_src); -- if (ret) -- goto err_mclk_rx; -- ret = clk_prepare_enable(i2s_tdm->mclk_rx_src); -- if (ret) -- goto err_mclk_rx_src; -- ret = clk_prepare_enable(i2s_tdm->mclk_root0); -- if (ret) -- goto err_mclk_root0; -- ret = clk_prepare_enable(i2s_tdm->mclk_root1); -- if (ret) -- goto err_mclk_root1; -- } - - return 0; - --err_mclk_root1: -- clk_disable_unprepare(i2s_tdm->mclk_root0); --err_mclk_root0: -- clk_disable_unprepare(i2s_tdm->mclk_rx_src); --err_mclk_rx_src: -- clk_disable_unprepare(i2s_tdm->mclk_tx_src); - err_mclk_rx: - clk_disable_unprepare(i2s_tdm->mclk_tx); - err_mclk_tx: -@@ -566,159 +516,6 @@ static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream, - I2S_XFER_RXS_START); - } - --static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm, -- struct clk *clk, unsigned long rate, -- int ppm) --{ -- unsigned long rate_target; -- int delta, ret; -- -- if (ppm == i2s_tdm->clk_ppm) -- return 0; -- -- if (ppm < 0) -- delta = -1; -- else -- delta = 1; -- -- delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000, -- 1000000); -- -- rate_target = rate + delta; -- -- if (!rate_target) -- return -EINVAL; -- -- ret = clk_set_rate(clk, rate_target); -- if (ret) -- return ret; -- -- i2s_tdm->clk_ppm = ppm; -- -- return 0; --} -- --static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm, -- struct snd_pcm_substream *substream, -- unsigned int lrck_freq) --{ -- struct clk *mclk_root; -- struct clk *mclk_parent; -- unsigned int mclk_root_freq; -- unsigned int mclk_root_initial_freq; -- unsigned int mclk_parent_freq; -- unsigned int div, delta; -- u64 ppm; -- int ret; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- mclk_parent = i2s_tdm->mclk_tx_src; -- else -- mclk_parent = i2s_tdm->mclk_rx_src; -- -- switch (lrck_freq) { -- case 8000: -- case 16000: -- case 24000: -- case 32000: -- case 48000: -- case 64000: -- case 96000: -- case 192000: -- mclk_root = i2s_tdm->mclk_root0; -- mclk_root_freq = i2s_tdm->mclk_root0_freq; -- mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq; -- mclk_parent_freq = DEFAULT_MCLK_FS * 192000; -- break; -- case 11025: -- case 22050: -- case 44100: -- case 88200: -- case 176400: -- mclk_root = i2s_tdm->mclk_root1; -- mclk_root_freq = i2s_tdm->mclk_root1_freq; -- mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq; -- mclk_parent_freq = DEFAULT_MCLK_FS * 176400; -- break; -- default: -- dev_err(i2s_tdm->dev, "Invalid LRCK frequency: %u Hz\n", -- lrck_freq); -- return -EINVAL; -- } -- -- ret = clk_set_parent(mclk_parent, mclk_root); -- if (ret) -- return ret; -- -- ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root, -- mclk_root_freq, 0); -- if (ret) -- return ret; -- -- delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq); -- ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq); -- -- if (ppm) { -- div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq); -- if (!div) -- return -EINVAL; -- -- mclk_root_freq = mclk_parent_freq * round_up(div, 2); -- -- ret = clk_set_rate(mclk_root, mclk_root_freq); -- if (ret) -- return ret; -- -- i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0); -- i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1); -- } -- -- return clk_set_rate(mclk_parent, mclk_parent_freq); --} -- --static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm, -- struct snd_pcm_substream *substream, -- struct clk **mclk) --{ -- unsigned int mclk_freq; -- int ret; -- -- if (i2s_tdm->clk_trcm) { -- if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) { -- dev_err(i2s_tdm->dev, -- "clk_trcm, tx: %d and rx: %d should be the same\n", -- i2s_tdm->mclk_tx_freq, -- i2s_tdm->mclk_rx_freq); -- return -EINVAL; -- } -- -- ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq); -- if (ret) -- return ret; -- -- ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq); -- if (ret) -- return ret; -- -- /* mclk_rx is also ok. */ -- *mclk = i2s_tdm->mclk_tx; -- } else { -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- *mclk = i2s_tdm->mclk_tx; -- mclk_freq = i2s_tdm->mclk_tx_freq; -- } else { -- *mclk = i2s_tdm->mclk_rx; -- mclk_freq = i2s_tdm->mclk_rx_freq; -- } -- -- ret = clk_set_rate(*mclk, mclk_freq); -- if (ret) -- return ret; -- } -- -- return 0; --} -- - static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture) - { - if (substream_capture) { -@@ -849,19 +646,17 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) - { - struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); -- struct clk *mclk; -- int ret = 0; - unsigned int val = 0; - unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64; -+ int err; - - if (i2s_tdm->is_master_mode) { -- if (i2s_tdm->mclk_calibrate) -- rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream, -- params_rate(params)); -+ struct clk *mclk = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ i2s_tdm->mclk_tx : i2s_tdm->mclk_rx; - -- ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk); -- if (ret) -- return ret; -+ err = clk_set_rate(mclk, DEFAULT_MCLK_FS * params_rate(params)); -+ if (err) -+ return err; - - mclk_rate = clk_get_rate(mclk); - bclk_rate = i2s_tdm->frame_width * params_rate(params); -@@ -969,96 +764,6 @@ static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream, - return 0; - } - --static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream, -- unsigned int freq, int dir) --{ -- struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai); -- -- /* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */ -- if (i2s_tdm->clk_trcm) { -- i2s_tdm->mclk_tx_freq = freq; -- i2s_tdm->mclk_rx_freq = freq; -- } else { -- if (stream == SNDRV_PCM_STREAM_PLAYBACK) -- i2s_tdm->mclk_tx_freq = freq; -- else -- i2s_tdm->mclk_rx_freq = freq; -- } -- -- dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n", -- stream ? "rx" : "tx", freq); -- -- return 0; --} -- --static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_info *uinfo) --{ -- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -- uinfo->count = 1; -- uinfo->value.integer.min = CLK_PPM_MIN; -- uinfo->value.integer.max = CLK_PPM_MAX; -- uinfo->value.integer.step = 1; -- -- return 0; --} -- --static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); -- struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); -- -- ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm; -- -- return 0; --} -- --static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); -- struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); -- int ret = 0, ppm = 0; -- int changed = 0; -- unsigned long old_rate; -- -- if (ucontrol->value.integer.value[0] < CLK_PPM_MIN || -- ucontrol->value.integer.value[0] > CLK_PPM_MAX) -- return -EINVAL; -- -- ppm = ucontrol->value.integer.value[0]; -- -- old_rate = clk_get_rate(i2s_tdm->mclk_root0); -- ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0, -- i2s_tdm->mclk_root0_freq, ppm); -- if (ret) -- return ret; -- if (old_rate != clk_get_rate(i2s_tdm->mclk_root0)) -- changed = 1; -- -- if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1)) -- return changed; -- -- old_rate = clk_get_rate(i2s_tdm->mclk_root1); -- ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1, -- i2s_tdm->mclk_root1_freq, ppm); -- if (ret) -- return ret; -- if (old_rate != clk_get_rate(i2s_tdm->mclk_root1)) -- changed = 1; -- -- return changed; --} -- --static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = { -- .iface = SNDRV_CTL_ELEM_IFACE_PCM, -- .name = "PCM Clock Compensation in PPM", -- .info = rockchip_i2s_tdm_clk_compensation_info, -- .get = rockchip_i2s_tdm_clk_compensation_get, -- .put = rockchip_i2s_tdm_clk_compensation_put, --}; -- - static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai) - { - struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); -@@ -1068,9 +773,6 @@ static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai) - if (i2s_tdm->has_playback) - dai->playback_dma_data = &i2s_tdm->playback_dma_data; - -- if (i2s_tdm->mclk_calibrate) -- snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1); -- - return 0; - } - -@@ -1110,7 +812,6 @@ static int rockchip_i2s_tdm_set_bclk_ratio(struct snd_soc_dai *dai, - static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { - .hw_params = rockchip_i2s_tdm_hw_params, - .set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio, -- .set_sysclk = rockchip_i2s_tdm_set_sysclk, - .set_fmt = rockchip_i2s_tdm_set_fmt, - .set_tdm_slot = rockchip_dai_tdm_slot, - .trigger = rockchip_i2s_tdm_trigger, -@@ -1433,35 +1134,6 @@ static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm, - rockchip_i2s_tdm_tx_path_config(i2s_tdm, num); - } - --static int rockchip_i2s_tdm_get_calibrate_mclks(struct rk_i2s_tdm_dev *i2s_tdm) --{ -- int num_mclks = 0; -- -- i2s_tdm->mclk_tx_src = devm_clk_get(i2s_tdm->dev, "mclk_tx_src"); -- if (!IS_ERR(i2s_tdm->mclk_tx_src)) -- num_mclks++; -- -- i2s_tdm->mclk_rx_src = devm_clk_get(i2s_tdm->dev, "mclk_rx_src"); -- if (!IS_ERR(i2s_tdm->mclk_rx_src)) -- num_mclks++; -- -- i2s_tdm->mclk_root0 = devm_clk_get(i2s_tdm->dev, "mclk_root0"); -- if (!IS_ERR(i2s_tdm->mclk_root0)) -- num_mclks++; -- -- i2s_tdm->mclk_root1 = devm_clk_get(i2s_tdm->dev, "mclk_root1"); -- if (!IS_ERR(i2s_tdm->mclk_root1)) -- num_mclks++; -- -- if (num_mclks < 4 && num_mclks != 0) -- return -ENOENT; -- -- if (num_mclks == 4) -- i2s_tdm->mclk_calibrate = 1; -- -- return 0; --} -- - static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm, - struct device_node *np, - bool is_rx_path) -@@ -1609,11 +1281,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) - i2s_tdm->io_multiplex = - of_property_read_bool(node, "rockchip,io-multiplex"); - -- ret = rockchip_i2s_tdm_get_calibrate_mclks(i2s_tdm); -- if (ret) -- return dev_err_probe(i2s_tdm->dev, ret, -- "mclk-calibrate clocks missing"); -- - regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(regs)) { - return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs), -@@ -1666,13 +1333,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev) - goto err_disable_hclk; - } - -- if (i2s_tdm->mclk_calibrate) { -- i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0); -- i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1); -- i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq; -- i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq; -- } -- - pm_runtime_enable(&pdev->dev); - - regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, -diff --git a/sound/soc/sof/ipc3-loader.c b/sound/soc/sof/ipc3-loader.c -index bf423ca4e97bb..6e3ef06721106 100644 ---- a/sound/soc/sof/ipc3-loader.c -+++ b/sound/soc/sof/ipc3-loader.c -@@ -138,8 +138,7 @@ static ssize_t ipc3_fw_ext_man_size(struct snd_sof_dev *sdev, const struct firmw - - static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev) - { -- struct snd_sof_pdata *plat_data = sdev->pdata; -- const struct firmware *fw = plat_data->fw; -+ const struct firmware *fw = sdev->basefw.fw; - const struct sof_ext_man_elem_header *elem_hdr; - const struct sof_ext_man_header *head; - ssize_t ext_man_size; -@@ -149,6 +148,8 @@ static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev) - - head = (struct sof_ext_man_header *)fw->data; - remaining = head->full_size - head->header_size; -+ if (remaining < 0 || remaining > sdev->basefw.fw->size) -+ return -EINVAL; - ext_man_size = ipc3_fw_ext_man_size(sdev, fw); - - /* Assert firmware starts with extended manifest */ -@@ -310,18 +311,18 @@ static int sof_ipc3_parse_module_memcpy(struct snd_sof_dev *sdev, - - static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev) - { -- struct snd_sof_pdata *plat_data = sdev->pdata; -- const struct firmware *fw = plat_data->fw; -+ u32 payload_offset = sdev->basefw.payload_offset; -+ const struct firmware *fw = sdev->basefw.fw; - struct snd_sof_fw_header *header; - struct snd_sof_mod_hdr *module; - int (*load_module)(struct snd_sof_dev *sof_dev, struct snd_sof_mod_hdr *hdr); - size_t remaining; - int ret, count; - -- if (!plat_data->fw) -+ if (!fw) - return -EINVAL; - -- header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset); -+ header = (struct snd_sof_fw_header *)(fw->data + payload_offset); - load_module = sof_ops(sdev)->load_module; - if (!load_module) { - dev_dbg(sdev->dev, "Using generic module loading\n"); -@@ -331,9 +332,8 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev) - } - - /* parse each module */ -- module = (struct snd_sof_mod_hdr *)(fw->data + plat_data->fw_offset + -- sizeof(*header)); -- remaining = fw->size - sizeof(*header) - plat_data->fw_offset; -+ module = (struct snd_sof_mod_hdr *)(fw->data + payload_offset + sizeof(*header)); -+ remaining = fw->size - sizeof(*header) - payload_offset; - /* check for wrap */ - if (remaining > fw->size) { - dev_err(sdev->dev, "%s: fw size smaller than header size\n", __func__); -@@ -374,19 +374,19 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev) - - static int sof_ipc3_validate_firmware(struct snd_sof_dev *sdev) - { -- struct snd_sof_pdata *plat_data = sdev->pdata; -- const struct firmware *fw = plat_data->fw; -+ u32 payload_offset = sdev->basefw.payload_offset; -+ const struct firmware *fw = sdev->basefw.fw; - struct snd_sof_fw_header *header; -- size_t fw_size = fw->size - plat_data->fw_offset; -+ size_t fw_size = fw->size - payload_offset; - -- if (fw->size <= plat_data->fw_offset) { -+ if (fw->size <= payload_offset) { - dev_err(sdev->dev, - "firmware size must be greater than firmware offset\n"); - return -EINVAL; - } - - /* Read the header information from the data pointer */ -- header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset); -+ header = (struct snd_sof_fw_header *)(fw->data + payload_offset); - - /* verify FW sig */ - if (strncmp(header->sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE) != 0) { -diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c -index e635ae515fa9f..9f433e9b4cd37 100644 ---- a/sound/soc/sof/ipc4-loader.c -+++ b/sound/soc/sof/ipc4-loader.c -@@ -17,9 +17,8 @@ - static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev) - { - struct sof_ipc4_fw_data *ipc4_data = sdev->private; -- struct snd_sof_pdata *plat_data = sdev->pdata; - struct sof_man4_fw_binary_header *fw_header; -- const struct firmware *fw = plat_data->fw; -+ const struct firmware *fw = sdev->basefw.fw; - struct sof_ext_manifest4_hdr *ext_man_hdr; - struct sof_man4_module_config *fm_config; - struct sof_ipc4_fw_module *fw_module; -@@ -138,9 +137,8 @@ static int sof_ipc4_validate_firmware(struct snd_sof_dev *sdev) - { - struct sof_ipc4_fw_data *ipc4_data = sdev->private; - u32 fw_hdr_offset = ipc4_data->manifest_fw_hdr_offset; -- struct snd_sof_pdata *plat_data = sdev->pdata; - struct sof_man4_fw_binary_header *fw_header; -- const struct firmware *fw = plat_data->fw; -+ const struct firmware *fw = sdev->basefw.fw; - struct sof_ext_manifest4_hdr *ext_man_hdr; - - ext_man_hdr = (struct sof_ext_manifest4_hdr *)fw->data; -diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c -index 5f51d936b3067..ba8e3aae0a5cb 100644 ---- a/sound/soc/sof/loader.c -+++ b/sound/soc/sof/loader.c -@@ -22,7 +22,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) - int ret; - - /* Don't request firmware again if firmware is already requested */ -- if (plat_data->fw) -+ if (sdev->basefw.fw) - return 0; - - fw_filename = kasprintf(GFP_KERNEL, "%s/%s", -@@ -31,7 +31,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) - if (!fw_filename) - return -ENOMEM; - -- ret = request_firmware(&plat_data->fw, fw_filename, sdev->dev); -+ ret = request_firmware(&sdev->basefw.fw, fw_filename, sdev->dev); - - if (ret < 0) { - dev_err(sdev->dev, -@@ -48,7 +48,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) - ext_man_size = sdev->ipc->ops->fw_loader->parse_ext_manifest(sdev); - if (ext_man_size > 0) { - /* when no error occurred, drop extended manifest */ -- plat_data->fw_offset = ext_man_size; -+ sdev->basefw.payload_offset = ext_man_size; - } else if (!ext_man_size) { - /* No extended manifest, so nothing to skip during FW load */ - dev_dbg(sdev->dev, "firmware doesn't contain extended manifest\n"); -@@ -58,6 +58,12 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) - fw_filename, ret); - } - -+ /* -+ * Until the platform code is switched to use the new container the fw -+ * and payload offset must be set in plat_data -+ */ -+ plat_data->fw = sdev->basefw.fw; -+ plat_data->fw_offset = sdev->basefw.payload_offset; - err: - kfree(fw_filename); - -@@ -100,7 +106,8 @@ int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev) - return 0; - - error: -- release_firmware(plat_data->fw); -+ release_firmware(sdev->basefw.fw); -+ sdev->basefw.fw = NULL; - plat_data->fw = NULL; - return ret; - -@@ -185,7 +192,8 @@ EXPORT_SYMBOL(snd_sof_run_firmware); - void snd_sof_fw_unload(struct snd_sof_dev *sdev) - { - /* TODO: support module unloading at runtime */ -- release_firmware(sdev->pdata->fw); -+ release_firmware(sdev->basefw.fw); -+ sdev->basefw.fw = NULL; - sdev->pdata->fw = NULL; - } - EXPORT_SYMBOL(snd_sof_fw_unload); -diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h -index de08825915b35..3d70b57e4864d 100644 ---- a/sound/soc/sof/sof-priv.h -+++ b/sound/soc/sof/sof-priv.h -@@ -136,6 +136,17 @@ struct snd_sof_platform_stream_params { - bool cont_update_posn; - }; - -+/** -+ * struct sof_firmware - Container struct for SOF firmware -+ * @fw: Pointer to the firmware -+ * @payload_offset: Offset of the data within the loaded firmware image to be -+ * loaded to the DSP (skipping for example ext_manifest section) -+ */ -+struct sof_firmware { -+ const struct firmware *fw; -+ u32 payload_offset; -+}; -+ - /* - * SOF DSP HW abstraction operations. - * Used to abstract DSP HW architecture and any IO busses between host CPU -@@ -487,6 +498,9 @@ struct snd_sof_dev { - spinlock_t ipc_lock; /* lock for IPC users */ - spinlock_t hw_lock; /* lock for HW IO access */ - -+ /* Main, Base firmware image */ -+ struct sof_firmware basefw; -+ - /* - * ASoC components. plat_drv fields are set dynamically so - * can't use const -diff --git a/sound/usb/stream.c b/sound/usb/stream.c -index 3d4add94e367d..d5409f3879455 100644 ---- a/sound/usb/stream.c -+++ b/sound/usb/stream.c -@@ -300,9 +300,12 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, - c = 0; - - if (bits) { -- for (; bits && *maps; maps++, bits >>= 1) -+ for (; bits && *maps; maps++, bits >>= 1) { - if (bits & 1) - chmap->map[c++] = *maps; -+ if (c == chmap->channels) -+ break; -+ } - } else { - /* If we're missing wChannelConfig, then guess something - to make sure the channel map is not skipped entirely */ -diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c -index 41c02b6f6f043..7e0b846e17eef 100644 ---- a/tools/bpf/bpftool/prog.c -+++ b/tools/bpf/bpftool/prog.c -@@ -2200,7 +2200,7 @@ static int profile_open_perf_events(struct profiler_bpf *obj) - int map_fd; - - profile_perf_events = calloc( -- sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric); -+ obj->rodata->num_cpu * obj->rodata->num_metric, sizeof(int)); - if (!profile_perf_events) { - p_err("failed to allocate memory for perf_event array: %s", - strerror(errno)); -diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c -index 77058174082d7..ef0764d6891e4 100644 ---- a/tools/bpf/resolve_btfids/main.c -+++ b/tools/bpf/resolve_btfids/main.c -@@ -70,6 +70,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -78,7 +79,7 @@ - #include - - #define BTF_IDS_SECTION ".BTF_ids" --#define BTF_ID "__BTF_ID__" -+#define BTF_ID_PREFIX "__BTF_ID__" - - #define BTF_STRUCT "struct" - #define BTF_UNION "union" -@@ -89,6 +90,14 @@ - - #define ADDR_CNT 100 - -+#if __BYTE_ORDER == __LITTLE_ENDIAN -+# define ELFDATANATIVE ELFDATA2LSB -+#elif __BYTE_ORDER == __BIG_ENDIAN -+# define ELFDATANATIVE ELFDATA2MSB -+#else -+# error "Unknown machine endianness!" -+#endif -+ - struct btf_id { - struct rb_node rb_node; - char *name; -@@ -116,6 +125,7 @@ struct object { - int idlist_shndx; - size_t strtabidx; - unsigned long idlist_addr; -+ int encoding; - } efile; - - struct rb_root sets; -@@ -161,7 +171,7 @@ static int eprintf(int level, int var, const char *fmt, ...) - - static bool is_btf_id(const char *name) - { -- return name && !strncmp(name, BTF_ID, sizeof(BTF_ID) - 1); -+ return name && !strncmp(name, BTF_ID_PREFIX, sizeof(BTF_ID_PREFIX) - 1); - } - - static struct btf_id *btf_id__find(struct rb_root *root, const char *name) -@@ -319,6 +329,7 @@ static int elf_collect(struct object *obj) - { - Elf_Scn *scn = NULL; - size_t shdrstrndx; -+ GElf_Ehdr ehdr; - int idx = 0; - Elf *elf; - int fd; -@@ -350,6 +361,13 @@ static int elf_collect(struct object *obj) - return -1; - } - -+ if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) { -+ pr_err("FAILED cannot get ELF header: %s\n", -+ elf_errmsg(-1)); -+ return -1; -+ } -+ obj->efile.encoding = ehdr.e_ident[EI_DATA]; -+ - /* - * Scan all the elf sections and look for save data - * from .BTF_ids section and symbols. -@@ -441,7 +459,7 @@ static int symbols_collect(struct object *obj) - * __BTF_ID__TYPE__vfs_truncate__0 - * prefix = ^ - */ -- prefix = name + sizeof(BTF_ID) - 1; -+ prefix = name + sizeof(BTF_ID_PREFIX) - 1; - - /* struct */ - if (!strncmp(prefix, BTF_STRUCT, sizeof(BTF_STRUCT) - 1)) { -@@ -649,19 +667,18 @@ static int cmp_id(const void *pa, const void *pb) - static int sets_patch(struct object *obj) - { - Elf_Data *data = obj->efile.idlist; -- int *ptr = data->d_buf; - struct rb_node *next; - - next = rb_first(&obj->sets); - while (next) { -- unsigned long addr, idx; -+ struct btf_id_set8 *set8; -+ struct btf_id_set *set; -+ unsigned long addr, off; - struct btf_id *id; -- int *base; -- int cnt; - - id = rb_entry(next, struct btf_id, rb_node); - addr = id->addr[0]; -- idx = addr - obj->efile.idlist_addr; -+ off = addr - obj->efile.idlist_addr; - - /* sets are unique */ - if (id->addr_cnt != 1) { -@@ -670,14 +687,39 @@ static int sets_patch(struct object *obj) - return -1; - } - -- idx = idx / sizeof(int); -- base = &ptr[idx] + (id->is_set8 ? 2 : 1); -- cnt = ptr[idx]; -+ if (id->is_set) { -+ set = data->d_buf + off; -+ qsort(set->ids, set->cnt, sizeof(set->ids[0]), cmp_id); -+ } else { -+ set8 = data->d_buf + off; -+ /* -+ * Make sure id is at the beginning of the pairs -+ * struct, otherwise the below qsort would not work. -+ */ -+ BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id); -+ qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id); - -- pr_debug("sorting addr %5lu: cnt %6d [%s]\n", -- (idx + 1) * sizeof(int), cnt, id->name); -+ /* -+ * When ELF endianness does not match endianness of the -+ * host, libelf will do the translation when updating -+ * the ELF. This, however, corrupts SET8 flags which are -+ * already in the target endianness. So, let's bswap -+ * them to the host endianness and libelf will then -+ * correctly translate everything. -+ */ -+ if (obj->efile.encoding != ELFDATANATIVE) { -+ int i; -+ -+ set8->flags = bswap_32(set8->flags); -+ for (i = 0; i < set8->cnt; i++) { -+ set8->pairs[i].flags = -+ bswap_32(set8->pairs[i].flags); -+ } -+ } -+ } - -- qsort(base, cnt, id->is_set8 ? sizeof(uint64_t) : sizeof(int), cmp_id); -+ pr_debug("sorting addr %5lu: cnt %6d [%s]\n", -+ off, id->is_set ? set->cnt : set8->cnt, id->name); - - next = rb_next(next); - } -diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h -index 2f882d5cb30f5..72535f00572f6 100644 ---- a/tools/include/linux/btf_ids.h -+++ b/tools/include/linux/btf_ids.h -@@ -8,6 +8,15 @@ struct btf_id_set { - u32 ids[]; - }; - -+struct btf_id_set8 { -+ u32 cnt; -+ u32 flags; -+ struct { -+ u32 id; -+ u32 flags; -+ } pairs[]; -+}; -+ - #ifdef CONFIG_DEBUG_INFO_BTF - - #include /* for __PASTE */ -diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h -index fddc05c667b5d..874fe362375de 100644 ---- a/tools/lib/bpf/bpf.h -+++ b/tools/lib/bpf/bpf.h -@@ -35,7 +35,7 @@ - extern "C" { - #endif - --int libbpf_set_memlock_rlim(size_t memlock_bytes); -+LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes); - - struct bpf_map_create_opts { - size_t sz; /* size of this struct for forward/backward compatibility */ -diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c -index e2014b1250ea2..c71d4d0f5c6f3 100644 ---- a/tools/lib/bpf/libbpf.c -+++ b/tools/lib/bpf/libbpf.c -@@ -70,6 +70,7 @@ - - static struct bpf_map *bpf_object__add_map(struct bpf_object *obj); - static bool prog_is_subprog(const struct bpf_object *obj, const struct bpf_program *prog); -+static int map_set_def_max_entries(struct bpf_map *map); - - static const char * const attach_type_name[] = { - [BPF_CGROUP_INET_INGRESS] = "cgroup_inet_ingress", -@@ -4992,6 +4993,9 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b - - if (bpf_map_type__is_map_in_map(def->type)) { - if (map->inner_map) { -+ err = map_set_def_max_entries(map->inner_map); -+ if (err) -+ return err; - err = bpf_object__create_map(obj, map->inner_map, true); - if (err) { - pr_warn("map '%s': failed to create inner map: %d\n", -diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h -index 377642ff51fce..8669f6e0f6e2f 100644 ---- a/tools/lib/bpf/libbpf_internal.h -+++ b/tools/lib/bpf/libbpf_internal.h -@@ -17,6 +17,20 @@ - #include - #include "relo_core.h" - -+/* Android's libc doesn't support AT_EACCESS in faccessat() implementation -+ * ([0]), and just returns -EINVAL even if file exists and is accessible. -+ * See [1] for issues caused by this. -+ * -+ * So just redefine it to 0 on Android. -+ * -+ * [0] https://android.googlesource.com/platform/bionic/+/refs/heads/android13-release/libc/bionic/faccessat.cpp#50 -+ * [1] https://github.com/libbpf/libbpf-bootstrap/issues/250#issuecomment-1911324250 -+ */ -+#ifdef __ANDROID__ -+#undef AT_EACCESS -+#define AT_EACCESS 0 -+#endif -+ - /* make sure libbpf doesn't use kernel-only integer typedefs */ - #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64 - -diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c -index 7314183cdcb6c..b9b0fda8374e2 100644 ---- a/tools/perf/builtin-record.c -+++ b/tools/perf/builtin-record.c -@@ -1785,8 +1785,8 @@ static int - record__switch_output(struct record *rec, bool at_exit) - { - struct perf_data *data = &rec->data; -+ char *new_filename = NULL; - int fd, err; -- char *new_filename; - - /* Same Size: "2015122520103046"*/ - char timestamp[] = "InvalidTimestamp"; -diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c -index 76605fde35078..7db35dbdfcefe 100644 ---- a/tools/perf/util/evsel.c -+++ b/tools/perf/util/evsel.c -@@ -2375,7 +2375,6 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event, - data->period = evsel->core.attr.sample_period; - data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - data->misc = event->header.misc; -- data->id = -1ULL; - data->data_src = PERF_MEM_DATA_SRC_NONE; - data->vcpu = -1; - -diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c -index bc866d18973e4..ef9a3df459657 100644 ---- a/tools/perf/util/stat-display.c -+++ b/tools/perf/util/stat-display.c -@@ -366,7 +366,7 @@ static void print_metric_only(struct perf_stat_config *config, - if (color) - mlen += strlen(color) + sizeof(PERF_COLOR_RESET) - 1; - -- color_snprintf(str, sizeof(str), color ?: "", fmt, val); -+ color_snprintf(str, sizeof(str), color ?: "", fmt ?: "", val); - fprintf(out, "%*s ", mlen, str); - } - -diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c -index c9bfe4696943b..cee7fc3b5bb0c 100644 ---- a/tools/perf/util/thread_map.c -+++ b/tools/perf/util/thread_map.c -@@ -279,13 +279,13 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) - threads->nr = ntasks; - } - out: -+ strlist__delete(slist); - if (threads) - refcount_set(&threads->refcnt, 1); - return threads; - - out_free_threads: - zfree(&threads); -- strlist__delete(slist); - goto out; - } - -diff --git a/tools/testing/selftests/bpf/progs/test_map_in_map.c b/tools/testing/selftests/bpf/progs/test_map_in_map.c -index f416032ba858b..b295f9b721bf8 100644 ---- a/tools/testing/selftests/bpf/progs/test_map_in_map.c -+++ b/tools/testing/selftests/bpf/progs/test_map_in_map.c -@@ -21,6 +21,32 @@ struct { - __type(value, __u32); - } mim_hash SEC(".maps"); - -+/* The following three maps are used to test -+ * perf_event_array map can be an inner -+ * map of hash/array_of_maps. -+ */ -+struct perf_event_array { -+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); -+ __type(key, __u32); -+ __type(value, __u32); -+} inner_map0 SEC(".maps"); -+ -+struct { -+ __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); -+ __uint(max_entries, 1); -+ __type(key, __u32); -+ __array(values, struct perf_event_array); -+} mim_array_pe SEC(".maps") = { -+ .values = {&inner_map0}}; -+ -+struct { -+ __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); -+ __uint(max_entries, 1); -+ __type(key, __u32); -+ __array(values, struct perf_event_array); -+} mim_hash_pe SEC(".maps") = { -+ .values = {&inner_map0}}; -+ - SEC("xdp") - int xdp_mimtest0(struct xdp_md *ctx) - { -diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c -index b73152822aa28..81cd48cc80c23 100644 ---- a/tools/testing/selftests/bpf/test_maps.c -+++ b/tools/testing/selftests/bpf/test_maps.c -@@ -1190,7 +1190,11 @@ static void test_map_in_map(void) - goto out_map_in_map; - } - -- bpf_object__load(obj); -+ err = bpf_object__load(obj); -+ if (err) { -+ printf("Failed to load test prog\n"); -+ goto out_map_in_map; -+ } - - map = bpf_object__find_map_by_name(obj, "mim_array"); - if (!map) { -diff --git a/tools/testing/selftests/net/forwarding/config b/tools/testing/selftests/net/forwarding/config -index 697994a9278bb..8d7a1a004b7c3 100644 ---- a/tools/testing/selftests/net/forwarding/config -+++ b/tools/testing/selftests/net/forwarding/config -@@ -6,14 +6,49 @@ CONFIG_IPV6_MULTIPLE_TABLES=y - CONFIG_NET_VRF=m - CONFIG_BPF_SYSCALL=y - CONFIG_CGROUP_BPF=y -+CONFIG_DUMMY=m -+CONFIG_IPV6=y -+CONFIG_IPV6_GRE=m -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_MACVLAN=m - CONFIG_NET_ACT_CT=m - CONFIG_NET_ACT_MIRRED=m - CONFIG_NET_ACT_MPLS=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_SAMPLE=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_TUNNEL_KEY=m - CONFIG_NET_ACT_VLAN=m - CONFIG_NET_CLS_FLOWER=m - CONFIG_NET_CLS_MATCHALL=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_IPGRE=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPIP=m -+CONFIG_NET_SCH_ETS=m - CONFIG_NET_SCH_INGRESS=m - CONFIG_NET_ACT_GACT=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_TC_SKB_EXT=y -+CONFIG_NET_TEAM=y -+CONFIG_NET_TEAM_MODE_LOADBALANCE=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_FLOW_TABLE=m -+CONFIG_NF_TABLES=m - CONFIG_VETH=m - CONFIG_NAMESPACES=y - CONFIG_NET_NS=y -+CONFIG_VXLAN=m -+CONFIG_XFRM_USER=m -diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh -index ac97f07e5ce82..bd3f7d492af2b 100755 ---- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh -+++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh -@@ -354,7 +354,7 @@ __ping_ipv4() - - # Send 100 packets and verify that at least 100 packets hit the rule, - # to overcome ARP noise. -- PING_COUNT=100 PING_TIMEOUT=11 ping_do $dev $dst_ip -+ PING_COUNT=100 PING_TIMEOUT=20 ping_do $dev $dst_ip - check_err $? "Ping failed" - - tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100 -@@ -410,7 +410,7 @@ __ping_ipv6() - - # Send 100 packets and verify that at least 100 packets hit the rule, - # to overcome neighbor discovery noise. -- PING_COUNT=100 PING_TIMEOUT=11 ping6_do $dev $dst_ip -+ PING_COUNT=100 PING_TIMEOUT=20 ping6_do $dev $dst_ip - check_err $? "Ping failed" - - tc_check_at_least_x_packets "dev $rp1 egress" 101 100 -diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh -index d880df89bc8bd..e83fde79f40d0 100755 ---- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh -+++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh -@@ -457,7 +457,7 @@ __ping_ipv4() - - # Send 100 packets and verify that at least 100 packets hit the rule, - # to overcome ARP noise. -- PING_COUNT=100 PING_TIMEOUT=11 ping_do $dev $dst_ip -+ PING_COUNT=100 PING_TIMEOUT=20 ping_do $dev $dst_ip - check_err $? "Ping failed" - - tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100 -@@ -522,7 +522,7 @@ __ping_ipv6() - - # Send 100 packets and verify that at least 100 packets hit the rule, - # to overcome neighbor discovery noise. -- PING_COUNT=100 PING_TIMEOUT=11 ping6_do $dev $dst_ip -+ PING_COUNT=100 PING_TIMEOUT=20 ping6_do $dev $dst_ip - check_err $? "Ping failed" - - tc_check_at_least_x_packets "dev $rp1 egress" 101 100 -diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c -index 5b80fb155d549..d89ee6e1926c7 100644 ---- a/tools/testing/selftests/net/tls.c -+++ b/tools/testing/selftests/net/tls.c -@@ -926,12 +926,12 @@ TEST_F(tls, recv_partial) - - memset(recv_mem, 0, sizeof(recv_mem)); - EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); -- EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first), -- MSG_WAITALL), -1); -+ EXPECT_EQ(recv(self->cfd, recv_mem, strlen(test_str_first), -+ MSG_WAITALL), strlen(test_str_first)); - EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0); - memset(recv_mem, 0, sizeof(recv_mem)); -- EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second), -- MSG_WAITALL), -1); -+ EXPECT_EQ(recv(self->cfd, recv_mem, strlen(test_str_second), -+ MSG_WAITALL), strlen(test_str_second)); - EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)), - 0); - } diff --git a/patch/kernel/odroidxu4-current/patch-6.6.13-14.patch b/patch/kernel/odroidxu4-current/patch-6.6.13-14.patch new file mode 100644 index 0000000000..3fc775822a --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-6.6.13-14.patch @@ -0,0 +1,22054 @@ +diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml +index adbfaea323435..90f31beb80c22 100644 +--- a/Documentation/devicetree/bindings/arm/qcom.yaml ++++ b/Documentation/devicetree/bindings/arm/qcom.yaml +@@ -136,7 +136,7 @@ description: | + There are many devices in the list below that run the standard ChromeOS + bootloader setup and use the open source depthcharge bootloader to boot the + OS. These devices do not use the scheme described above. For details, see: +- https://docs.kernel.org/arm/google/chromebook-boot-flow.html ++ https://docs.kernel.org/arch/arm/google/chromebook-boot-flow.html + + properties: + $nodename: +diff --git a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml +index c1060e5fcef3a..d3d8a2e143ed2 100644 +--- a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml ++++ b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml +@@ -126,7 +126,7 @@ examples: + - | + #include + +- gpio@e000a000 { ++ gpio@a0020000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0xa0020000 0x10000>; + #gpio-cells = <2>; +diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +index 7032c7e150390..3e128733ef535 100644 +--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml ++++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +@@ -61,6 +61,9 @@ properties: + - description: used for 1st data pipe from RDMA + - description: used for 2nd data pipe from RDMA + ++ '#dma-cells': ++ const: 1 ++ + required: + - compatible + - reg +@@ -70,6 +73,7 @@ required: + - clocks + - iommus + - mboxes ++ - '#dma-cells' + + additionalProperties: false + +@@ -80,16 +84,17 @@ examples: + #include + #include + +- mdp3_rdma0: mdp3-rdma0@14001000 { +- compatible = "mediatek,mt8183-mdp3-rdma"; +- reg = <0x14001000 0x1000>; +- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; +- mediatek,gce-events = , +- ; +- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; +- clocks = <&mmsys CLK_MM_MDP_RDMA0>, +- <&mmsys CLK_MM_MDP_RSZ1>; +- iommus = <&iommu>; +- mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, +- <&gce 21 CMDQ_THR_PRIO_LOWEST>; ++ dma-controller@14001000 { ++ compatible = "mediatek,mt8183-mdp3-rdma"; ++ reg = <0x14001000 0x1000>; ++ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; ++ mediatek,gce-events = , ++ ; ++ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; ++ clocks = <&mmsys CLK_MM_MDP_RDMA0>, ++ <&mmsys CLK_MM_MDP_RSZ1>; ++ iommus = <&iommu>; ++ mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, ++ <&gce 21 CMDQ_THR_PRIO_LOWEST>; ++ #dma-cells = <1>; + }; +diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml +index 0baa77198fa21..64ea98aa05928 100644 +--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml ++++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml +@@ -50,6 +50,9 @@ properties: + iommus: + maxItems: 1 + ++ '#dma-cells': ++ const: 1 ++ + required: + - compatible + - reg +@@ -58,6 +61,7 @@ required: + - power-domains + - clocks + - iommus ++ - '#dma-cells' + + additionalProperties: false + +@@ -68,13 +72,14 @@ examples: + #include + #include + +- mdp3_wrot0: mdp3-wrot0@14005000 { +- compatible = "mediatek,mt8183-mdp3-wrot"; +- reg = <0x14005000 0x1000>; +- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; +- mediatek,gce-events = , +- ; +- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; +- clocks = <&mmsys CLK_MM_MDP_WROT0>; +- iommus = <&iommu>; ++ dma-controller@14005000 { ++ compatible = "mediatek,mt8183-mdp3-wrot"; ++ reg = <0x14005000 0x1000>; ++ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; ++ mediatek,gce-events = , ++ ; ++ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; ++ clocks = <&mmsys CLK_MM_MDP_WROT0>; ++ iommus = <&iommu>; ++ #dma-cells = <1>; + }; +diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +index e466dff8286d2..afcaa427d48b0 100644 +--- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml ++++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +@@ -90,15 +90,16 @@ properties: + description: connection point for input on the parallel interface + + properties: +- bus-type: +- enum: [5, 6] +- + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + +- required: +- - bus-type ++ properties: ++ bus-type: ++ enum: [5, 6] ++ ++ required: ++ - bus-type + + anyOf: + - required: +diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +index 9af203dc8793f..fa7408eb74895 100644 +--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml ++++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +@@ -62,12 +62,12 @@ properties: + "#clock-cells": + const: 1 + description: +- See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h ++ See include/dt-bindings/phy/phy-qcom-qmp.h + + "#phy-cells": + const: 1 + description: +- See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h ++ See include/dt-bindings/phy/phy-qcom-qmp.h + + orientation-switch: + description: +diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst +index 44deb52beeb47..d0b241628cf13 100644 +--- a/Documentation/driver-api/pci/p2pdma.rst ++++ b/Documentation/driver-api/pci/p2pdma.rst +@@ -83,19 +83,9 @@ this to include other types of resources like doorbells. + Client Drivers + -------------- + +-A client driver typically only has to conditionally change its DMA map +-routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead +-of the usual :c:func:`dma_map_sg()` function. Memory mapped in this +-way does not need to be unmapped. +- +-The client may also, optionally, make use of +-:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping +-functions and when to use the regular mapping functions. In some +-situations, it may be more appropriate to use a flag to indicate a +-given request is P2P memory and map appropriately. It is important to +-ensure that struct pages that back P2P memory stay out of code that +-does not have support for them as other code may treat the pages as +-regular memory which may not be appropriate. ++A client driver only has to use the mapping API :c:func:`dma_map_sg()` ++and :c:func:`dma_unmap_sg()` functions as usual, and the implementation ++will do the right thing for the P2P capable memory. + + + Orchestrator Drivers +diff --git a/Makefile b/Makefile +index a4a2932a43185..bad16eda67e2e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 13 ++SUBLEVEL = 14 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi +index 516f0d2495e2d..950adb63af701 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi +@@ -738,7 +738,7 @@ + + xoadc: xoadc@197 { + compatible = "qcom,pm8921-adc"; +- reg = <197>; ++ reg = <0x197>; + interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>; + #address-cells = <2>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi +index 44f3f0127fd70..78738371f634c 100644 +--- a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi +@@ -404,8 +404,8 @@ + <&gcc GPLL0_VOTE>, + <&gcc GPLL1_VOTE>, + <&rpmcc RPM_SMD_GFX3D_CLK_SRC>, +- <0>, +- <0>; ++ <&mdss_dsi0_phy 1>, ++ <&mdss_dsi0_phy 0>; + clock-names = "xo", + "mmss_gpll0_vote", + "gpll0_vote", +diff --git a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi +index 1a3583029a649..271899c861c01 100644 +--- a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi +@@ -338,7 +338,7 @@ + power-domains = <&gcc PCIE_GDSC>; + + phys = <&pcie_phy>; +- phy-names = "pcie-phy"; ++ phy-names = "pciephy"; + + max-link-speed = <3>; + num-lanes = <2>; +@@ -530,7 +530,7 @@ + reg = <0x0c264000 0x1000>; + }; + +- spmi_bus: qcom,spmi@c440000 { ++ spmi_bus: spmi@c440000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0xc440000 0xd00>, + <0xc600000 0x2000000>, +diff --git a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts +index afcd6285890cc..c27963898b5e6 100644 +--- a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts ++++ b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; +- compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157a-dk1", "st,stm32mp157"; ++ compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157"; + + reserved-memory { + optee@de000000 { +diff --git a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts +index 39358d9020003..6226189431340 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts ++++ b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; +- compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157c-dk2", "st,stm32mp157"; ++ compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157"; + + reserved-memory { + optee@de000000 { +diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts +index 07ea765a4553a..c7c4d7e89d612 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts ++++ b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts +@@ -11,7 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; +- compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; ++ compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157"; + + reserved-memory { + optee@fe000000 { +diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts +index 813086ec24895..2ab77e64f1bbb 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts ++++ b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts +@@ -11,8 +11,7 @@ + + / { + model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; +- compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", +- "st,stm32mp157"; ++ compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; + + reserved-memory { + optee@fe000000 { +diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig +index 4316e1370627c..2a8a9fe46586d 100644 +--- a/arch/arm/mach-davinci/Kconfig ++++ b/arch/arm/mach-davinci/Kconfig +@@ -4,12 +4,14 @@ menuconfig ARCH_DAVINCI + bool "TI DaVinci" + depends on ARCH_MULTI_V5 + depends on CPU_LITTLE_ENDIAN ++ select CPU_ARM926T + select DAVINCI_TIMER + select ZONE_DMA + select PM_GENERIC_DOMAINS if PM + select PM_GENERIC_DOMAINS_OF if PM && OF + select REGMAP_MMIO + select RESET_CONTROLLER ++ select PINCTRL + select PINCTRL_SINGLE + + if ARCH_DAVINCI +diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +index 738024baaa578..54faf83cb436e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +@@ -1408,7 +1408,7 @@ + assigned-clocks = <&clk IMX8MM_CLK_GPU3D_CORE>, + <&clk IMX8MM_GPU_PLL_OUT>; + assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; +- assigned-clock-rates = <0>, <1000000000>; ++ assigned-clock-rates = <0>, <800000000>; + power-domains = <&pgc_gpu>; + }; + +@@ -1423,7 +1423,7 @@ + assigned-clocks = <&clk IMX8MM_CLK_GPU2D_CORE>, + <&clk IMX8MM_GPU_PLL_OUT>; + assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; +- assigned-clock-rates = <0>, <1000000000>; ++ assigned-clock-rates = <0>, <800000000>; + power-domains = <&pgc_gpu>; + }; + +diff --git a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi +index 970047f2dabd5..c06e011a6c3ff 100644 +--- a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi ++++ b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi +@@ -25,9 +25,6 @@ + gpios = <&gpio28 0 0>; + + regulators { +- #address-cells = <1>; +- #size-cells = <0>; +- + ldo3: ldo3 { /* HDMI */ + regulator-name = "ldo3"; + regulator-min-microvolt = <1500000>; +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +index 9eab2bb221348..805ef2d79b401 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -130,7 +130,7 @@ + compatible = "microchip,mcp7940x"; + reg = <0x6f>; + interrupt-parent = <&gpiosb>; +- interrupts = <5 0>; /* GPIO2_5 */ ++ interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO2_5 */ + }; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 976dc968b3ca1..df6e9990cd5fa 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1660,7 +1660,7 @@ + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>; + }; + +- mdp3-rdma0@14001000 { ++ dma-controller0@14001000 { + compatible = "mediatek,mt8183-mdp3-rdma"; + reg = <0 0x14001000 0 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; +@@ -1672,6 +1672,7 @@ + iommus = <&iommu M4U_PORT_MDP_RDMA0>; + mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>, + <&gce 21 CMDQ_THR_PRIO_LOWEST 0>; ++ #dma-cells = <1>; + }; + + mdp3-rsz0@14003000 { +@@ -1692,7 +1693,7 @@ + clocks = <&mmsys CLK_MM_MDP_RSZ1>; + }; + +- mdp3-wrot0@14005000 { ++ dma-controller@14005000 { + compatible = "mediatek,mt8183-mdp3-wrot"; + reg = <0 0x14005000 0 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; +@@ -1701,6 +1702,7 @@ + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + iommus = <&iommu M4U_PORT_MDP_WROT0>; ++ #dma-cells = <1>; + }; + + mdp3-wdma@14006000 { +diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +index df0c04f2ba1da..2fec6fd1c1a71 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi +@@ -22,7 +22,7 @@ + + aliases { + ovl0 = &ovl0; +- ovl_2l0 = &ovl_2l0; ++ ovl-2l0 = &ovl_2l0; + rdma0 = &rdma0; + rdma1 = &rdma1; + }; +@@ -1160,14 +1160,14 @@ + status = "disabled"; + }; + +- adsp_mailbox0: mailbox@10686000 { ++ adsp_mailbox0: mailbox@10686100 { + compatible = "mediatek,mt8186-adsp-mbox"; + #mbox-cells = <0>; + reg = <0 0x10686100 0 0x1000>; + interrupts = ; + }; + +- adsp_mailbox1: mailbox@10687000 { ++ adsp_mailbox1: mailbox@10687100 { + compatible = "mediatek,mt8186-adsp-mbox"; + #mbox-cells = <0>; + reg = <0 0x10687100 0 0x1000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index e0ac2e9f5b720..6708c4d21abf9 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -2873,7 +2873,7 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + }; + +- vdo1_rdma0: rdma@1c104000 { ++ vdo1_rdma0: dma-controller@1c104000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c104000 0 0x1000>; + interrupts = ; +@@ -2881,9 +2881,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x4000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma1: rdma@1c105000 { ++ vdo1_rdma1: dma-controller@1c105000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c105000 0 0x1000>; + interrupts = ; +@@ -2891,9 +2892,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x5000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma2: rdma@1c106000 { ++ vdo1_rdma2: dma-controller@1c106000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c106000 0 0x1000>; + interrupts = ; +@@ -2901,9 +2903,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x6000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma3: rdma@1c107000 { ++ vdo1_rdma3: dma-controller@1c107000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c107000 0 0x1000>; + interrupts = ; +@@ -2911,9 +2914,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x7000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma4: rdma@1c108000 { ++ vdo1_rdma4: dma-controller@1c108000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c108000 0 0x1000>; + interrupts = ; +@@ -2921,9 +2925,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x8000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma5: rdma@1c109000 { ++ vdo1_rdma5: dma-controller@1c109000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c109000 0 0x1000>; + interrupts = ; +@@ -2931,9 +2936,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA5>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x9000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma6: rdma@1c10a000 { ++ vdo1_rdma6: dma-controller@1c10a000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c10a000 0 0x1000>; + interrupts = ; +@@ -2941,9 +2947,10 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA6>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xa000 0x1000>; ++ #dma-cells = <1>; + }; + +- vdo1_rdma7: rdma@1c10b000 { ++ vdo1_rdma7: dma-controller@1c10b000 { + compatible = "mediatek,mt8195-vdo1-rdma"; + reg = <0 0x1c10b000 0 0x1000>; + interrupts = ; +@@ -2951,6 +2958,7 @@ + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA7>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xb000 0x1000>; ++ #dma-cells = <1>; + }; + + merge1: vpp-merge@1c10c000 { +diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +index 264845cecf925..fc907afe5174c 100644 +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -565,7 +565,7 @@ + <&gcc GCC_USB0_MOCK_UTMI_CLK>; + assigned-clock-rates = <133330000>, + <133330000>, +- <20000000>; ++ <24000000>; + + resets = <&gcc GCC_USB0_BCR>; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +index 0f7c591878962..37abb83ea4647 100644 +--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts ++++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +@@ -366,6 +366,16 @@ + status = "okay"; + }; + ++&usb_qmpphy { ++ vdda-phy-supply = <&pm2250_l12>; ++ vdda-pll-supply = <&pm2250_l13>; ++ status = "okay"; ++}; ++ ++&usb_dwc3 { ++ dr_mode = "host"; ++}; ++ + &usb_hsphy { + vdd-supply = <&pm2250_l12>; + vdda-pll-supply = <&pm2250_l13>; +diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +index a7278a9472ed9..9738c0dacd58c 100644 +--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts ++++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +@@ -518,7 +518,6 @@ + + &usb_dwc3 { + maximum-speed = "super-speed"; +- dr_mode = "peripheral"; + }; + + &usb_hsphy { +diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +index dfa8ee5c75af6..e95a004c33919 100644 +--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts ++++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +@@ -63,8 +63,8 @@ + function = LED_FUNCTION_INDICATOR; + color = ; + gpios = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "panic-indicator"; + default-state = "off"; ++ panic-indicator; + }; + + led-wlan { +diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi +index 9f4f58e831a4a..d4ca92b98c7db 100644 +--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi ++++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi +@@ -1602,8 +1602,8 @@ + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 14 IRQ_TYPE_EDGE_RISING>, +- <&pdc 15 IRQ_TYPE_EDGE_RISING>, ++ <&pdc 14 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 15 IRQ_TYPE_EDGE_BOTH>, + <&pdc 12 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "pwr_event", + "dp_hs_phy_irq", +@@ -1689,8 +1689,8 @@ + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 8 IRQ_TYPE_EDGE_RISING>, +- <&pdc 7 IRQ_TYPE_EDGE_RISING>, ++ <&pdc 8 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 7 IRQ_TYPE_EDGE_BOTH>, + <&pdc 13 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "pwr_event", + "dp_hs_phy_irq", +@@ -1752,8 +1752,8 @@ + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 10 IRQ_TYPE_EDGE_RISING>, +- <&pdc 9 IRQ_TYPE_EDGE_RISING>; ++ <&pdc 10 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 9 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "pwr_event", + "dp_hs_phy_irq", + "dm_hs_phy_irq"; +@@ -2173,7 +2173,7 @@ + compatible = "qcom,apss-wdt-sa8775p", "qcom,kpss-wdt"; + reg = <0x0 0x17c10000 0x0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + memtimer: timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts +index dbb48934d4995..3342cb0480385 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts ++++ b/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts +@@ -209,9 +209,22 @@ + AVDD-supply = <&vreg_l15a_1p8>; + MICVDD-supply = <®_codec_3p3>; + VBAT-supply = <®_codec_3p3>; ++ DBVDD-supply = <&vreg_l15a_1p8>; ++ LDO1-IN-supply = <&vreg_l15a_1p8>; ++ ++ /* ++ * NOTE: The board has a path from this codec to the ++ * DMIC microphones in the lid, however some of the option ++ * resistors are absent and the microphones are connected ++ * to the SoC instead. ++ * ++ * If the resistors were to be changed by the user to ++ * connect the codec, the following could be used: ++ * ++ * realtek,dmic1-data-pin = <1>; ++ * realtek,dmic1-clk-pin = <1>; ++ */ + +- realtek,dmic1-data-pin = <1>; +- realtek,dmic1-clk-pin = <1>; + realtek,jd-src = <1>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi +index a79c0f2e18799..589ae40cd3cc9 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi +@@ -3587,7 +3587,7 @@ + compatible = "qcom,apss-wdt-sc7180", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi +index 2e1cd219fc182..5d462ae14ba12 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi +@@ -46,6 +46,26 @@ + }; + }; + ++&lpass_aon { ++ status = "okay"; ++}; ++ ++&lpass_core { ++ status = "okay"; ++}; ++ ++&lpass_hm { ++ status = "okay"; ++}; ++ ++&lpasscc { ++ status = "okay"; ++}; ++ ++&pdc_reset { ++ status = "okay"; ++}; ++ + /* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */ + &pmk8350_pon { + status = "disabled"; +@@ -84,6 +104,10 @@ + dma-coherent; + }; + ++&watchdog { ++ status = "okay"; ++}; ++ + &wifi { + status = "okay"; + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 91bb58c6b1a61..ec5c36425a225 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -925,6 +925,7 @@ + + bus-width = <8>; + supports-cqe; ++ dma-coherent; + + qcom,dll-config = <0x0007642c>; + qcom,ddr-config = <0x80040868>; +@@ -2255,6 +2256,7 @@ + clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; + clock-names = "iface"; + #clock-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_rx_macro: codec@3200000 { +@@ -2406,6 +2408,7 @@ + clock-names = "bi_tcxo", "bi_tcxo_ao", "iface"; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_core: clock-controller@3900000 { +@@ -2416,6 +2419,7 @@ + power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_cpu: audio@3987000 { +@@ -2486,6 +2490,7 @@ + clock-names = "bi_tcxo"; + #clock-cells = <1>; + #power-domain-cells = <1>; ++ status = "reserved"; /* Owned by ADSP firmware */ + }; + + lpass_ag_noc: interconnect@3c40000 { +@@ -2554,7 +2559,8 @@ + "cx_mem", + "cx_dbgc"; + interrupts = ; +- iommus = <&adreno_smmu 0 0x401>; ++ iommus = <&adreno_smmu 0 0x400>, ++ <&adreno_smmu 1 0x400>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; +@@ -2728,6 +2734,7 @@ + "gpu_cc_hub_aon_clk"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>; ++ dma-coherent; + }; + + remoteproc_mpss: remoteproc@4080000 { +@@ -3285,6 +3292,7 @@ + operating-points-v2 = <&sdhc2_opp_table>; + + bus-width = <4>; ++ dma-coherent; + + qcom,dll-config = <0x0007642c>; + +@@ -3405,8 +3413,8 @@ + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 12 IRQ_TYPE_EDGE_RISING>, +- <&pdc 13 IRQ_TYPE_EDGE_RISING>; ++ <&pdc 12 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 13 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq"; +@@ -4199,6 +4207,7 @@ + compatible = "qcom,sc7280-pdc-global"; + reg = <0 0x0b5e0000 0 0x20000>; + #reset-cells = <1>; ++ status = "reserved"; /* Owned by firmware */ + }; + + tsens0: thermal-sensor@c263000 { +@@ -5195,11 +5204,12 @@ + }; + }; + +- watchdog@17c10000 { ++ watchdog: watchdog@17c10000 { + compatible = "qcom,apss-wdt-sc7280", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; ++ status = "reserved"; /* Owned by Gunyah hyp */ + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts +index 834e6f9fb7c82..ae008c3b0aed9 100644 +--- a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts ++++ b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts +@@ -42,7 +42,7 @@ + pinctrl-0 = <&hall_int_active_state>; + + lid-switch { +- gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>; ++ gpios = <&tlmm 121 GPIO_ACTIVE_LOW>; + linux,input-type = ; + linux,code = ; + wakeup-source; +diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi +index 486f7ffef43b2..f4381424e70a2 100644 +--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi +@@ -1749,23 +1749,29 @@ + <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + +- phys = <&pcie0_lane>; ++ phys = <&pcie0_phy>; + phy-names = "pciephy"; ++ dma-coherent; + + status = "disabled"; + }; + +- pcie0_phy: phy-wrapper@1c06000 { ++ pcie0_phy: phy@1c06000 { + compatible = "qcom,sc8180x-qmp-pcie-phy"; +- reg = <0 0x1c06000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01c06000 0 0x1000>; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_CLKREF_CLK>, +- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "ref", "refgen"; ++ <&gcc GCC_PCIE0_PHY_REFGEN_CLK>, ++ <&gcc GCC_PCIE_0_PIPE_CLK>; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen", ++ "pipe"; ++ #clock-cells = <0>; ++ clock-output-names = "pcie_0_pipe_clk"; ++ #phy-cells = <0>; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "phy"; +@@ -1774,21 +1780,6 @@ + assigned-clock-rates = <100000000>; + + status = "disabled"; +- +- pcie0_lane: phy@1c06200 { +- reg = <0 0x1c06200 0 0x170>, /* tx0 */ +- <0 0x1c06400 0 0x200>, /* rx0 */ +- <0 0x1c06a00 0 0x1f0>, /* pcs */ +- <0 0x1c06600 0 0x170>, /* tx1 */ +- <0 0x1c06800 0 0x200>, /* rx1 */ +- <0 0x1c06e00 0 0xf4>; /* pcs_com */ +- clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; +- clock-names = "pipe0"; +- +- #clock-cells = <0>; +- clock-output-names = "pcie_0_pipe_clk"; +- #phy-cells = <0>; +- }; + }; + + pcie3: pci@1c08000 { +@@ -1856,23 +1847,30 @@ + <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + +- phys = <&pcie3_lane>; ++ phys = <&pcie3_phy>; + phy-names = "pciephy"; ++ dma-coherent; + + status = "disabled"; + }; + +- pcie3_phy: phy-wrapper@1c0c000 { ++ pcie3_phy: phy@1c0c000 { + compatible = "qcom,sc8180x-qmp-pcie-phy"; +- reg = <0 0x1c0c000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01c0c000 0 0x1000>; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_3_CFG_AHB_CLK>, + <&gcc GCC_PCIE_3_CLKREF_CLK>, +- <&gcc GCC_PCIE2_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "ref", "refgen"; ++ <&gcc GCC_PCIE3_PHY_REFGEN_CLK>, ++ <&gcc GCC_PCIE_3_PIPE_CLK>; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen", ++ "pipe"; ++ #clock-cells = <0>; ++ clock-output-names = "pcie_3_pipe_clk"; ++ ++ #phy-cells = <0>; + + resets = <&gcc GCC_PCIE_3_PHY_BCR>; + reset-names = "phy"; +@@ -1881,21 +1879,6 @@ + assigned-clock-rates = <100000000>; + + status = "disabled"; +- +- pcie3_lane: phy@1c0c200 { +- reg = <0 0x1c0c200 0 0x170>, /* tx0 */ +- <0 0x1c0c400 0 0x200>, /* rx0 */ +- <0 0x1c0ca00 0 0x1f0>, /* pcs */ +- <0 0x1c0c600 0 0x170>, /* tx1 */ +- <0 0x1c0c800 0 0x200>, /* rx1 */ +- <0 0x1c0ce00 0 0xf4>; /* pcs_com */ +- clocks = <&gcc GCC_PCIE_3_PIPE_CLK>; +- clock-names = "pipe0"; +- +- #clock-cells = <0>; +- clock-output-names = "pcie_3_pipe_clk"; +- #phy-cells = <0>; +- }; + }; + + pcie1: pci@1c10000 { +@@ -1963,23 +1946,30 @@ + <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + +- phys = <&pcie1_lane>; ++ phys = <&pcie1_phy>; + phy-names = "pciephy"; ++ dma-coherent; + + status = "disabled"; + }; + +- pcie1_phy: phy-wrapper@1c16000 { ++ pcie1_phy: phy@1c16000 { + compatible = "qcom,sc8180x-qmp-pcie-phy"; +- reg = <0 0x1c16000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01c16000 0 0x1000>; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_CLKREF_CLK>, +- <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "ref", "refgen"; ++ <&gcc GCC_PCIE1_PHY_REFGEN_CLK>, ++ <&gcc GCC_PCIE_1_PIPE_CLK>; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen", ++ "pipe"; ++ #clock-cells = <0>; ++ clock-output-names = "pcie_1_pipe_clk"; ++ ++ #phy-cells = <0>; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "phy"; +@@ -1988,21 +1978,6 @@ + assigned-clock-rates = <100000000>; + + status = "disabled"; +- +- pcie1_lane: phy@1c0e200 { +- reg = <0 0x1c16200 0 0x170>, /* tx0 */ +- <0 0x1c16400 0 0x200>, /* rx0 */ +- <0 0x1c16a00 0 0x1f0>, /* pcs */ +- <0 0x1c16600 0 0x170>, /* tx1 */ +- <0 0x1c16800 0 0x200>, /* rx1 */ +- <0 0x1c16e00 0 0xf4>; /* pcs_com */ +- clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; +- clock-names = "pipe0"; +- #clock-cells = <0>; +- clock-output-names = "pcie_1_pipe_clk"; +- +- #phy-cells = <0>; +- }; + }; + + pcie2: pci@1c18000 { +@@ -2070,23 +2045,30 @@ + <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + +- phys = <&pcie2_lane>; ++ phys = <&pcie2_phy>; + phy-names = "pciephy"; ++ dma-coherent; + + status = "disabled"; + }; + +- pcie2_phy: phy-wrapper@1c1c000 { ++ pcie2_phy: phy@1c1c000 { + compatible = "qcom,sc8180x-qmp-pcie-phy"; +- reg = <0 0x1c1c000 0 0x1c0>; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; ++ reg = <0 0x01c1c000 0 0x1000>; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_2_CFG_AHB_CLK>, + <&gcc GCC_PCIE_2_CLKREF_CLK>, +- <&gcc GCC_PCIE2_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "ref", "refgen"; ++ <&gcc GCC_PCIE2_PHY_REFGEN_CLK>, ++ <&gcc GCC_PCIE_2_PIPE_CLK>; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen", ++ "pipe"; ++ #clock-cells = <0>; ++ clock-output-names = "pcie_2_pipe_clk"; ++ ++ #phy-cells = <0>; + + resets = <&gcc GCC_PCIE_2_PHY_BCR>; + reset-names = "phy"; +@@ -2095,22 +2077,6 @@ + assigned-clock-rates = <100000000>; + + status = "disabled"; +- +- pcie2_lane: phy@1c0e200 { +- reg = <0 0x1c1c200 0 0x170>, /* tx0 */ +- <0 0x1c1c400 0 0x200>, /* rx0 */ +- <0 0x1c1ca00 0 0x1f0>, /* pcs */ +- <0 0x1c1c600 0 0x170>, /* tx1 */ +- <0 0x1c1c800 0 0x200>, /* rx1 */ +- <0 0x1c1ce00 0 0xf4>; /* pcs_com */ +- clocks = <&gcc GCC_PCIE_2_PIPE_CLK>; +- clock-names = "pipe0"; +- +- #clock-cells = <0>; +- clock-output-names = "pcie_2_pipe_clk"; +- +- #phy-cells = <0>; +- }; + }; + + ufs_mem_hc: ufshc@1d84000 { +diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +index 38edaf51aa345..f2055899ae7ae 100644 +--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts ++++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +@@ -82,6 +82,9 @@ + leds { + compatible = "gpio-leds"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cam_indicator_en>; ++ + led-camera-indicator { + label = "white:camera-indicator"; + function = LED_FUNCTION_INDICATOR; +@@ -601,6 +604,7 @@ + }; + + &mdss0_dp3_phy { ++ compatible = "qcom,sc8280xp-edp-phy"; + vdda-phy-supply = <&vreg_l6b>; + vdda-pll-supply = <&vreg_l3b>; + +@@ -1277,6 +1281,13 @@ + }; + }; + ++ cam_indicator_en: cam-indicator-en-state { ++ pins = "gpio28"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ + edp_reg_en: edp-reg-en-state { + pins = "gpio25"; + function = "gpio"; +diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +index cad59af7ccef1..b8081513176ac 100644 +--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +@@ -4225,7 +4225,7 @@ + compatible = "qcom,apss-wdt-sc8280xp", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +index c7eba6c491be2..7e7bf3fb3be63 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +@@ -67,8 +67,8 @@ + function = LED_FUNCTION_INDICATOR; + color = ; + gpios = <&pm8998_gpios 13 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "panic-indicator"; + default-state = "off"; ++ panic-indicator; + }; + + led-1 { +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index 055ca80c00757..2cf1993a8190f 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -5118,7 +5118,7 @@ + compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt"; + reg = <0 0x17980000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + apss_shared: mailbox@17990000 { +diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi +index 197f8fed19a29..07081088ba146 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -1165,6 +1165,10 @@ + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <66666667>; + ++ interrupts = , ++ ; ++ interrupt-names = "hs_phy_irq", "ss_phy_irq"; ++ + power-domains = <&gcc USB30_PRIM_GDSC>; + qcom,select-utmi-as-pipe-clk; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index 8fd6f4d034900..6464e144c228c 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -2524,7 +2524,7 @@ + compatible = "qcom,apss-wdt-sm6350", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi +index e7ff55443da70..e56f7ea4ebc6a 100644 +--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi +@@ -311,6 +311,25 @@ + }; + }; + ++ mpm: interrupt-controller { ++ compatible = "qcom,mpm"; ++ qcom,rpm-msg-ram = <&apss_mpm>; ++ interrupts = ; ++ mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_SMP2P>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ #power-domain-cells = <0>; ++ interrupt-parent = <&intc>; ++ qcom,mpm-pin-count = <96>; ++ qcom,mpm-pin-map = <5 296>, /* Soundwire wake_irq */ ++ <12 422>, /* DWC3 ss_phy_irq */ ++ <86 183>, /* MPM wake, SPMI */ ++ <89 314>, /* TSENS0 0C */ ++ <90 315>, /* TSENS1 0C */ ++ <93 164>, /* DWC3 dm_hs_phy_irq */ ++ <94 165>; /* DWC3 dp_hs_phy_irq */ ++ }; ++ + memory@80000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the size */ +@@ -486,6 +505,7 @@ + + CLUSTER_PD: power-domain-cpu-cluster0 { + #power-domain-cells = <0>; ++ power-domains = <&mpm>; + domain-idle-states = <&CLUSTER_SLEEP_0>; + }; + }; +@@ -808,7 +828,7 @@ + reg = <0 0x00500000 0 0x800000>; + interrupts = ; + gpio-ranges = <&tlmm 0 0 157>; +- /* TODO: Hook up MPM as wakeup-parent when it's there */ ++ wakeup-parent = <&mpm>; + interrupt-controller; + gpio-controller; + #interrupt-cells = <2>; +@@ -930,7 +950,7 @@ + <0 0x01c0a000 0 0x26000>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; +- interrupts = ; ++ interrupts-extended = <&mpm 86 IRQ_TYPE_LEVEL_HIGH>; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; +@@ -962,8 +982,15 @@ + }; + + rpm_msg_ram: sram@45f0000 { +- compatible = "qcom,rpm-msg-ram"; ++ compatible = "qcom,rpm-msg-ram", "mmio-sram"; + reg = <0 0x045f0000 0 0x7000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x0 0x045f0000 0x7000>; ++ ++ apss_mpm: sram@1b8 { ++ reg = <0x1b8 0x48>; ++ }; + }; + + sram@4690000 { +@@ -1360,10 +1387,10 @@ + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <133333333>; + +- interrupts = , +- , +- , +- ; ++ interrupts-extended = <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>, ++ <&mpm 12 IRQ_TYPE_LEVEL_HIGH>, ++ <&mpm 93 IRQ_TYPE_EDGE_BOTH>, ++ <&mpm 94 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "hs_phy_irq", + "ss_phy_irq", + "dm_hs_phy_irq", +diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +index bb161b536da46..f4c6e1309a7e9 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts ++++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +@@ -127,8 +127,6 @@ + vdda_sp_sensor: + vdda_ufs_2ln_core_1: + vdda_ufs_2ln_core_2: +- vdda_usb_ss_dp_core_1: +- vdda_usb_ss_dp_core_2: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vreg_l5a_0p875: ldo5 { +@@ -210,6 +208,12 @@ + regulator-max-microvolt = <3008000>; + regulator-initial-mode = ; + }; ++ ++ vreg_l18a_0p8: ldo18 { ++ regulator-min-microvolt = <880000>; ++ regulator-max-microvolt = <880000>; ++ regulator-initial-mode = ; ++ }; + }; + + regulators-1 { +@@ -445,13 +449,13 @@ + &usb_1_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; +- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; ++ vdda-pll-supply = <&vreg_l18a_0p8>; + }; + + &usb_2_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; +- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; ++ vdda-pll-supply = <&vreg_l5a_0p875>; + }; + + &usb_1 { +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index 19c6003dca153..32045fb481575 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -3959,6 +3959,7 @@ + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div_clk"; + power-domains = <&rpmhpd SM8150_MMCX>; ++ required-opps = <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; +@@ -4197,7 +4198,7 @@ + compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index a4e58ad731c34..1a98481d0c7f4 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -5664,7 +5664,7 @@ + compatible = "qcom,apss-wdt-sm8250", "qcom,kpss-wdt"; + reg = <0 0x17c10000 0 0x1000>; + clocks = <&sleep_clk>; +- interrupts = ; ++ interrupts = ; + }; + + timer@17c20000 { +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index a94e069da83d5..a7cf506f24b6c 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -918,9 +918,9 @@ + }; + }; + +- gpi_dma0: dma-controller@9800000 { ++ gpi_dma0: dma-controller@900000 { + compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma"; +- reg = <0 0x09800000 0 0x60000>; ++ reg = <0 0x00900000 0 0x60000>; + interrupts = , + , + , +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 2a60cf8bd891c..79cc8fbcd8468 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -2325,7 +2325,7 @@ + ; + interrupt-names = "core", "wakeup"; + +- clocks = <&vamacro>; ++ clocks = <&txmacro>; + clock-names = "iface"; + label = "TX"; + +diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi +index d115960bdeec8..3a228d4f0c148 100644 +--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi +@@ -283,9 +283,9 @@ + compatible = "arm,idle-state"; + idle-state-name = "silver-rail-power-collapse"; + arm,psci-suspend-param = <0x40000004>; +- entry-latency-us = <800>; ++ entry-latency-us = <550>; + exit-latency-us = <750>; +- min-residency-us = <4090>; ++ min-residency-us = <6700>; + local-timer-stop; + }; + +@@ -294,8 +294,18 @@ + idle-state-name = "gold-rail-power-collapse"; + arm,psci-suspend-param = <0x40000004>; + entry-latency-us = <600>; +- exit-latency-us = <1550>; +- min-residency-us = <4791>; ++ exit-latency-us = <1300>; ++ min-residency-us = <8136>; ++ local-timer-stop; ++ }; ++ ++ PRIME_CPU_SLEEP_0: cpu-sleep-2-0 { ++ compatible = "arm,idle-state"; ++ idle-state-name = "goldplus-rail-power-collapse"; ++ arm,psci-suspend-param = <0x40000004>; ++ entry-latency-us = <500>; ++ exit-latency-us = <1350>; ++ min-residency-us = <7480>; + local-timer-stop; + }; + }; +@@ -304,17 +314,17 @@ + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x41000044>; +- entry-latency-us = <1050>; +- exit-latency-us = <2500>; +- min-residency-us = <5309>; ++ entry-latency-us = <750>; ++ exit-latency-us = <2350>; ++ min-residency-us = <9144>; + }; + + CLUSTER_SLEEP_1: cluster-sleep-1 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x4100c344>; +- entry-latency-us = <2700>; +- exit-latency-us = <3500>; +- min-residency-us = <13959>; ++ entry-latency-us = <2800>; ++ exit-latency-us = <4400>; ++ min-residency-us = <10150>; + }; + }; + }; +@@ -398,7 +408,7 @@ + CPU_PD7: power-domain-cpu7 { + #power-domain-cells = <0>; + power-domains = <&CLUSTER_PD>; +- domain-idle-states = <&BIG_CPU_SLEEP_0>; ++ domain-idle-states = <&PRIME_CPU_SLEEP_0>; + }; + + CLUSTER_PD: power-domain-cluster { +@@ -2178,7 +2188,7 @@ + interrupts = , + ; + interrupt-names = "core", "wakeup"; +- clocks = <&lpass_vamacro>; ++ clocks = <&lpass_txmacro>; + clock-names = "iface"; + label = "TX"; + +@@ -2893,8 +2903,8 @@ + + interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>, +- <&pdc 15 IRQ_TYPE_EDGE_RISING>, +- <&pdc 14 IRQ_TYPE_EDGE_RISING>; ++ <&pdc 15 IRQ_TYPE_EDGE_BOTH>, ++ <&pdc 14 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "hs_phy_irq", + "ss_phy_irq", + "dm_hs_phy_irq", +diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi +index bb4a5270f71b6..913f70fe6c5cd 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi +@@ -187,6 +187,9 @@ + }; + + &hscif0 { ++ pinctrl-0 = <&hscif0_pins>; ++ pinctrl-names = "default"; ++ + status = "okay"; + }; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts b/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts +index 1c6d83b47cd21..6ecdf5d283390 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts +@@ -455,7 +455,7 @@ + &pinctrl { + leds { + sys_led_pin: sys-status-led-pin { +- rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +index 3198af08fb9fa..de36abb243f10 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +@@ -462,7 +462,7 @@ + <193>, <194>, <195>; + interrupt-controller; + #interrupt-cells = <2>; +- ti,ngpio = <87>; ++ ti,ngpio = <92>; + ti,davinci-gpio-unbanked = <0>; + power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 77 0>; +@@ -480,7 +480,7 @@ + <183>, <184>, <185>; + interrupt-controller; + #interrupt-cells = <2>; +- ti,ngpio = <88>; ++ ti,ngpio = <52>; + ti,davinci-gpio-unbanked = <0>; + power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 78 0>; +diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +index ba1c14a54acf4..b849648d51f91 100644 +--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +@@ -14,6 +14,16 @@ + + / { + aliases { ++ serial0 = &wkup_uart0; ++ serial1 = &mcu_uart0; ++ serial2 = &main_uart0; ++ serial3 = &main_uart1; ++ i2c0 = &wkup_i2c0; ++ i2c1 = &mcu_i2c0; ++ i2c2 = &main_i2c0; ++ i2c3 = &main_i2c1; ++ i2c4 = &main_i2c2; ++ i2c5 = &main_i2c3; + spi0 = &mcu_spi0; + mmc0 = &sdhci1; + mmc1 = &sdhci0; +diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +index bc460033a37a8..c98068b6c122a 100644 +--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +@@ -1034,7 +1034,7 @@ + assigned-clocks = <&k3_clks 67 2>; + assigned-clock-parents = <&k3_clks 67 5>; + +- interrupts = ; ++ interrupts = ; + + dma-coherent; + +diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile +index 5e40c0b4fa0a9..1068b0fa8e984 100644 +--- a/arch/arm64/boot/dts/xilinx/Makefile ++++ b/arch/arm64/boot/dts/xilinx/Makefile +@@ -22,11 +22,10 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA.dtb + dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA.dtb + + zynqmp-sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo ++dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revA.dtb + zynqmp-sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo ++dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revB.dtb + zynqmp-smk-k26-revA-sck-kv-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo ++dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revA.dtb + zynqmp-smk-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo +- +-zynqmp-sm-k26-revA-sck-kr-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo +-zynqmp-sm-k26-revA-sck-kr-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo +-zynqmp-smk-k26-revA-sck-kr-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo +-zynqmp-smk-k26-revA-sck-kr-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo ++dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revB.dtb +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index 20d7ef82de90a..b3f64144b5cd9 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -1107,12 +1107,13 @@ static int za_set(struct task_struct *target, + } + } + +- /* Allocate/reinit ZA storage */ +- sme_alloc(target, true); +- if (!target->thread.sme_state) { +- ret = -ENOMEM; +- goto out; +- } ++ /* ++ * Only flush the storage if PSTATE.ZA was not already set, ++ * otherwise preserve any existing data. ++ */ ++ sme_alloc(target, !thread_za_enabled(&target->thread)); ++ if (!target->thread.sme_state) ++ return -ENOMEM; + + /* If there is no data then disable ZA */ + if (!count) { +diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c +index 5fe2365a629f2..c420723548d8d 100644 +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -584,7 +584,11 @@ static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db, + unsigned long flags; + + raw_spin_lock_irqsave(&dist->lpi_list_lock, flags); ++ + irq = __vgic_its_check_cache(dist, db, devid, eventid); ++ if (irq) ++ vgic_get_irq_kref(irq); ++ + raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); + + return irq; +@@ -763,6 +767,7 @@ int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi) + raw_spin_lock_irqsave(&irq->irq_lock, flags); + irq->pending_latch = true; + vgic_queue_irq_unlock(kvm, irq, flags); ++ vgic_put_irq(kvm, irq); + + return 0; + } +diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +index 871a45d4fc84c..ae5a3a717655e 100644 +--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c ++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +@@ -365,19 +365,26 @@ static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + + raw_spin_lock_irqsave(&irq->irq_lock, flags); +- if (test_bit(i, &val)) { +- /* +- * pending_latch is set irrespective of irq type +- * (level or edge) to avoid dependency that VM should +- * restore irq config before pending info. +- */ +- irq->pending_latch = true; +- vgic_queue_irq_unlock(vcpu->kvm, irq, flags); +- } else { ++ ++ /* ++ * pending_latch is set irrespective of irq type ++ * (level or edge) to avoid dependency that VM should ++ * restore irq config before pending info. ++ */ ++ irq->pending_latch = test_bit(i, &val); ++ ++ if (irq->hw && vgic_irq_is_sgi(irq->intid)) { ++ irq_set_irqchip_state(irq->host_irq, ++ IRQCHIP_STATE_PENDING, ++ irq->pending_latch); + irq->pending_latch = false; +- raw_spin_unlock_irqrestore(&irq->irq_lock, flags); + } + ++ if (irq->pending_latch) ++ vgic_queue_irq_unlock(vcpu->kvm, irq, flags); ++ else ++ raw_spin_unlock_irqrestore(&irq->irq_lock, flags); ++ + vgic_put_irq(vcpu->kvm, irq); + } + +diff --git a/arch/csky/include/asm/jump_label.h b/arch/csky/include/asm/jump_label.h +index d488ba6084bc6..98a3f4b168bd2 100644 +--- a/arch/csky/include/asm/jump_label.h ++++ b/arch/csky/include/asm/jump_label.h +@@ -43,5 +43,10 @@ label: + return true; + } + ++enum jump_label_type; ++void arch_jump_label_transform_static(struct jump_entry *entry, ++ enum jump_label_type type); ++#define arch_jump_label_transform_static arch_jump_label_transform_static ++ + #endif /* __ASSEMBLY__ */ + #endif /* __ASM_CSKY_JUMP_LABEL_H */ +diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h +index 9b16a3b8e7060..f16bd42456e4c 100644 +--- a/arch/loongarch/include/asm/elf.h ++++ b/arch/loongarch/include/asm/elf.h +@@ -241,8 +241,6 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); + do { \ + current->thread.vdso = &vdso_info; \ + \ +- loongarch_set_personality_fcsr(state); \ +- \ + if (personality(current->personality) != PER_LINUX) \ + set_personality(PER_LINUX); \ + } while (0) +@@ -259,7 +257,6 @@ do { \ + clear_thread_flag(TIF_32BIT_ADDR); \ + \ + current->thread.vdso = &vdso_info; \ +- loongarch_set_personality_fcsr(state); \ + \ + p = personality(current->personality); \ + if (p != PER_LINUX32 && p != PER_LINUX) \ +@@ -340,6 +337,4 @@ extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, + extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, + struct arch_elf_state *state); + +-extern void loongarch_set_personality_fcsr(struct arch_elf_state *state); +- + #endif /* _ASM_ELF_H */ +diff --git a/arch/loongarch/kernel/elf.c b/arch/loongarch/kernel/elf.c +index 183e94fc9c69c..0fa81ced28dcd 100644 +--- a/arch/loongarch/kernel/elf.c ++++ b/arch/loongarch/kernel/elf.c +@@ -23,8 +23,3 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, + { + return 0; + } +- +-void loongarch_set_personality_fcsr(struct arch_elf_state *state) +-{ +- current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; +-} +diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c +index 767d94cce0de0..f2ff8b5d591e4 100644 +--- a/arch/loongarch/kernel/process.c ++++ b/arch/loongarch/kernel/process.c +@@ -85,6 +85,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) + regs->csr_euen = euen; + lose_fpu(0); + lose_lbt(0); ++ current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; + + clear_thread_flag(TIF_LSX_CTX_LIVE); + clear_thread_flag(TIF_LASX_CTX_LIVE); +diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c +index 00915fb3cb82c..9eb7753d117df 100644 +--- a/arch/loongarch/net/bpf_jit.c ++++ b/arch/loongarch/net/bpf_jit.c +@@ -461,7 +461,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + const u8 dst = regmap[insn->dst_reg]; + const s16 off = insn->off; + const s32 imm = insn->imm; +- const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; + const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32; + + switch (code) { +@@ -865,8 +864,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + + /* dst = imm64 */ + case BPF_LD | BPF_IMM | BPF_DW: ++ { ++ const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; ++ + move_imm(ctx, dst, imm64, is32); + return 1; ++ } + + /* dst = *(size *)(src + off) */ + case BPF_LDX | BPF_MEM | BPF_B: +diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c +index f521874ebb07b..67f067706af27 100644 +--- a/arch/mips/alchemy/devboards/db1200.c ++++ b/arch/mips/alchemy/devboards/db1200.c +@@ -847,7 +847,7 @@ int __init db1200_dev_setup(void) + i2c_register_board_info(0, db1200_i2c_devs, + ARRAY_SIZE(db1200_i2c_devs)); + spi_register_board_info(db1200_spi_devs, +- ARRAY_SIZE(db1200_i2c_devs)); ++ ARRAY_SIZE(db1200_spi_devs)); + + /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) + * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) +diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c +index fd91d9c9a2525..6c6837181f555 100644 +--- a/arch/mips/alchemy/devboards/db1550.c ++++ b/arch/mips/alchemy/devboards/db1550.c +@@ -589,7 +589,7 @@ int __init db1550_dev_setup(void) + i2c_register_board_info(0, db1550_i2c_devs, + ARRAY_SIZE(db1550_i2c_devs)); + spi_register_board_info(db1550_spi_devs, +- ARRAY_SIZE(db1550_i2c_devs)); ++ ARRAY_SIZE(db1550_spi_devs)); + + c = clk_get(NULL, "psc0_intclk"); + if (!IS_ERR(c)) { +diff --git a/arch/mips/include/asm/dmi.h b/arch/mips/include/asm/dmi.h +index 27415a288adf5..dc397f630c660 100644 +--- a/arch/mips/include/asm/dmi.h ++++ b/arch/mips/include/asm/dmi.h +@@ -5,7 +5,7 @@ + #include + #include + +-#define dmi_early_remap(x, l) ioremap_cache(x, l) ++#define dmi_early_remap(x, l) ioremap(x, l) + #define dmi_early_unmap(x, l) iounmap(x) + #define dmi_remap(x, l) ioremap_cache(x, l) + #define dmi_unmap(x) iounmap(x) +diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c +index cb871eb784a7c..f88a2f83c5eac 100644 +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -326,11 +326,11 @@ static void __init bootmem_init(void) + panic("Incorrect memory mapping !!!"); + + if (max_pfn > PFN_DOWN(HIGHMEM_START)) { ++ max_low_pfn = PFN_DOWN(HIGHMEM_START); + #ifdef CONFIG_HIGHMEM +- highstart_pfn = PFN_DOWN(HIGHMEM_START); ++ highstart_pfn = max_low_pfn; + highend_pfn = max_pfn; + #else +- max_low_pfn = PFN_DOWN(HIGHMEM_START); + max_pfn = max_low_pfn; + #endif + } +diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c +index 8fbef537fb885..81f6c4f8fbc15 100644 +--- a/arch/mips/kernel/smp.c ++++ b/arch/mips/kernel/smp.c +@@ -351,10 +351,11 @@ early_initcall(mips_smp_ipi_init); + */ + asmlinkage void start_secondary(void) + { +- unsigned int cpu; ++ unsigned int cpu = raw_smp_processor_id(); + + cpu_probe(); + per_cpu_trap_init(false); ++ rcu_cpu_starting(cpu); + mips_clockevent_init(); + mp_ops->init_secondary(); + cpu_report(); +@@ -366,7 +367,6 @@ asmlinkage void start_secondary(void) + */ + + calibrate_delay(); +- cpu = smp_processor_id(); + cpu_data[cpu].udelay_val = loops_per_jiffy; + + set_cpu_sibling_map(cpu); +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index 4640cee33f123..2fe51e0ad6371 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -857,6 +857,7 @@ config THREAD_SHIFT + int "Thread shift" if EXPERT + range 13 15 + default "15" if PPC_256K_PAGES ++ default "15" if PPC_PSERIES || PPC_POWERNV + default "14" if PPC64 + default "13" + help +diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c +index eddc031c4b95f..87d65bdd3ecae 100644 +--- a/arch/powerpc/kernel/rtas.c ++++ b/arch/powerpc/kernel/rtas.c +@@ -544,6 +544,21 @@ static int __init rtas_token_to_function_xarray_init(void) + } + arch_initcall(rtas_token_to_function_xarray_init); + ++/* ++ * For use by sys_rtas(), where the token value is provided by user ++ * space and we don't want to warn on failed lookups. ++ */ ++static const struct rtas_function *rtas_token_to_function_untrusted(s32 token) ++{ ++ return xa_load(&rtas_token_to_function_xarray, token); ++} ++ ++/* ++ * Reverse lookup for deriving the function descriptor from a ++ * known-good token value in contexts where the former is not already ++ * available. @token must be valid, e.g. derived from the result of a ++ * prior lookup against the function table. ++ */ + static const struct rtas_function *rtas_token_to_function(s32 token) + { + const struct rtas_function *func; +@@ -551,7 +566,7 @@ static const struct rtas_function *rtas_token_to_function(s32 token) + if (WARN_ONCE(token < 0, "invalid token %d", token)) + return NULL; + +- func = xa_load(&rtas_token_to_function_xarray, token); ++ func = rtas_token_to_function_untrusted(token); + + if (WARN_ONCE(!func, "unexpected failed lookup for token %d", token)) + return NULL; +@@ -1726,7 +1741,7 @@ static bool block_rtas_call(int token, int nargs, + * If this token doesn't correspond to a function the kernel + * understands, you're not allowed to call it. + */ +- func = rtas_token_to_function(token); ++ func = rtas_token_to_function_untrusted(token); + if (!func) + goto err; + /* +diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c +index efd0ebf70a5e6..fdfc2a62dd67d 100644 +--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c ++++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c +@@ -28,6 +28,7 @@ + #include + + #include "book3s.h" ++#include "book3s_hv.h" + #include "trace_hv.h" + + //#define DEBUG_RESIZE_HPT 1 +@@ -347,7 +348,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, + unsigned long v, orig_v, gr; + __be64 *hptep; + long int index; +- int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); ++ int virtmode = __kvmppc_get_msr_hv(vcpu) & (data ? MSR_DR : MSR_IR); + + if (kvm_is_radix(vcpu->kvm)) + return kvmppc_mmu_radix_xlate(vcpu, eaddr, gpte, data, iswrite); +@@ -385,7 +386,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, + + /* Get PP bits and key for permission check */ + pp = gr & (HPTE_R_PP0 | HPTE_R_PP); +- key = (vcpu->arch.shregs.msr & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS; ++ key = (__kvmppc_get_msr_hv(vcpu) & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS; + key &= slb_v; + + /* Calculate permissions */ +diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c +index 572707858d65d..10aacbf92466a 100644 +--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c ++++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c +@@ -15,6 +15,7 @@ + + #include + #include ++#include "book3s_hv.h" + #include + #include + #include +@@ -294,9 +295,9 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, + } else { + if (!(pte & _PAGE_PRIVILEGED)) { + /* Check AMR/IAMR to see if strict mode is in force */ +- if (vcpu->arch.amr & (1ul << 62)) ++ if (kvmppc_get_amr_hv(vcpu) & (1ul << 62)) + gpte->may_read = 0; +- if (vcpu->arch.amr & (1ul << 63)) ++ if (kvmppc_get_amr_hv(vcpu) & (1ul << 63)) + gpte->may_write = 0; + if (vcpu->arch.iamr & (1ul << 62)) + gpte->may_execute = 0; +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index 130bafdb14308..0429488ba170d 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -868,7 +868,7 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, + /* Guests can't breakpoint the hypervisor */ + if ((value1 & CIABR_PRIV) == CIABR_PRIV_HYPER) + return H_P3; +- vcpu->arch.ciabr = value1; ++ kvmppc_set_ciabr_hv(vcpu, value1); + return H_SUCCESS; + case H_SET_MODE_RESOURCE_SET_DAWR0: + if (!kvmppc_power8_compatible(vcpu)) +@@ -879,8 +879,8 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, + return H_UNSUPPORTED_FLAG_START; + if (value2 & DABRX_HYP) + return H_P4; +- vcpu->arch.dawr0 = value1; +- vcpu->arch.dawrx0 = value2; ++ kvmppc_set_dawr0_hv(vcpu, value1); ++ kvmppc_set_dawrx0_hv(vcpu, value2); + return H_SUCCESS; + case H_SET_MODE_RESOURCE_SET_DAWR1: + if (!kvmppc_power8_compatible(vcpu)) +@@ -895,8 +895,8 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, + return H_UNSUPPORTED_FLAG_START; + if (value2 & DABRX_HYP) + return H_P4; +- vcpu->arch.dawr1 = value1; +- vcpu->arch.dawrx1 = value2; ++ kvmppc_set_dawr1_hv(vcpu, value1); ++ kvmppc_set_dawrx1_hv(vcpu, value2); + return H_SUCCESS; + case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE: + /* +@@ -1370,7 +1370,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) + */ + static void kvmppc_cede(struct kvm_vcpu *vcpu) + { +- vcpu->arch.shregs.msr |= MSR_EE; ++ __kvmppc_set_msr_hv(vcpu, __kvmppc_get_msr_hv(vcpu) | MSR_EE); + vcpu->arch.ceded = 1; + smp_mb(); + if (vcpu->arch.prodded) { +@@ -1544,7 +1544,7 @@ static int kvmppc_pmu_unavailable(struct kvm_vcpu *vcpu) + if (!(vcpu->arch.hfscr_permitted & HFSCR_PM)) + return EMULATE_FAIL; + +- vcpu->arch.hfscr |= HFSCR_PM; ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_PM); + + return RESUME_GUEST; + } +@@ -1554,7 +1554,7 @@ static int kvmppc_ebb_unavailable(struct kvm_vcpu *vcpu) + if (!(vcpu->arch.hfscr_permitted & HFSCR_EBB)) + return EMULATE_FAIL; + +- vcpu->arch.hfscr |= HFSCR_EBB; ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_EBB); + + return RESUME_GUEST; + } +@@ -1564,7 +1564,7 @@ static int kvmppc_tm_unavailable(struct kvm_vcpu *vcpu) + if (!(vcpu->arch.hfscr_permitted & HFSCR_TM)) + return EMULATE_FAIL; + +- vcpu->arch.hfscr |= HFSCR_TM; ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_TM); + + return RESUME_GUEST; + } +@@ -1585,7 +1585,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + * That can happen due to a bug, or due to a machine check + * occurring at just the wrong time. + */ +- if (vcpu->arch.shregs.msr & MSR_HV) { ++ if (__kvmppc_get_msr_hv(vcpu) & MSR_HV) { + printk(KERN_EMERG "KVM trap in HV mode!\n"); + printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", + vcpu->arch.trap, kvmppc_get_pc(vcpu), +@@ -1636,7 +1636,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + * so that it knows that the machine check occurred. + */ + if (!vcpu->kvm->arch.fwnmi_enabled) { +- ulong flags = (vcpu->arch.shregs.msr & 0x083c0000) | ++ ulong flags = (__kvmppc_get_msr_hv(vcpu) & 0x083c0000) | + (kvmppc_get_msr(vcpu) & SRR1_PREFIXED); + kvmppc_core_queue_machine_check(vcpu, flags); + r = RESUME_GUEST; +@@ -1666,7 +1666,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + * as a result of a hypervisor emulation interrupt + * (e40) getting turned into a 700 by BML RTAS. + */ +- flags = (vcpu->arch.shregs.msr & 0x1f0000ull) | ++ flags = (__kvmppc_get_msr_hv(vcpu) & 0x1f0000ull) | + (kvmppc_get_msr(vcpu) & SRR1_PREFIXED); + kvmppc_core_queue_program(vcpu, flags); + r = RESUME_GUEST; +@@ -1676,7 +1676,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + { + int i; + +- if (unlikely(vcpu->arch.shregs.msr & MSR_PR)) { ++ if (unlikely(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { + /* + * Guest userspace executed sc 1. This can only be + * reached by the P9 path because the old path +@@ -1754,7 +1754,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + break; + } + +- if (!(vcpu->arch.shregs.msr & MSR_DR)) ++ if (!(__kvmppc_get_msr_hv(vcpu) & MSR_DR)) + vsid = vcpu->kvm->arch.vrma_slb_v; + else + vsid = vcpu->arch.fault_gpa; +@@ -1778,7 +1778,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + long err; + + vcpu->arch.fault_dar = kvmppc_get_pc(vcpu); +- vcpu->arch.fault_dsisr = vcpu->arch.shregs.msr & ++ vcpu->arch.fault_dsisr = __kvmppc_get_msr_hv(vcpu) & + DSISR_SRR1_MATCH_64S; + if (kvm_is_radix(vcpu->kvm) || !cpu_has_feature(CPU_FTR_ARCH_300)) { + /* +@@ -1787,7 +1787,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + * hash fault handling below is v3 only (it uses ASDR + * via fault_gpa). + */ +- if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) ++ if (__kvmppc_get_msr_hv(vcpu) & HSRR1_HISI_WRITE) + vcpu->arch.fault_dsisr |= DSISR_ISSTORE; + r = RESUME_PAGE_FAULT; + break; +@@ -1801,7 +1801,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + break; + } + +- if (!(vcpu->arch.shregs.msr & MSR_IR)) ++ if (!(__kvmppc_get_msr_hv(vcpu) & MSR_IR)) + vsid = vcpu->kvm->arch.vrma_slb_v; + else + vsid = vcpu->arch.fault_gpa; +@@ -1863,7 +1863,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + * Otherwise, we just generate a program interrupt to the guest. + */ + case BOOK3S_INTERRUPT_H_FAC_UNAVAIL: { +- u64 cause = vcpu->arch.hfscr >> 56; ++ u64 cause = kvmppc_get_hfscr_hv(vcpu) >> 56; + + r = EMULATE_FAIL; + if (cpu_has_feature(CPU_FTR_ARCH_300)) { +@@ -1891,7 +1891,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, + kvmppc_dump_regs(vcpu); + printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", + vcpu->arch.trap, kvmppc_get_pc(vcpu), +- vcpu->arch.shregs.msr); ++ __kvmppc_get_msr_hv(vcpu)); + run->hw.hardware_exit_reason = vcpu->arch.trap; + r = RESUME_HOST; + break; +@@ -1915,11 +1915,11 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) + * That can happen due to a bug, or due to a machine check + * occurring at just the wrong time. + */ +- if (vcpu->arch.shregs.msr & MSR_HV) { ++ if (__kvmppc_get_msr_hv(vcpu) & MSR_HV) { + pr_emerg("KVM trap in HV mode while nested!\n"); + pr_emerg("trap=0x%x | pc=0x%lx | msr=0x%llx\n", + vcpu->arch.trap, kvmppc_get_pc(vcpu), +- vcpu->arch.shregs.msr); ++ __kvmppc_get_msr_hv(vcpu)); + kvmppc_dump_regs(vcpu); + return RESUME_HOST; + } +@@ -1976,7 +1976,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) + vcpu->arch.fault_dar = kvmppc_get_pc(vcpu); + vcpu->arch.fault_dsisr = kvmppc_get_msr(vcpu) & + DSISR_SRR1_MATCH_64S; +- if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) ++ if (__kvmppc_get_msr_hv(vcpu) & HSRR1_HISI_WRITE) + vcpu->arch.fault_dsisr |= DSISR_ISSTORE; + srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + r = kvmhv_nested_page_fault(vcpu); +@@ -2207,64 +2207,64 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + *val = get_reg_val(id, vcpu->arch.dabrx); + break; + case KVM_REG_PPC_DSCR: +- *val = get_reg_val(id, vcpu->arch.dscr); ++ *val = get_reg_val(id, kvmppc_get_dscr_hv(vcpu)); + break; + case KVM_REG_PPC_PURR: +- *val = get_reg_val(id, vcpu->arch.purr); ++ *val = get_reg_val(id, kvmppc_get_purr_hv(vcpu)); + break; + case KVM_REG_PPC_SPURR: +- *val = get_reg_val(id, vcpu->arch.spurr); ++ *val = get_reg_val(id, kvmppc_get_spurr_hv(vcpu)); + break; + case KVM_REG_PPC_AMR: +- *val = get_reg_val(id, vcpu->arch.amr); ++ *val = get_reg_val(id, kvmppc_get_amr_hv(vcpu)); + break; + case KVM_REG_PPC_UAMOR: +- *val = get_reg_val(id, vcpu->arch.uamor); ++ *val = get_reg_val(id, kvmppc_get_uamor_hv(vcpu)); + break; + case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCR1: + i = id - KVM_REG_PPC_MMCR0; +- *val = get_reg_val(id, vcpu->arch.mmcr[i]); ++ *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, i)); + break; + case KVM_REG_PPC_MMCR2: +- *val = get_reg_val(id, vcpu->arch.mmcr[2]); ++ *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, 2)); + break; + case KVM_REG_PPC_MMCRA: +- *val = get_reg_val(id, vcpu->arch.mmcra); ++ *val = get_reg_val(id, kvmppc_get_mmcra_hv(vcpu)); + break; + case KVM_REG_PPC_MMCRS: + *val = get_reg_val(id, vcpu->arch.mmcrs); + break; + case KVM_REG_PPC_MMCR3: +- *val = get_reg_val(id, vcpu->arch.mmcr[3]); ++ *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, 3)); + break; + case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: + i = id - KVM_REG_PPC_PMC1; +- *val = get_reg_val(id, vcpu->arch.pmc[i]); ++ *val = get_reg_val(id, kvmppc_get_pmc_hv(vcpu, i)); + break; + case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2: + i = id - KVM_REG_PPC_SPMC1; + *val = get_reg_val(id, vcpu->arch.spmc[i]); + break; + case KVM_REG_PPC_SIAR: +- *val = get_reg_val(id, vcpu->arch.siar); ++ *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); + break; + case KVM_REG_PPC_SDAR: +- *val = get_reg_val(id, vcpu->arch.sdar); ++ *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); + break; + case KVM_REG_PPC_SIER: +- *val = get_reg_val(id, vcpu->arch.sier[0]); ++ *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0)); + break; + case KVM_REG_PPC_SIER2: +- *val = get_reg_val(id, vcpu->arch.sier[1]); ++ *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 1)); + break; + case KVM_REG_PPC_SIER3: +- *val = get_reg_val(id, vcpu->arch.sier[2]); ++ *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 2)); + break; + case KVM_REG_PPC_IAMR: +- *val = get_reg_val(id, vcpu->arch.iamr); ++ *val = get_reg_val(id, kvmppc_get_iamr_hv(vcpu)); + break; + case KVM_REG_PPC_PSPB: +- *val = get_reg_val(id, vcpu->arch.pspb); ++ *val = get_reg_val(id, kvmppc_get_pspb_hv(vcpu)); + break; + case KVM_REG_PPC_DPDES: + /* +@@ -2282,19 +2282,19 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + *val = get_reg_val(id, vcpu->arch.vcore->vtb); + break; + case KVM_REG_PPC_DAWR: +- *val = get_reg_val(id, vcpu->arch.dawr0); ++ *val = get_reg_val(id, kvmppc_get_dawr0_hv(vcpu)); + break; + case KVM_REG_PPC_DAWRX: +- *val = get_reg_val(id, vcpu->arch.dawrx0); ++ *val = get_reg_val(id, kvmppc_get_dawrx0_hv(vcpu)); + break; + case KVM_REG_PPC_DAWR1: +- *val = get_reg_val(id, vcpu->arch.dawr1); ++ *val = get_reg_val(id, kvmppc_get_dawr1_hv(vcpu)); + break; + case KVM_REG_PPC_DAWRX1: +- *val = get_reg_val(id, vcpu->arch.dawrx1); ++ *val = get_reg_val(id, kvmppc_get_dawrx1_hv(vcpu)); + break; + case KVM_REG_PPC_CIABR: +- *val = get_reg_val(id, vcpu->arch.ciabr); ++ *val = get_reg_val(id, kvmppc_get_ciabr_hv(vcpu)); + break; + case KVM_REG_PPC_CSIGR: + *val = get_reg_val(id, vcpu->arch.csigr); +@@ -2312,7 +2312,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + *val = get_reg_val(id, vcpu->arch.acop); + break; + case KVM_REG_PPC_WORT: +- *val = get_reg_val(id, vcpu->arch.wort); ++ *val = get_reg_val(id, kvmppc_get_wort_hv(vcpu)); + break; + case KVM_REG_PPC_TIDR: + *val = get_reg_val(id, vcpu->arch.tid); +@@ -2345,7 +2345,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + *val = get_reg_val(id, vcpu->arch.vcore->lpcr); + break; + case KVM_REG_PPC_PPR: +- *val = get_reg_val(id, vcpu->arch.ppr); ++ *val = get_reg_val(id, kvmppc_get_ppr_hv(vcpu)); + break; + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM + case KVM_REG_PPC_TFHAR: +@@ -2425,6 +2425,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + case KVM_REG_PPC_PTCR: + *val = get_reg_val(id, vcpu->kvm->arch.l1_ptcr); + break; ++ case KVM_REG_PPC_FSCR: ++ *val = get_reg_val(id, kvmppc_get_fscr_hv(vcpu)); ++ break; + default: + r = -EINVAL; + break; +@@ -2453,29 +2456,29 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + vcpu->arch.dabrx = set_reg_val(id, *val) & ~DABRX_HYP; + break; + case KVM_REG_PPC_DSCR: +- vcpu->arch.dscr = set_reg_val(id, *val); ++ kvmppc_set_dscr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_PURR: +- vcpu->arch.purr = set_reg_val(id, *val); ++ kvmppc_set_purr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SPURR: +- vcpu->arch.spurr = set_reg_val(id, *val); ++ kvmppc_set_spurr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_AMR: +- vcpu->arch.amr = set_reg_val(id, *val); ++ kvmppc_set_amr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_UAMOR: +- vcpu->arch.uamor = set_reg_val(id, *val); ++ kvmppc_set_uamor_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCR1: + i = id - KVM_REG_PPC_MMCR0; +- vcpu->arch.mmcr[i] = set_reg_val(id, *val); ++ kvmppc_set_mmcr_hv(vcpu, i, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_MMCR2: +- vcpu->arch.mmcr[2] = set_reg_val(id, *val); ++ kvmppc_set_mmcr_hv(vcpu, 2, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_MMCRA: +- vcpu->arch.mmcra = set_reg_val(id, *val); ++ kvmppc_set_mmcra_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_MMCRS: + vcpu->arch.mmcrs = set_reg_val(id, *val); +@@ -2485,32 +2488,32 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + break; + case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: + i = id - KVM_REG_PPC_PMC1; +- vcpu->arch.pmc[i] = set_reg_val(id, *val); ++ kvmppc_set_pmc_hv(vcpu, i, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2: + i = id - KVM_REG_PPC_SPMC1; + vcpu->arch.spmc[i] = set_reg_val(id, *val); + break; + case KVM_REG_PPC_SIAR: +- vcpu->arch.siar = set_reg_val(id, *val); ++ kvmppc_set_siar_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SDAR: +- vcpu->arch.sdar = set_reg_val(id, *val); ++ kvmppc_set_sdar_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SIER: +- vcpu->arch.sier[0] = set_reg_val(id, *val); ++ kvmppc_set_sier_hv(vcpu, 0, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SIER2: +- vcpu->arch.sier[1] = set_reg_val(id, *val); ++ kvmppc_set_sier_hv(vcpu, 1, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_SIER3: +- vcpu->arch.sier[2] = set_reg_val(id, *val); ++ kvmppc_set_sier_hv(vcpu, 2, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_IAMR: +- vcpu->arch.iamr = set_reg_val(id, *val); ++ kvmppc_set_iamr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_PSPB: +- vcpu->arch.pspb = set_reg_val(id, *val); ++ kvmppc_set_pspb_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_DPDES: + if (cpu_has_feature(CPU_FTR_ARCH_300)) +@@ -2522,22 +2525,22 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + vcpu->arch.vcore->vtb = set_reg_val(id, *val); + break; + case KVM_REG_PPC_DAWR: +- vcpu->arch.dawr0 = set_reg_val(id, *val); ++ kvmppc_set_dawr0_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_DAWRX: +- vcpu->arch.dawrx0 = set_reg_val(id, *val) & ~DAWRX_HYP; ++ kvmppc_set_dawrx0_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP); + break; + case KVM_REG_PPC_DAWR1: +- vcpu->arch.dawr1 = set_reg_val(id, *val); ++ kvmppc_set_dawr1_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_DAWRX1: +- vcpu->arch.dawrx1 = set_reg_val(id, *val) & ~DAWRX_HYP; ++ kvmppc_set_dawrx1_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP); + break; + case KVM_REG_PPC_CIABR: +- vcpu->arch.ciabr = set_reg_val(id, *val); ++ kvmppc_set_ciabr_hv(vcpu, set_reg_val(id, *val)); + /* Don't allow setting breakpoints in hypervisor code */ +- if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) +- vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ ++ if ((kvmppc_get_ciabr_hv(vcpu) & CIABR_PRIV) == CIABR_PRIV_HYPER) ++ kvmppc_set_ciabr_hv(vcpu, kvmppc_get_ciabr_hv(vcpu) & ~CIABR_PRIV); + break; + case KVM_REG_PPC_CSIGR: + vcpu->arch.csigr = set_reg_val(id, *val); +@@ -2555,7 +2558,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + vcpu->arch.acop = set_reg_val(id, *val); + break; + case KVM_REG_PPC_WORT: +- vcpu->arch.wort = set_reg_val(id, *val); ++ kvmppc_set_wort_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_TIDR: + vcpu->arch.tid = set_reg_val(id, *val); +@@ -2615,7 +2618,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), false); + break; + case KVM_REG_PPC_PPR: +- vcpu->arch.ppr = set_reg_val(id, *val); ++ kvmppc_set_ppr_hv(vcpu, set_reg_val(id, *val)); + break; + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM + case KVM_REG_PPC_TFHAR: +@@ -2699,6 +2702,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, + case KVM_REG_PPC_PTCR: + vcpu->kvm->arch.l1_ptcr = set_reg_val(id, *val); + break; ++ case KVM_REG_PPC_FSCR: ++ kvmppc_set_fscr_hv(vcpu, set_reg_val(id, *val)); ++ break; + default: + r = -EINVAL; + break; +@@ -2916,19 +2922,20 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu) + vcpu->arch.shared_big_endian = false; + #endif + #endif +- vcpu->arch.mmcr[0] = MMCR0_FC; ++ kvmppc_set_mmcr_hv(vcpu, 0, MMCR0_FC); ++ + if (cpu_has_feature(CPU_FTR_ARCH_31)) { +- vcpu->arch.mmcr[0] |= MMCR0_PMCCEXT; +- vcpu->arch.mmcra = MMCRA_BHRB_DISABLE; ++ kvmppc_set_mmcr_hv(vcpu, 0, kvmppc_get_mmcr_hv(vcpu, 0) | MMCR0_PMCCEXT); ++ kvmppc_set_mmcra_hv(vcpu, MMCRA_BHRB_DISABLE); + } + +- vcpu->arch.ctrl = CTRL_RUNLATCH; ++ kvmppc_set_ctrl_hv(vcpu, CTRL_RUNLATCH); + /* default to host PVR, since we can't spoof it */ + kvmppc_set_pvr_hv(vcpu, mfspr(SPRN_PVR)); + spin_lock_init(&vcpu->arch.vpa_update_lock); + spin_lock_init(&vcpu->arch.tbacct_lock); + vcpu->arch.busy_preempt = TB_NIL; +- vcpu->arch.shregs.msr = MSR_ME; ++ __kvmppc_set_msr_hv(vcpu, MSR_ME); + vcpu->arch.intr_msr = MSR_SF | MSR_ME; + + /* +@@ -2938,29 +2945,30 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu) + * don't set the HFSCR_MSGP bit, and that causes those instructions + * to trap and then we emulate them. + */ +- vcpu->arch.hfscr = HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB | +- HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP; ++ kvmppc_set_hfscr_hv(vcpu, HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB | ++ HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP); + + /* On POWER10 and later, allow prefixed instructions */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) +- vcpu->arch.hfscr |= HFSCR_PREFIX; ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_PREFIX); + + if (cpu_has_feature(CPU_FTR_HVMODE)) { +- vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) & mfspr(SPRN_HFSCR)); ++ + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM + if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) +- vcpu->arch.hfscr |= HFSCR_TM; ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_TM); + #endif + } + if (cpu_has_feature(CPU_FTR_TM_COMP)) + vcpu->arch.hfscr |= HFSCR_TM; + +- vcpu->arch.hfscr_permitted = vcpu->arch.hfscr; ++ vcpu->arch.hfscr_permitted = kvmppc_get_hfscr_hv(vcpu); + + /* + * PM, EBB, TM are demand-faulted so start with it clear. + */ +- vcpu->arch.hfscr &= ~(HFSCR_PM | HFSCR_EBB | HFSCR_TM); ++ kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) & ~(HFSCR_PM | HFSCR_EBB | HFSCR_TM)); + + kvmppc_mmu_book3s_hv_init(vcpu); + +@@ -4176,7 +4184,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, + __this_cpu_write(cpu_in_guest, NULL); + + if (trap == BOOK3S_INTERRUPT_SYSCALL && +- !(vcpu->arch.shregs.msr & MSR_PR)) { ++ !(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { + unsigned long req = kvmppc_get_gpr(vcpu, 3); + + /* +@@ -4655,13 +4663,19 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, + + if (!nested) { + kvmppc_core_prepare_to_enter(vcpu); +- if (vcpu->arch.shregs.msr & MSR_EE) { +- if (xive_interrupt_pending(vcpu)) ++ if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, ++ &vcpu->arch.pending_exceptions) || ++ xive_interrupt_pending(vcpu)) { ++ /* ++ * For nested HV, don't synthesize but always pass MER, ++ * the L0 will be able to optimise that more ++ * effectively than manipulating registers directly. ++ */ ++ if (!kvmhv_on_pseries() && (__kvmppc_get_msr_hv(vcpu) & MSR_EE)) + kvmppc_inject_interrupt_hv(vcpu, +- BOOK3S_INTERRUPT_EXTERNAL, 0); +- } else if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, +- &vcpu->arch.pending_exceptions)) { +- lpcr |= LPCR_MER; ++ BOOK3S_INTERRUPT_EXTERNAL, 0); ++ else ++ lpcr |= LPCR_MER; + } + } else if (vcpu->arch.pending_exceptions || + vcpu->arch.doorbell_request || +@@ -4844,7 +4858,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu) + msr |= MSR_VSX; + if ((cpu_has_feature(CPU_FTR_TM) || + cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) && +- (vcpu->arch.hfscr & HFSCR_TM)) ++ (kvmppc_get_hfscr_hv(vcpu) & HFSCR_TM)) + msr |= MSR_TM; + msr = msr_check_and_set(msr); + +@@ -4868,7 +4882,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu) + if (run->exit_reason == KVM_EXIT_PAPR_HCALL) { + accumulate_time(vcpu, &vcpu->arch.hcall); + +- if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_PR)) { ++ if (WARN_ON_ONCE(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { + /* + * These should have been caught reflected + * into the guest by now. Final sanity check: +diff --git a/arch/powerpc/kvm/book3s_hv.h b/arch/powerpc/kvm/book3s_hv.h +index 2f2e59d7d433a..95241764dfb4e 100644 +--- a/arch/powerpc/kvm/book3s_hv.h ++++ b/arch/powerpc/kvm/book3s_hv.h +@@ -50,3 +50,71 @@ void accumulate_time(struct kvm_vcpu *vcpu, struct kvmhv_tb_accumulator *next); + #define start_timing(vcpu, next) do {} while (0) + #define end_timing(vcpu) do {} while (0) + #endif ++ ++static inline void __kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 val) ++{ ++ vcpu->arch.shregs.msr = val; ++} ++ ++static inline u64 __kvmppc_get_msr_hv(struct kvm_vcpu *vcpu) ++{ ++ return vcpu->arch.shregs.msr; ++} ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size) \ ++static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, u##size val) \ ++{ \ ++ vcpu->arch.reg = val; \ ++} ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size) \ ++static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu) \ ++{ \ ++ return vcpu->arch.reg; \ ++} ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(reg, size) \ ++ KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size) \ ++ KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size) \ ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size) \ ++static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, int i, u##size val) \ ++{ \ ++ vcpu->arch.reg[i] = val; \ ++} ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size) \ ++static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu, int i) \ ++{ \ ++ return vcpu->arch.reg[i]; \ ++} ++ ++#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(reg, size) \ ++ KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size) \ ++ KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size) \ ++ ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(mmcra, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hfscr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(fscr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dscr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(purr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(spurr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(amr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(uamor, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(siar, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(sdar, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(iamr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr0, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ctrl, 64) ++ ++KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(mmcr, 64) ++KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(sier, 64) ++KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(pmc, 32) ++ ++KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(pspb, 32) +diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c +index 0f5b021fa5590..663f5222f3d06 100644 +--- a/arch/powerpc/kvm/book3s_hv_builtin.c ++++ b/arch/powerpc/kvm/book3s_hv_builtin.c +@@ -32,6 +32,7 @@ + + #include "book3s_xics.h" + #include "book3s_xive.h" ++#include "book3s_hv.h" + + /* + * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) +@@ -510,7 +511,7 @@ void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr) + */ + if ((msr & MSR_TS_MASK) == MSR_TS_MASK) + msr &= ~MSR_TS_MASK; +- vcpu->arch.shregs.msr = msr; ++ __kvmppc_set_msr_hv(vcpu, msr); + kvmppc_end_cede(vcpu); + } + EXPORT_SYMBOL_GPL(kvmppc_set_msr_hv); +@@ -548,7 +549,7 @@ static void inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags) + kvmppc_set_srr0(vcpu, pc); + kvmppc_set_srr1(vcpu, (msr & SRR1_MSR_BITS) | srr1_flags); + kvmppc_set_pc(vcpu, new_pc); +- vcpu->arch.shregs.msr = new_msr; ++ __kvmppc_set_msr_hv(vcpu, new_msr); + } + + void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags) +diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile +index 51ad0397c17ab..6eac63e79a899 100644 +--- a/arch/powerpc/lib/Makefile ++++ b/arch/powerpc/lib/Makefile +@@ -45,7 +45,7 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o + # so it is only needed for modules, and only for older linkers which + # do not support --save-restore-funcs + ifndef CONFIG_LD_IS_BFD +-extra-$(CONFIG_PPC64) += crtsavres.o ++always-$(CONFIG_PPC64) += crtsavres.o + endif + + obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ +diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c +index 39dbe6b348df2..27f18119fda17 100644 +--- a/arch/powerpc/perf/hv-gpci.c ++++ b/arch/powerpc/perf/hv-gpci.c +@@ -534,6 +534,9 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev + if (!ret) + goto parse_result; + ++ if (ret && (ret != H_PARAMETER)) ++ goto out; ++ + /* + * ret value as 'H_PARAMETER' implies that the current buffer size + * can't accommodate all the information, and a partial buffer +diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c +index ada817c49b722..56d82f7f9734e 100644 +--- a/arch/powerpc/perf/imc-pmu.c ++++ b/arch/powerpc/perf/imc-pmu.c +@@ -299,6 +299,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + attr_group->attrs = attrs; + do { + ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value); ++ if (!ev_val_str) ++ continue; + dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str); + if (!dev_str) + continue; +@@ -306,6 +308,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + attrs[j++] = dev_str; + if (pmu->events[i].scale) { + ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name); ++ if (!ev_scale_str) ++ continue; + dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale); + if (!dev_str) + continue; +@@ -315,6 +319,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) + + if (pmu->events[i].unit) { + ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name); ++ if (!ev_unit_str) ++ continue; + dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit); + if (!dev_str) + continue; +diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig +index 1624ebf95497b..35a1f4b9f8272 100644 +--- a/arch/powerpc/platforms/44x/Kconfig ++++ b/arch/powerpc/platforms/44x/Kconfig +@@ -173,6 +173,7 @@ config ISS4xx + config CURRITUCK + bool "IBM Currituck (476fpe) Support" + depends on PPC_47x ++ select I2C + select SWIOTLB + select 476FPE + select FORCE_PCI +diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c +index f9a7001dacb7a..56a1f7ce78d2c 100644 +--- a/arch/powerpc/platforms/powernv/opal-irqchip.c ++++ b/arch/powerpc/platforms/powernv/opal-irqchip.c +@@ -275,6 +275,8 @@ int __init opal_event_init(void) + else + name = kasprintf(GFP_KERNEL, "opal"); + ++ if (!name) ++ continue; + /* Install interrupt handler */ + rc = request_irq(r->start, opal_interrupt, r->flags & IRQD_TRIGGER_MASK, + name, NULL); +diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c +index 7bfe4cbeb35a9..ea917266aa172 100644 +--- a/arch/powerpc/platforms/powernv/opal-powercap.c ++++ b/arch/powerpc/platforms/powernv/opal-powercap.c +@@ -196,6 +196,12 @@ void __init opal_powercap_init(void) + + j = 0; + pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node); ++ if (!pcaps[i].pg.name) { ++ kfree(pcaps[i].pattrs); ++ kfree(pcaps[i].pg.attrs); ++ goto out_pcaps_pattrs; ++ } ++ + if (has_min) { + powercap_add_attr(min, "powercap-min", + &pcaps[i].pattrs[j]); +diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c +index 262cd6fac9071..748c2b97fa537 100644 +--- a/arch/powerpc/platforms/powernv/opal-xscom.c ++++ b/arch/powerpc/platforms/powernv/opal-xscom.c +@@ -165,6 +165,11 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, + ent->chip = chip; + snprintf(ent->name, 16, "%08x", chip); + ent->path.data = (void *)kasprintf(GFP_KERNEL, "%pOF", dn); ++ if (!ent->path.data) { ++ kfree(ent); ++ return -ENOMEM; ++ } ++ + ent->path.size = strlen((char *)ent->path.data); + + dir = debugfs_create_dir(ent->name, root); +diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c +index aa4042dcd6d40..4adca5b61daba 100644 +--- a/arch/powerpc/platforms/pseries/hotplug-memory.c ++++ b/arch/powerpc/platforms/pseries/hotplug-memory.c +@@ -435,14 +435,15 @@ static int dlpar_memory_remove_by_index(u32 drc_index) + } + } + +- if (!lmb_found) ++ if (!lmb_found) { ++ pr_debug("Failed to look up LMB for drc index %x\n", drc_index); + rc = -EINVAL; +- +- if (rc) ++ } else if (rc) { + pr_debug("Failed to hot-remove memory at %llx\n", + lmb->base_addr); +- else ++ } else { + pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); ++ } + + return rc; + } +diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h +index 32336e8a17cb0..a393d5035c543 100644 +--- a/arch/riscv/include/asm/sections.h ++++ b/arch/riscv/include/asm/sections.h +@@ -13,6 +13,7 @@ extern char _start_kernel[]; + extern char __init_data_begin[], __init_data_end[]; + extern char __init_text_begin[], __init_text_end[]; + extern char __alt_start[], __alt_end[]; ++extern char __exittext_begin[], __exittext_end[]; + + static inline bool is_va_kernel_text(uintptr_t va) + { +diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h +index d4ffc3c37649f..b65bf6306f69c 100644 +--- a/arch/riscv/include/asm/xip_fixup.h ++++ b/arch/riscv/include/asm/xip_fixup.h +@@ -13,7 +13,7 @@ + add \reg, \reg, t0 + .endm + .macro XIP_FIXUP_FLASH_OFFSET reg +- la t1, __data_loc ++ la t0, __data_loc + REG_L t1, _xip_phys_offset + sub \reg, \reg, t1 + add \reg, \reg, t0 +diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c +index 7c651d55fcbd2..df4f6fec5d174 100644 +--- a/arch/riscv/kernel/module.c ++++ b/arch/riscv/kernel/module.c +@@ -440,7 +440,8 @@ void *module_alloc(unsigned long size) + { + return __vmalloc_node_range(size, 1, MODULES_VADDR, + MODULES_END, GFP_KERNEL, +- PAGE_KERNEL, 0, NUMA_NO_NODE, ++ PAGE_KERNEL, VM_FLUSH_RESET_PERMS, ++ NUMA_NO_NODE, + __builtin_return_address(0)); + } + #endif +diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c +index 13ee7bf589a15..37e87fdcf6a00 100644 +--- a/arch/riscv/kernel/patch.c ++++ b/arch/riscv/kernel/patch.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + struct patch_insn { + void *addr; +@@ -25,6 +26,14 @@ struct patch_insn { + int riscv_patch_in_stop_machine = false; + + #ifdef CONFIG_MMU ++ ++static inline bool is_kernel_exittext(uintptr_t addr) ++{ ++ return system_state < SYSTEM_RUNNING && ++ addr >= (uintptr_t)__exittext_begin && ++ addr < (uintptr_t)__exittext_end; ++} ++ + /* + * The fix_to_virt(, idx) needs a const value (not a dynamic variable of + * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". +@@ -35,7 +44,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap) + uintptr_t uintaddr = (uintptr_t) addr; + struct page *page; + +- if (core_kernel_text(uintaddr)) ++ if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) + page = phys_to_page(__pa_symbol(addr)); + else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + page = vmalloc_to_page(addr); +diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S +index 50767647fbc64..8c3daa1b05313 100644 +--- a/arch/riscv/kernel/vmlinux-xip.lds.S ++++ b/arch/riscv/kernel/vmlinux-xip.lds.S +@@ -29,10 +29,12 @@ SECTIONS + HEAD_TEXT_SECTION + INIT_TEXT_SECTION(PAGE_SIZE) + /* we have to discard exit text and such at runtime, not link time */ ++ __exittext_begin = .; + .exit.text : + { + EXIT_TEXT + } ++ __exittext_end = .; + + .text : { + _text = .; +diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S +index 492dd4b8f3d69..002ca58dd998c 100644 +--- a/arch/riscv/kernel/vmlinux.lds.S ++++ b/arch/riscv/kernel/vmlinux.lds.S +@@ -69,10 +69,12 @@ SECTIONS + __soc_builtin_dtb_table_end = .; + } + /* we have to discard exit text and such at runtime, not link time */ ++ __exittext_begin = .; + .exit.text : + { + EXIT_TEXT + } ++ __exittext_end = .; + + __init_text_end = .; + . = ALIGN(SECTION_ALIGN); +diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c +index 161d0b34c2cb2..01398fee5cf82 100644 +--- a/arch/riscv/mm/pageattr.c ++++ b/arch/riscv/mm/pageattr.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -25,19 +26,6 @@ static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk) + return new_val; + } + +-static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr, +- unsigned long next, struct mm_walk *walk) +-{ +- pgd_t val = READ_ONCE(*pgd); +- +- if (pgd_leaf(val)) { +- val = __pgd(set_pageattr_masks(pgd_val(val), walk)); +- set_pgd(pgd, val); +- } +- +- return 0; +-} +- + static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, + unsigned long next, struct mm_walk *walk) + { +@@ -96,7 +84,6 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next, + } + + static const struct mm_walk_ops pageattr_ops = { +- .pgd_entry = pageattr_pgd_entry, + .p4d_entry = pageattr_p4d_entry, + .pud_entry = pageattr_pud_entry, + .pmd_entry = pageattr_pmd_entry, +@@ -105,12 +92,181 @@ static const struct mm_walk_ops pageattr_ops = { + .walk_lock = PGWALK_RDLOCK, + }; + ++#ifdef CONFIG_64BIT ++static int __split_linear_mapping_pmd(pud_t *pudp, ++ unsigned long vaddr, unsigned long end) ++{ ++ pmd_t *pmdp; ++ unsigned long next; ++ ++ pmdp = pmd_offset(pudp, vaddr); ++ ++ do { ++ next = pmd_addr_end(vaddr, end); ++ ++ if (next - vaddr >= PMD_SIZE && ++ vaddr <= (vaddr & PMD_MASK) && end >= next) ++ continue; ++ ++ if (pmd_leaf(*pmdp)) { ++ struct page *pte_page; ++ unsigned long pfn = _pmd_pfn(*pmdp); ++ pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK); ++ pte_t *ptep_new; ++ int i; ++ ++ pte_page = alloc_page(GFP_KERNEL); ++ if (!pte_page) ++ return -ENOMEM; ++ ++ ptep_new = (pte_t *)page_address(pte_page); ++ for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new) ++ set_pte(ptep_new, pfn_pte(pfn + i, prot)); ++ ++ smp_wmb(); ++ ++ set_pmd(pmdp, pfn_pmd(page_to_pfn(pte_page), PAGE_TABLE)); ++ } ++ } while (pmdp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_pud(p4d_t *p4dp, ++ unsigned long vaddr, unsigned long end) ++{ ++ pud_t *pudp; ++ unsigned long next; ++ int ret; ++ ++ pudp = pud_offset(p4dp, vaddr); ++ ++ do { ++ next = pud_addr_end(vaddr, end); ++ ++ if (next - vaddr >= PUD_SIZE && ++ vaddr <= (vaddr & PUD_MASK) && end >= next) ++ continue; ++ ++ if (pud_leaf(*pudp)) { ++ struct page *pmd_page; ++ unsigned long pfn = _pud_pfn(*pudp); ++ pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK); ++ pmd_t *pmdp_new; ++ int i; ++ ++ pmd_page = alloc_page(GFP_KERNEL); ++ if (!pmd_page) ++ return -ENOMEM; ++ ++ pmdp_new = (pmd_t *)page_address(pmd_page); ++ for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new) ++ set_pmd(pmdp_new, ++ pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot)); ++ ++ smp_wmb(); ++ ++ set_pud(pudp, pfn_pud(page_to_pfn(pmd_page), PAGE_TABLE)); ++ } ++ ++ ret = __split_linear_mapping_pmd(pudp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (pudp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_p4d(pgd_t *pgdp, ++ unsigned long vaddr, unsigned long end) ++{ ++ p4d_t *p4dp; ++ unsigned long next; ++ int ret; ++ ++ p4dp = p4d_offset(pgdp, vaddr); ++ ++ do { ++ next = p4d_addr_end(vaddr, end); ++ ++ /* ++ * If [vaddr; end] contains [vaddr & P4D_MASK; next], we don't ++ * need to split, we'll change the protections on the whole P4D. ++ */ ++ if (next - vaddr >= P4D_SIZE && ++ vaddr <= (vaddr & P4D_MASK) && end >= next) ++ continue; ++ ++ if (p4d_leaf(*p4dp)) { ++ struct page *pud_page; ++ unsigned long pfn = _p4d_pfn(*p4dp); ++ pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK); ++ pud_t *pudp_new; ++ int i; ++ ++ pud_page = alloc_page(GFP_KERNEL); ++ if (!pud_page) ++ return -ENOMEM; ++ ++ /* ++ * Fill the pud level with leaf puds that have the same ++ * protections as the leaf p4d. ++ */ ++ pudp_new = (pud_t *)page_address(pud_page); ++ for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new) ++ set_pud(pudp_new, ++ pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot)); ++ ++ /* ++ * Make sure the pud filling is not reordered with the ++ * p4d store which could result in seeing a partially ++ * filled pud level. ++ */ ++ smp_wmb(); ++ ++ set_p4d(p4dp, pfn_p4d(page_to_pfn(pud_page), PAGE_TABLE)); ++ } ++ ++ ret = __split_linear_mapping_pud(p4dp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (p4dp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int __split_linear_mapping_pgd(pgd_t *pgdp, ++ unsigned long vaddr, ++ unsigned long end) ++{ ++ unsigned long next; ++ int ret; ++ ++ do { ++ next = pgd_addr_end(vaddr, end); ++ /* We never use PGD mappings for the linear mapping */ ++ ret = __split_linear_mapping_p4d(pgdp, vaddr, next); ++ if (ret) ++ return ret; ++ } while (pgdp++, vaddr = next, vaddr != end); ++ ++ return 0; ++} ++ ++static int split_linear_mapping(unsigned long start, unsigned long end) ++{ ++ return __split_linear_mapping_pgd(pgd_offset_k(start), start, end); ++} ++#endif /* CONFIG_64BIT */ ++ + static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, + pgprot_t clear_mask) + { + int ret; + unsigned long start = addr; + unsigned long end = start + PAGE_SIZE * numpages; ++ unsigned long __maybe_unused lm_start; ++ unsigned long __maybe_unused lm_end; + struct pageattr_masks masks = { + .set_mask = set_mask, + .clear_mask = clear_mask +@@ -120,11 +276,72 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, + return 0; + + mmap_write_lock(&init_mm); ++ ++#ifdef CONFIG_64BIT ++ /* ++ * We are about to change the permissions of a kernel mapping, we must ++ * apply the same changes to its linear mapping alias, which may imply ++ * splitting a huge mapping. ++ */ ++ ++ if (is_vmalloc_or_module_addr((void *)start)) { ++ struct vm_struct *area = NULL; ++ int i, page_start; ++ ++ area = find_vm_area((void *)start); ++ page_start = (start - (unsigned long)area->addr) >> PAGE_SHIFT; ++ ++ for (i = page_start; i < page_start + numpages; ++i) { ++ lm_start = (unsigned long)page_address(area->pages[i]); ++ lm_end = lm_start + PAGE_SIZE; ++ ++ ret = split_linear_mapping(lm_start, lm_end); ++ if (ret) ++ goto unlock; ++ ++ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, ++ &pageattr_ops, NULL, &masks); ++ if (ret) ++ goto unlock; ++ } ++ } else if (is_kernel_mapping(start) || is_linear_mapping(start)) { ++ if (is_kernel_mapping(start)) { ++ lm_start = (unsigned long)lm_alias(start); ++ lm_end = (unsigned long)lm_alias(end); ++ } else { ++ lm_start = start; ++ lm_end = end; ++ } ++ ++ ret = split_linear_mapping(lm_start, lm_end); ++ if (ret) ++ goto unlock; ++ ++ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, ++ &pageattr_ops, NULL, &masks); ++ if (ret) ++ goto unlock; ++ } ++ + ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, + &masks); ++ ++unlock: ++ mmap_write_unlock(&init_mm); ++ ++ /* ++ * We can't use flush_tlb_kernel_range() here as we may have split a ++ * hugepage that is larger than that, so let's flush everything. ++ */ ++ flush_tlb_all(); ++#else ++ ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, ++ &masks); ++ + mmap_write_unlock(&init_mm); + + flush_tlb_kernel_range(start, end); ++#endif + + return ret; + } +@@ -159,36 +376,14 @@ int set_memory_nx(unsigned long addr, int numpages) + + int set_direct_map_invalid_noflush(struct page *page) + { +- int ret; +- unsigned long start = (unsigned long)page_address(page); +- unsigned long end = start + PAGE_SIZE; +- struct pageattr_masks masks = { +- .set_mask = __pgprot(0), +- .clear_mask = __pgprot(_PAGE_PRESENT) +- }; +- +- mmap_read_lock(&init_mm); +- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +- mmap_read_unlock(&init_mm); +- +- return ret; ++ return __set_memory((unsigned long)page_address(page), 1, ++ __pgprot(0), __pgprot(_PAGE_PRESENT)); + } + + int set_direct_map_default_noflush(struct page *page) + { +- int ret; +- unsigned long start = (unsigned long)page_address(page); +- unsigned long end = start + PAGE_SIZE; +- struct pageattr_masks masks = { +- .set_mask = PAGE_KERNEL, +- .clear_mask = __pgprot(0) +- }; +- +- mmap_read_lock(&init_mm); +- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); +- mmap_read_unlock(&init_mm); +- +- return ret; ++ return __set_memory((unsigned long)page_address(page), 1, ++ PAGE_KERNEL, __pgprot(_PAGE_EXEC)); + } + + #ifdef CONFIG_DEBUG_PAGEALLOC +diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h +index 287bb88f76986..2686bee800e3d 100644 +--- a/arch/s390/include/asm/pci_io.h ++++ b/arch/s390/include/asm/pci_io.h +@@ -11,6 +11,8 @@ + /* I/O size constraints */ + #define ZPCI_MAX_READ_SIZE 8 + #define ZPCI_MAX_WRITE_SIZE 128 ++#define ZPCI_BOUNDARY_SIZE (1 << 12) ++#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1) + + /* I/O Map */ + #define ZPCI_IOMAP_SHIFT 48 +@@ -125,16 +127,18 @@ out: + int zpci_write_block(volatile void __iomem *dst, const void *src, + unsigned long len); + +-static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) ++static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max) + { +- int count = len > max ? max : len, size = 1; ++ int offset = dst & ZPCI_BOUNDARY_MASK; ++ int size; + +- while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { +- dst = dst >> 1; +- src = src >> 1; +- size = size << 1; +- } +- return size; ++ size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max); ++ if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8)) ++ return size; ++ ++ if (size >= 8) ++ return 8; ++ return rounddown_pow_of_two(size); + } + + static inline int zpci_memcpy_fromio(void *dst, +@@ -144,9 +148,9 @@ static inline int zpci_memcpy_fromio(void *dst, + int size, rc = 0; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) src, +- (u64) dst, n, +- ZPCI_MAX_READ_SIZE); ++ size = zpci_get_max_io_size((u64 __force) src, ++ (u64) dst, n, ++ ZPCI_MAX_READ_SIZE); + rc = zpci_read_single(dst, src, size); + if (rc) + break; +@@ -166,9 +170,9 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst, + return -EINVAL; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) dst, +- (u64) src, n, +- ZPCI_MAX_WRITE_SIZE); ++ size = zpci_get_max_io_size((u64 __force) dst, ++ (u64) src, n, ++ ZPCI_MAX_WRITE_SIZE); + if (size > 8) /* main path */ + rc = zpci_write_block(dst, src, size); + else +diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c +index 5880893329310..a90499c087f0c 100644 +--- a/arch/s390/pci/pci_mmio.c ++++ b/arch/s390/pci/pci_mmio.c +@@ -97,9 +97,9 @@ static inline int __memcpy_toio_inuser(void __iomem *dst, + return -EINVAL; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) dst, +- (u64 __force) src, n, +- ZPCI_MAX_WRITE_SIZE); ++ size = zpci_get_max_io_size((u64 __force) dst, ++ (u64 __force) src, n, ++ ZPCI_MAX_WRITE_SIZE); + if (size > 8) /* main path */ + rc = __pcistb_mio_inuser(dst, src, size, &status); + else +@@ -242,9 +242,9 @@ static inline int __memcpy_fromio_inuser(void __user *dst, + u8 status; + + while (n > 0) { +- size = zpci_get_max_write_size((u64 __force) src, +- (u64 __force) dst, n, +- ZPCI_MAX_READ_SIZE); ++ size = zpci_get_max_io_size((u64 __force) src, ++ (u64 __force) dst, n, ++ ZPCI_MAX_READ_SIZE); + rc = __pcilg_mio_inuser(dst, src, size, &status); + if (rc) + break; +diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c +index ffe2ee8a02465..97a37c0629972 100644 +--- a/arch/um/drivers/virt-pci.c ++++ b/arch/um/drivers/virt-pci.c +@@ -971,7 +971,7 @@ static long um_pci_map_platform(unsigned long offset, size_t size, + *ops = &um_pci_device_bar_ops; + *priv = &um_pci_platform_device->resptr[0]; + +- return 0; ++ return offset; + } + + static const struct logic_iomem_region_ops um_pci_platform_ops = { +diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c +index 8250f0f59c2bb..49bc27ab26ad0 100644 +--- a/arch/x86/events/intel/uncore_snbep.c ++++ b/arch/x86/events/intel/uncore_snbep.c +@@ -5596,7 +5596,7 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i + struct pci_dev *ubox = NULL; + struct pci_dev *dev = NULL; + u32 nid, gid; +- int i, idx, ret = -EPERM; ++ int i, idx, lgc_pkg, ret = -EPERM; + struct intel_uncore_topology *upi; + unsigned int devfn; + +@@ -5614,8 +5614,13 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i + for (i = 0; i < 8; i++) { + if (nid != GIDNIDMAP(gid, i)) + continue; ++ lgc_pkg = topology_phys_to_logical_pkg(i); ++ if (lgc_pkg < 0) { ++ ret = -EPERM; ++ goto err; ++ } + for (idx = 0; idx < type->num_boxes; idx++) { +- upi = &type->topology[nid][idx]; ++ upi = &type->topology[lgc_pkg][idx]; + devfn = PCI_DEVFN(dev_link0 + idx, ICX_UPI_REGS_ADDR_FUNCTION); + dev = pci_get_domain_bus_and_slot(pci_domain_nr(ubox->bus), + ubox->bus->number, +@@ -5626,6 +5631,7 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i + goto err; + } + } ++ break; + } + } + err: +diff --git a/arch/x86/include/asm/kvm-x86-pmu-ops.h b/arch/x86/include/asm/kvm-x86-pmu-ops.h +index 6c98f4bb4228b..058bc636356a1 100644 +--- a/arch/x86/include/asm/kvm-x86-pmu-ops.h ++++ b/arch/x86/include/asm/kvm-x86-pmu-ops.h +@@ -22,7 +22,7 @@ KVM_X86_PMU_OP(get_msr) + KVM_X86_PMU_OP(set_msr) + KVM_X86_PMU_OP(refresh) + KVM_X86_PMU_OP(init) +-KVM_X86_PMU_OP(reset) ++KVM_X86_PMU_OP_OPTIONAL(reset) + KVM_X86_PMU_OP_OPTIONAL(deliver_pmi) + KVM_X86_PMU_OP_OPTIONAL(cleanup) + +diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h +index 778df05f85391..bae83810505bf 100644 +--- a/arch/x86/include/asm/mwait.h ++++ b/arch/x86/include/asm/mwait.h +@@ -115,8 +115,15 @@ static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned lo + } + + __monitor((void *)¤t_thread_info()->flags, 0, 0); +- if (!need_resched()) +- __mwait(eax, ecx); ++ ++ if (!need_resched()) { ++ if (ecx & 1) { ++ __mwait(eax, ecx); ++ } else { ++ __sti_mwait(eax, ecx); ++ raw_local_irq_disable(); ++ } ++ } + } + current_clr_polling(); + } +diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c +index 4d8d4bcf915dd..72f0695c3dc1d 100644 +--- a/arch/x86/kernel/cpu/mce/inject.c ++++ b/arch/x86/kernel/cpu/mce/inject.c +@@ -746,6 +746,7 @@ static void check_hw_inj_possible(void) + + wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); + rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); ++ wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); + + if (!status) { + hw_injection_possible = false; +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index fb8f52149be9a..f2fff625576d5 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -24,8 +24,8 @@ + + static int kvmclock __initdata = 1; + static int kvmclock_vsyscall __initdata = 1; +-static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME; +-static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK; ++static int msr_kvm_system_time __ro_after_init; ++static int msr_kvm_wall_clock __ro_after_init; + static u64 kvm_sched_clock_offset __ro_after_init; + + static int __init parse_no_kvmclock(char *arg) +@@ -195,7 +195,8 @@ static void kvm_setup_secondary_clock(void) + + void kvmclock_disable(void) + { +- native_write_msr(msr_kvm_system_time, 0, 0); ++ if (msr_kvm_system_time) ++ native_write_msr(msr_kvm_system_time, 0, 0); + } + + static void __init kvmclock_init_mem(void) +@@ -294,7 +295,10 @@ void __init kvmclock_init(void) + if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { + msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; + msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; +- } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { ++ } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { ++ msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; ++ msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; ++ } else { + return; + } + +diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c +index 9ae07db6f0f64..dc8e8e907cfbf 100644 +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -250,6 +250,24 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc) + return true; + } + ++static void pmc_release_perf_event(struct kvm_pmc *pmc) ++{ ++ if (pmc->perf_event) { ++ perf_event_release_kernel(pmc->perf_event); ++ pmc->perf_event = NULL; ++ pmc->current_config = 0; ++ pmc_to_pmu(pmc)->event_count--; ++ } ++} ++ ++static void pmc_stop_counter(struct kvm_pmc *pmc) ++{ ++ if (pmc->perf_event) { ++ pmc->counter = pmc_read_counter(pmc); ++ pmc_release_perf_event(pmc); ++ } ++} ++ + static int filter_cmp(const void *pa, const void *pb, u64 mask) + { + u64 a = *(u64 *)pa & mask; +@@ -639,24 +657,53 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + return 0; + } + +-/* refresh PMU settings. This function generally is called when underlying +- * settings are changed (such as changes of PMU CPUID by guest VMs), which +- * should rarely happen. ++void kvm_pmu_reset(struct kvm_vcpu *vcpu) ++{ ++ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); ++ struct kvm_pmc *pmc; ++ int i; ++ ++ pmu->need_cleanup = false; ++ ++ bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX); ++ ++ for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) { ++ pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i); ++ if (!pmc) ++ continue; ++ ++ pmc_stop_counter(pmc); ++ pmc->counter = 0; ++ ++ if (pmc_is_gp(pmc)) ++ pmc->eventsel = 0; ++ } ++ ++ pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0; ++ ++ static_call_cond(kvm_x86_pmu_reset)(vcpu); ++} ++ ++ ++/* ++ * Refresh the PMU configuration for the vCPU, e.g. if userspace changes CPUID ++ * and/or PERF_CAPABILITIES. + */ + void kvm_pmu_refresh(struct kvm_vcpu *vcpu) + { + if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm)) + return; + ++ /* ++ * Stop/release all existing counters/events before realizing the new ++ * vPMU model. ++ */ ++ kvm_pmu_reset(vcpu); ++ + bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX); + static_call(kvm_x86_pmu_refresh)(vcpu); + } + +-void kvm_pmu_reset(struct kvm_vcpu *vcpu) +-{ +- static_call(kvm_x86_pmu_reset)(vcpu); +-} +- + void kvm_pmu_init(struct kvm_vcpu *vcpu) + { + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); +diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h +index 1d64113de4883..a46aa9b25150f 100644 +--- a/arch/x86/kvm/pmu.h ++++ b/arch/x86/kvm/pmu.h +@@ -80,24 +80,6 @@ static inline void pmc_write_counter(struct kvm_pmc *pmc, u64 val) + pmc->counter &= pmc_bitmask(pmc); + } + +-static inline void pmc_release_perf_event(struct kvm_pmc *pmc) +-{ +- if (pmc->perf_event) { +- perf_event_release_kernel(pmc->perf_event); +- pmc->perf_event = NULL; +- pmc->current_config = 0; +- pmc_to_pmu(pmc)->event_count--; +- } +-} +- +-static inline void pmc_stop_counter(struct kvm_pmc *pmc) +-{ +- if (pmc->perf_event) { +- pmc->counter = pmc_read_counter(pmc); +- pmc_release_perf_event(pmc); +- } +-} +- + static inline bool pmc_is_gp(struct kvm_pmc *pmc) + { + return pmc->type == KVM_PMC_GP; +diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c +index 3fea8c47679e6..60891b9ce25f6 100644 +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -247,18 +247,6 @@ static bool nested_svm_check_bitmap_pa(struct kvm_vcpu *vcpu, u64 pa, u32 size) + kvm_vcpu_is_legal_gpa(vcpu, addr + size - 1); + } + +-static bool nested_svm_check_tlb_ctl(struct kvm_vcpu *vcpu, u8 tlb_ctl) +-{ +- /* Nested FLUSHBYASID is not supported yet. */ +- switch(tlb_ctl) { +- case TLB_CONTROL_DO_NOTHING: +- case TLB_CONTROL_FLUSH_ALL_ASID: +- return true; +- default: +- return false; +- } +-} +- + static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu, + struct vmcb_ctrl_area_cached *control) + { +@@ -278,9 +266,6 @@ static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu, + IOPM_SIZE))) + return false; + +- if (CC(!nested_svm_check_tlb_ctl(vcpu, control->tlb_ctl))) +- return false; +- + if (CC((control->int_ctl & V_NMI_ENABLE_MASK) && + !vmcb12_is_intercept(control, INTERCEPT_NMI))) { + return false; +diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c +index 373ff6a6687b3..3fd47de14b38a 100644 +--- a/arch/x86/kvm/svm/pmu.c ++++ b/arch/x86/kvm/svm/pmu.c +@@ -233,21 +233,6 @@ static void amd_pmu_init(struct kvm_vcpu *vcpu) + } + } + +-static void amd_pmu_reset(struct kvm_vcpu *vcpu) +-{ +- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); +- int i; +- +- for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC; i++) { +- struct kvm_pmc *pmc = &pmu->gp_counters[i]; +- +- pmc_stop_counter(pmc); +- pmc->counter = pmc->prev_counter = pmc->eventsel = 0; +- } +- +- pmu->global_ctrl = pmu->global_status = 0; +-} +- + struct kvm_pmu_ops amd_pmu_ops __initdata = { + .hw_event_available = amd_hw_event_available, + .pmc_idx_to_pmc = amd_pmc_idx_to_pmc, +@@ -259,7 +244,6 @@ struct kvm_pmu_ops amd_pmu_ops __initdata = { + .set_msr = amd_pmu_set_msr, + .refresh = amd_pmu_refresh, + .init = amd_pmu_init, +- .reset = amd_pmu_reset, + .EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT, + .MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC, + .MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS, +diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c +index 820d3e1f6b4f8..90c1f7f07e53b 100644 +--- a/arch/x86/kvm/vmx/pmu_intel.c ++++ b/arch/x86/kvm/vmx/pmu_intel.c +@@ -632,26 +632,6 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu) + + static void intel_pmu_reset(struct kvm_vcpu *vcpu) + { +- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); +- struct kvm_pmc *pmc = NULL; +- int i; +- +- for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) { +- pmc = &pmu->gp_counters[i]; +- +- pmc_stop_counter(pmc); +- pmc->counter = pmc->prev_counter = pmc->eventsel = 0; +- } +- +- for (i = 0; i < KVM_PMC_MAX_FIXED; i++) { +- pmc = &pmu->fixed_counters[i]; +- +- pmc_stop_counter(pmc); +- pmc->counter = pmc->prev_counter = 0; +- } +- +- pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0; +- + intel_pmu_release_guest_lbr_event(vcpu); + } + +diff --git a/arch/x86/lib/misc.c b/arch/x86/lib/misc.c +index 92cd8ecc3a2c8..40b81c338ae5b 100644 +--- a/arch/x86/lib/misc.c ++++ b/arch/x86/lib/misc.c +@@ -8,7 +8,7 @@ + */ + int num_digits(int val) + { +- int m = 10; ++ long long m = 10; + int d = 1; + + if (val < 0) { +diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c +index 4b3efaa82ab7c..e9497ee0f8547 100644 +--- a/arch/x86/pci/mmconfig-shared.c ++++ b/arch/x86/pci/mmconfig-shared.c +@@ -525,6 +525,8 @@ static bool __ref is_mmconf_reserved(check_reserved_t is_reserved, + static bool __ref + pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early) + { ++ struct resource *conflict; ++ + if (!early && !acpi_disabled) { + if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, + "ACPI motherboard resource")) +@@ -542,8 +544,17 @@ pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int e + &cfg->res); + + if (is_mmconf_reserved(is_efi_mmio, cfg, dev, +- "EfiMemoryMappedIO")) ++ "EfiMemoryMappedIO")) { ++ conflict = insert_resource_conflict(&iomem_resource, ++ &cfg->res); ++ if (conflict) ++ pr_warn("MMCONFIG %pR conflicts with %s %pR\n", ++ &cfg->res, conflict->name, conflict); ++ else ++ pr_info("MMCONFIG %pR reserved to work around lack of ACPI motherboard _CRS\n", ++ &cfg->res); + return true; ++ } + } + + /* +diff --git a/block/bio.c b/block/bio.c +index 816d412c06e9b..5eba53ca953b4 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -1145,13 +1145,22 @@ EXPORT_SYMBOL(bio_add_folio); + + void __bio_release_pages(struct bio *bio, bool mark_dirty) + { +- struct bvec_iter_all iter_all; +- struct bio_vec *bvec; ++ struct folio_iter fi; ++ ++ bio_for_each_folio_all(fi, bio) { ++ struct page *page; ++ size_t done = 0; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (mark_dirty && !PageCompound(bvec->bv_page)) +- set_page_dirty_lock(bvec->bv_page); +- bio_release_page(bio, bvec->bv_page); ++ if (mark_dirty) { ++ folio_lock(fi.folio); ++ folio_mark_dirty(fi.folio); ++ folio_unlock(fi.folio); ++ } ++ page = folio_page(fi.folio, fi.offset / PAGE_SIZE); ++ do { ++ bio_release_page(bio, page++); ++ done += PAGE_SIZE; ++ } while (done < fi.length); + } + } + EXPORT_SYMBOL_GPL(__bio_release_pages); +@@ -1439,18 +1448,12 @@ EXPORT_SYMBOL(bio_free_pages); + * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions + * for performing direct-IO in BIOs. + * +- * The problem is that we cannot run set_page_dirty() from interrupt context ++ * The problem is that we cannot run folio_mark_dirty() from interrupt context + * because the required locks are not interrupt-safe. So what we can do is to + * mark the pages dirty _before_ performing IO. And in interrupt context, + * check that the pages are still dirty. If so, fine. If not, redirty them + * in process context. + * +- * We special-case compound pages here: normally this means reads into hugetlb +- * pages. The logic in here doesn't really work right for compound pages +- * because the VM does not uniformly chase down the head page in all cases. +- * But dirtiness of compound pages is pretty meaningless anyway: the VM doesn't +- * handle them at all. So we skip compound pages here at an early stage. +- * + * Note that this code is very hard to test under normal circumstances because + * direct-io pins the pages with get_user_pages(). This makes + * is_page_cache_freeable return false, and the VM will not clean the pages. +@@ -1466,12 +1469,12 @@ EXPORT_SYMBOL(bio_free_pages); + */ + void bio_set_pages_dirty(struct bio *bio) + { +- struct bio_vec *bvec; +- struct bvec_iter_all iter_all; ++ struct folio_iter fi; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (!PageCompound(bvec->bv_page)) +- set_page_dirty_lock(bvec->bv_page); ++ bio_for_each_folio_all(fi, bio) { ++ folio_lock(fi.folio); ++ folio_mark_dirty(fi.folio); ++ folio_unlock(fi.folio); + } + } + EXPORT_SYMBOL_GPL(bio_set_pages_dirty); +@@ -1515,12 +1518,11 @@ static void bio_dirty_fn(struct work_struct *work) + + void bio_check_pages_dirty(struct bio *bio) + { +- struct bio_vec *bvec; ++ struct folio_iter fi; + unsigned long flags; +- struct bvec_iter_all iter_all; + +- bio_for_each_segment_all(bvec, bio, iter_all) { +- if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) ++ bio_for_each_folio_all(fi, bio) { ++ if (!folio_test_dirty(fi.folio)) + goto defer; + } + +diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h +index fd482439afbc9..b927a4a0ad030 100644 +--- a/block/blk-cgroup.h ++++ b/block/blk-cgroup.h +@@ -252,7 +252,8 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, + if (blkcg == &blkcg_root) + return q->root_blkg; + +- blkg = rcu_dereference(blkcg->blkg_hint); ++ blkg = rcu_dereference_check(blkcg->blkg_hint, ++ lockdep_is_held(&q->queue_lock)); + if (blkg && blkg->q == q) + return blkg; + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 20ecd0ab616f7..6041e17492ecb 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2968,12 +2968,6 @@ void blk_mq_submit_bio(struct bio *bio) + blk_status_t ret; + + bio = blk_queue_bounce(bio, q); +- if (bio_may_exceed_limits(bio, &q->limits)) { +- bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); +- if (!bio) +- return; +- } +- + bio_set_ioprio(bio); + + if (plug) { +@@ -2982,6 +2976,11 @@ void blk_mq_submit_bio(struct bio *bio) + rq = NULL; + } + if (rq) { ++ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { ++ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); ++ if (!bio) ++ return; ++ } + if (!bio_integrity_prep(bio)) + return; + if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) +@@ -2992,6 +2991,11 @@ void blk_mq_submit_bio(struct bio *bio) + } else { + if (unlikely(bio_queue_enter(bio))) + return; ++ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { ++ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); ++ if (!bio) ++ goto fail; ++ } + if (!bio_integrity_prep(bio)) + goto fail; + } +diff --git a/block/genhd.c b/block/genhd.c +index cc32a0c704eb8..f9b81be6c7610 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -432,7 +432,9 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, + DISK_MAX_PARTS); + disk->minors = DISK_MAX_PARTS; + } +- if (disk->first_minor + disk->minors > MINORMASK + 1) ++ if (disk->first_minor > MINORMASK || ++ disk->minors > MINORMASK + 1 || ++ disk->first_minor + disk->minors > MINORMASK + 1) + goto out_exit_elevator; + } else { + if (WARN_ON(disk->minors)) +@@ -542,6 +544,7 @@ out_put_holder_dir: + kobject_put(disk->part0->bd_holder_dir); + out_del_block_link: + sysfs_remove_link(block_depr, dev_name(ddev)); ++ pm_runtime_set_memalloc_noio(ddev, false); + out_device_del: + device_del(ddev); + out_free_ext_minor: +diff --git a/block/ioctl.c b/block/ioctl.c +index d5f5cd61efd7f..a74ef911e2797 100644 +--- a/block/ioctl.c ++++ b/block/ioctl.c +@@ -18,7 +18,7 @@ static int blkpg_do_ioctl(struct block_device *bdev, + { + struct gendisk *disk = bdev->bd_disk; + struct blkpg_partition p; +- long long start, length; ++ sector_t start, length; + + if (disk->flags & GENHD_FL_NO_PART) + return -EINVAL; +@@ -35,14 +35,17 @@ static int blkpg_do_ioctl(struct block_device *bdev, + if (op == BLKPG_DEL_PARTITION) + return bdev_del_partition(disk, p.pno); + ++ if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) ++ return -EINVAL; ++ /* Check that the partition is aligned to the block size */ ++ if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) ++ return -EINVAL; ++ + start = p.start >> SECTOR_SHIFT; + length = p.length >> SECTOR_SHIFT; + + switch (op) { + case BLKPG_ADD_PARTITION: +- /* check if partition is aligned to blocksize */ +- if (p.start & (bdev_logical_block_size(bdev) - 1)) +- return -EINVAL; + return bdev_add_partition(disk, p.pno, start, length); + case BLKPG_RESIZE_PARTITION: + return bdev_resize_partition(disk, p.pno, start, length); +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index ea6fb8e89d065..68cc9290cabe9 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -1116,9 +1116,13 @@ EXPORT_SYMBOL_GPL(af_alg_sendmsg); + void af_alg_free_resources(struct af_alg_async_req *areq) + { + struct sock *sk = areq->sk; ++ struct af_alg_ctx *ctx; + + af_alg_free_areq_sgls(areq); + sock_kfree_s(sk, areq, areq->areqlen); ++ ++ ctx = alg_sk(sk)->private; ++ ctx->inflight = false; + } + EXPORT_SYMBOL_GPL(af_alg_free_resources); + +@@ -1188,11 +1192,19 @@ EXPORT_SYMBOL_GPL(af_alg_poll); + struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, + unsigned int areqlen) + { +- struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); ++ struct af_alg_ctx *ctx = alg_sk(sk)->private; ++ struct af_alg_async_req *areq; ++ ++ /* Only one AIO request can be in flight. */ ++ if (ctx->inflight) ++ return ERR_PTR(-EBUSY); + ++ areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); + if (unlikely(!areq)) + return ERR_PTR(-ENOMEM); + ++ ctx->inflight = true; ++ + areq->areqlen = areqlen; + areq->sk = sk; + areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; +diff --git a/crypto/rsa.c b/crypto/rsa.c +index c79613cdce6e4..b9cd11fb7d367 100644 +--- a/crypto/rsa.c ++++ b/crypto/rsa.c +@@ -220,6 +220,8 @@ static int rsa_check_exponent_fips(MPI e) + } + + e_max = mpi_alloc(0); ++ if (!e_max) ++ return -ENOMEM; + mpi_set_bit(e_max, 256); + + if (mpi_cmp(e, e_max) >= 0) { +diff --git a/crypto/scompress.c b/crypto/scompress.c +index 442a82c9de7de..b108a30a76001 100644 +--- a/crypto/scompress.c ++++ b/crypto/scompress.c +@@ -117,6 +117,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + struct crypto_scomp *scomp = *tfm_ctx; + void **ctx = acomp_request_ctx(req); + struct scomp_scratch *scratch; ++ unsigned int dlen; + int ret; + + if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) +@@ -128,6 +129,8 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE) + req->dlen = SCOMP_SCRATCH_SIZE; + ++ dlen = req->dlen; ++ + scratch = raw_cpu_ptr(&scomp_scratch); + spin_lock(&scratch->lock); + +@@ -145,6 +148,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + ret = -ENOMEM; + goto out; + } ++ } else if (req->dlen > dlen) { ++ ret = -ENOSPC; ++ goto out; + } + scatterwalk_map_and_copy(scratch->dst, req->dst, 0, req->dlen, + 1); +diff --git a/drivers/accel/habanalabs/common/habanalabs_ioctl.c b/drivers/accel/habanalabs/common/habanalabs_ioctl.c +index 6a45a92344e9b..a7f6c54c123ef 100644 +--- a/drivers/accel/habanalabs/common/habanalabs_ioctl.c ++++ b/drivers/accel/habanalabs/common/habanalabs_ioctl.c +@@ -682,7 +682,7 @@ static int sec_attest_info(struct hl_fpriv *hpriv, struct hl_info_args *args) + if (!sec_attest_info) + return -ENOMEM; + +- info = kmalloc(sizeof(*info), GFP_KERNEL); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + rc = -ENOMEM; + goto free_sec_attest_info; +diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c +index e120a96e1eaee..71e8d4e7a36cc 100644 +--- a/drivers/acpi/acpi_extlog.c ++++ b/drivers/acpi/acpi_extlog.c +@@ -145,9 +145,14 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, + static u32 err_seq; + + estatus = extlog_elog_entry_check(cpu, bank); +- if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC)) ++ if (!estatus) + return NOTIFY_DONE; + ++ if (mce->kflags & MCE_HANDLED_CEC) { ++ estatus->block_status = 0; ++ return NOTIFY_DONE; ++ } ++ + memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN); + /* clear record status to enable BIOS to update it again */ + estatus->block_status = 0; +diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c +index c5598b6d5db8b..794962c5c88e9 100644 +--- a/drivers/acpi/acpi_lpit.c ++++ b/drivers/acpi/acpi_lpit.c +@@ -105,7 +105,7 @@ static void lpit_update_residency(struct lpit_residency_info *info, + return; + + info->frequency = lpit_native->counter_frequency ? +- lpit_native->counter_frequency : tsc_khz * 1000; ++ lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U); + if (!info->frequency) + info->frequency = 1; + +diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c +index 539e700de4d28..a052e0ab19e4c 100644 +--- a/drivers/acpi/acpi_lpss.c ++++ b/drivers/acpi/acpi_lpss.c +@@ -465,8 +465,9 @@ static int register_device_clock(struct acpi_device *adev, + if (!clk_name) + return -ENOMEM; + clk = clk_register_fractional_divider(NULL, clk_name, parent, ++ 0, prv_base, 1, 15, 16, 15, + CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, +- prv_base, 1, 15, 16, 15, 0, NULL); ++ NULL); + parent = clk_name; + + clk_name = kasprintf(GFP_KERNEL, "%s-update", devname); +diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c +index 35f071ad95324..27a6ae89f13a8 100644 +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -1713,12 +1713,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) + return; + count++; + +- acpi_get_parent(device->dev->handle, &acpi_parent); +- +- pdev = acpi_get_pci_dev(acpi_parent); +- if (pdev) { +- parent = &pdev->dev; +- pci_dev_put(pdev); ++ if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) { ++ pdev = acpi_get_pci_dev(acpi_parent); ++ if (pdev) { ++ parent = &pdev->dev; ++ pci_dev_put(pdev); ++ } + } + + memset(&props, 0, sizeof(struct backlight_properties)); +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 99b4e33554355..4d958a165da05 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -851,6 +851,7 @@ static int acpi_get_ref_args(struct fwnode_reference_args *args, + * @index: Index of the reference to return + * @num_args: Maximum number of arguments after each reference + * @args: Location to store the returned reference with optional arguments ++ * (may be NULL) + * + * Find property with @name, verifify that it is a package containing at least + * one object reference and if so, store the ACPI device object pointer to the +@@ -907,6 +908,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, + if (!device) + return -EINVAL; + ++ if (!args) ++ return 0; ++ + args->fwnode = acpi_fwnode_handle(device); + args->nargs = 0; + return 0; +diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c +index 5e2505fa82ff9..34c27223cb7dd 100644 +--- a/drivers/android/binder_alloc.c ++++ b/drivers/android/binder_alloc.c +@@ -271,7 +271,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, + } + if (mm) { + mmap_write_unlock(mm); +- mmput(mm); ++ mmput_async(mm); + } + return 0; + +@@ -304,7 +304,7 @@ err_page_ptr_cleared: + err_no_vma: + if (mm) { + mmap_write_unlock(mm); +- mmput(mm); ++ mmput_async(mm); + } + return vma ? -ENOMEM : -ESRCH; + } +@@ -344,8 +344,7 @@ static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid) + continue; + if (!buffer->async_transaction) + continue; +- total_alloc_size += binder_alloc_buffer_size(alloc, buffer) +- + sizeof(struct binder_buffer); ++ total_alloc_size += binder_alloc_buffer_size(alloc, buffer); + num_buffers++; + } + +@@ -407,17 +406,17 @@ static struct binder_buffer *binder_alloc_new_buf_locked( + alloc->pid, extra_buffers_size); + return ERR_PTR(-EINVAL); + } +- if (is_async && +- alloc->free_async_space < size + sizeof(struct binder_buffer)) { ++ ++ /* Pad 0-size buffers so they get assigned unique addresses */ ++ size = max(size, sizeof(void *)); ++ ++ if (is_async && alloc->free_async_space < size) { + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, + "%d: binder_alloc_buf size %zd failed, no async space left\n", + alloc->pid, size); + return ERR_PTR(-ENOSPC); + } + +- /* Pad 0-size buffers so they get assigned unique addresses */ +- size = max(size, sizeof(void *)); +- + while (n) { + buffer = rb_entry(n, struct binder_buffer, rb_node); + BUG_ON(!buffer->free); +@@ -519,7 +518,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( + buffer->pid = pid; + buffer->oneway_spam_suspect = false; + if (is_async) { +- alloc->free_async_space -= size + sizeof(struct binder_buffer); ++ alloc->free_async_space -= size; + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "%d: binder_alloc_buf size %zd async free %zd\n", + alloc->pid, size, alloc->free_async_space); +@@ -657,8 +656,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, + BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); + + if (buffer->async_transaction) { +- alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); +- ++ alloc->free_async_space += buffer_size; + binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "%d: binder_free_buf size %zd async free %zd\n", + alloc->pid, size, alloc->free_async_space); +diff --git a/drivers/base/class.c b/drivers/base/class.c +index 05d9df90f621b..9cd489a577086 100644 +--- a/drivers/base/class.c ++++ b/drivers/base/class.c +@@ -215,6 +215,7 @@ int class_register(const struct class *cls) + return 0; + + err_out: ++ lockdep_unregister_key(key); + kfree(cp); + return error; + } +diff --git a/drivers/base/node.c b/drivers/base/node.c +index 493d533f83755..4d588f4658c85 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -868,11 +868,15 @@ int __register_one_node(int nid) + { + int error; + int cpu; ++ struct node *node; + +- node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL); +- if (!node_devices[nid]) ++ node = kzalloc(sizeof(struct node), GFP_KERNEL); ++ if (!node) + return -ENOMEM; + ++ INIT_LIST_HEAD(&node->access_list); ++ node_devices[nid] = node; ++ + error = register_node(node_devices[nid], nid); + + /* link cpu under this node */ +@@ -881,7 +885,6 @@ int __register_one_node(int nid) + register_cpu_under_node(cpu, nid); + } + +- INIT_LIST_HEAD(&node_devices[nid]->access_list); + node_init_caches(nid); + + return error; +diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c +index 1886995a0b3a3..079bd14bdedc7 100644 +--- a/drivers/base/swnode.c ++++ b/drivers/base/swnode.c +@@ -541,6 +541,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, + if (nargs > NR_FWNODE_REFERENCE_ARGS) + return -EINVAL; + ++ if (!args) ++ return 0; ++ + args->fwnode = software_node_get(refnode); + args->nargs = nargs; + +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 9f2d412fc560e..552f56a84a7eb 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -165,39 +165,37 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) + return get_size(lo->lo_offset, lo->lo_sizelimit, file); + } + ++/* ++ * We support direct I/O only if lo_offset is aligned with the logical I/O size ++ * of backing device, and the logical block size of loop is bigger than that of ++ * the backing device. ++ */ ++static bool lo_bdev_can_use_dio(struct loop_device *lo, ++ struct block_device *backing_bdev) ++{ ++ unsigned short sb_bsize = bdev_logical_block_size(backing_bdev); ++ ++ if (queue_logical_block_size(lo->lo_queue) < sb_bsize) ++ return false; ++ if (lo->lo_offset & (sb_bsize - 1)) ++ return false; ++ return true; ++} ++ + static void __loop_update_dio(struct loop_device *lo, bool dio) + { + struct file *file = lo->lo_backing_file; +- struct address_space *mapping = file->f_mapping; +- struct inode *inode = mapping->host; +- unsigned short sb_bsize = 0; +- unsigned dio_align = 0; ++ struct inode *inode = file->f_mapping->host; ++ struct block_device *backing_bdev = NULL; + bool use_dio; + +- if (inode->i_sb->s_bdev) { +- sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev); +- dio_align = sb_bsize - 1; +- } ++ if (S_ISBLK(inode->i_mode)) ++ backing_bdev = I_BDEV(inode); ++ else if (inode->i_sb->s_bdev) ++ backing_bdev = inode->i_sb->s_bdev; + +- /* +- * We support direct I/O only if lo_offset is aligned with the +- * logical I/O size of backing device, and the logical block +- * size of loop is bigger than the backing device's. +- * +- * TODO: the above condition may be loosed in the future, and +- * direct I/O may be switched runtime at that time because most +- * of requests in sane applications should be PAGE_SIZE aligned +- */ +- if (dio) { +- if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && +- !(lo->lo_offset & dio_align) && +- (file->f_mode & FMODE_CAN_ODIRECT)) +- use_dio = true; +- else +- use_dio = false; +- } else { +- use_dio = false; +- } ++ use_dio = dio && (file->f_mode & FMODE_CAN_ODIRECT) && ++ (!backing_bdev || lo_bdev_can_use_dio(lo, backing_bdev)); + + if (lo->use_dio == use_dio) + return; +diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c +index 968090935eb23..9544746de1683 100644 +--- a/drivers/block/null_blk/main.c ++++ b/drivers/block/null_blk/main.c +@@ -2165,10 +2165,8 @@ static int null_add_dev(struct nullb_device *dev) + + blk_queue_logical_block_size(nullb->q, dev->blocksize); + blk_queue_physical_block_size(nullb->q, dev->blocksize); +- if (!dev->max_sectors) +- dev->max_sectors = queue_max_hw_sectors(nullb->q); +- dev->max_sectors = min(dev->max_sectors, BLK_DEF_MAX_SECTORS); +- blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); ++ if (dev->max_sectors) ++ blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); + + if (dev->virt_boundary) + blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); +@@ -2268,12 +2266,6 @@ static int __init null_init(void) + g_bs = PAGE_SIZE; + } + +- if (g_max_sectors > BLK_DEF_MAX_SECTORS) { +- pr_warn("invalid max sectors\n"); +- pr_warn("defaults max sectors to %u\n", BLK_DEF_MAX_SECTORS); +- g_max_sectors = BLK_DEF_MAX_SECTORS; +- } +- + if (g_home_node != NUMA_NO_NODE && g_home_node >= nr_online_nodes) { + pr_err("invalid home_node value\n"); + g_home_node = NUMA_NO_NODE; +diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c +index 935feab815d97..203a000a84e34 100644 +--- a/drivers/bluetooth/btmtkuart.c ++++ b/drivers/bluetooth/btmtkuart.c +@@ -336,7 +336,7 @@ mtk_stp_split(struct btmtkuart_dev *bdev, const unsigned char *data, int count, + return data; + } + +-static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) ++static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) + { + struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); + const unsigned char *p_left = data, *p_h4; +@@ -375,25 +375,20 @@ static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) + bt_dev_err(bdev->hdev, + "Frame reassembly failed (%d)", err); + bdev->rx_skb = NULL; +- return err; ++ return; + } + + sz_left -= sz_h4; + p_left += sz_h4; + } +- +- return 0; + } + + static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, + size_t count) + { + struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); +- int err; + +- err = btmtkuart_recv(bdev->hdev, data, count); +- if (err < 0) +- return err; ++ btmtkuart_recv(bdev->hdev, data, count); + + bdev->hdev->stat.byte_rx += count; + +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index b7e66b7ac5702..951fe3014a3f3 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -1276,11 +1276,10 @@ static int btnxpuart_receive_buf(struct serdev_device *serdev, const u8 *data, + if (IS_ERR(nxpdev->rx_skb)) { + int err = PTR_ERR(nxpdev->rx_skb); + /* Safe to ignore out-of-sync bootloader signatures */ +- if (is_fw_downloading(nxpdev)) +- return count; +- bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err); ++ if (!is_fw_downloading(nxpdev)) ++ bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err); + nxpdev->rx_skb = NULL; +- return err; ++ return count; + } + if (!is_fw_downloading(nxpdev)) + nxpdev->hdev->stat.byte_rx += count; +diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c +index 600881808982a..582d5c166a75e 100644 +--- a/drivers/bus/mhi/ep/main.c ++++ b/drivers/bus/mhi/ep/main.c +@@ -71,45 +71,77 @@ err_unlock: + static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, + struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code) + { +- struct mhi_ring_element event = {}; ++ struct mhi_ring_element *event; ++ int ret; ++ ++ event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); ++ if (!event) ++ return -ENOMEM; + +- event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre)); +- event.dword[0] = MHI_TRE_EV_DWORD0(code, len); +- event.dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); ++ event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre)); ++ event->dword[0] = MHI_TRE_EV_DWORD0(code, len); ++ event->dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); + +- return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event, MHI_TRE_DATA_GET_BEI(tre)); ++ ret = mhi_ep_send_event(mhi_cntrl, ring->er_index, event, MHI_TRE_DATA_GET_BEI(tre)); ++ kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); ++ ++ return ret; + } + + int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state) + { +- struct mhi_ring_element event = {}; ++ struct mhi_ring_element *event; ++ int ret; ++ ++ event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); ++ if (!event) ++ return -ENOMEM; ++ ++ event->dword[0] = MHI_SC_EV_DWORD0(state); ++ event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); + +- event.dword[0] = MHI_SC_EV_DWORD0(state); +- event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); ++ ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); ++ kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); + +- return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); ++ return ret; + } + + int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env) + { +- struct mhi_ring_element event = {}; ++ struct mhi_ring_element *event; ++ int ret; ++ ++ event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); ++ if (!event) ++ return -ENOMEM; ++ ++ event->dword[0] = MHI_EE_EV_DWORD0(exec_env); ++ event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); + +- event.dword[0] = MHI_EE_EV_DWORD0(exec_env); +- event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); ++ ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); ++ kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); + +- return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); ++ return ret; + } + + static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code) + { + struct mhi_ep_ring *ring = &mhi_cntrl->mhi_cmd->ring; +- struct mhi_ring_element event = {}; ++ struct mhi_ring_element *event; ++ int ret; ++ ++ event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); ++ if (!event) ++ return -ENOMEM; + +- event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element)); +- event.dword[0] = MHI_CC_EV_DWORD0(code); +- event.dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); ++ event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element)); ++ event->dword[0] = MHI_CC_EV_DWORD0(code); ++ event->dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); + +- return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); ++ ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); ++ kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); ++ ++ return ret; + } + + static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_element *el) +@@ -292,10 +324,9 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + size_t tr_len, read_offset, write_offset; ++ struct mhi_ep_buf_info buf_info = {}; + struct mhi_ring_element *el; + bool tr_done = false; +- void *write_addr; +- u64 read_addr; + u32 buf_left; + int ret; + +@@ -324,11 +355,13 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + + read_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left; + write_offset = len - buf_left; +- read_addr = mhi_chan->tre_loc + read_offset; +- write_addr = result->buf_addr + write_offset; ++ ++ buf_info.host_addr = mhi_chan->tre_loc + read_offset; ++ buf_info.dev_addr = result->buf_addr + write_offset; ++ buf_info.size = tr_len; + + dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_id); +- ret = mhi_cntrl->read_from_host(mhi_cntrl, read_addr, write_addr, tr_len); ++ ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n"); + return ret; +@@ -419,7 +452,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } else { + /* UL channel */ +- result.buf_addr = kzalloc(len, GFP_KERNEL); ++ result.buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL | GFP_DMA); + if (!result.buf_addr) + return -ENOMEM; + +@@ -427,7 +460,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem + ret = mhi_ep_read_channel(mhi_cntrl, ring, &result, len); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); +- kfree(result.buf_addr); ++ kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr); + return ret; + } + +@@ -439,7 +472,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem + /* Read until the ring becomes empty */ + } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); + +- kfree(result.buf_addr); ++ kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr); + } + + return 0; +@@ -451,12 +484,11 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; + struct mhi_ep_chan *mhi_chan = mhi_dev->dl_chan; + struct device *dev = &mhi_chan->mhi_dev->dev; ++ struct mhi_ep_buf_info buf_info = {}; + struct mhi_ring_element *el; + u32 buf_left, read_offset; + struct mhi_ep_ring *ring; + enum mhi_ev_ccs code; +- void *read_addr; +- u64 write_addr; + size_t tr_len; + u32 tre_len; + int ret; +@@ -485,11 +517,13 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) + + tr_len = min(buf_left, tre_len); + read_offset = skb->len - buf_left; +- read_addr = skb->data + read_offset; +- write_addr = MHI_TRE_DATA_GET_PTR(el); ++ ++ buf_info.dev_addr = skb->data + read_offset; ++ buf_info.host_addr = MHI_TRE_DATA_GET_PTR(el); ++ buf_info.size = tr_len; + + dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id); +- ret = mhi_cntrl->write_to_host(mhi_cntrl, read_addr, write_addr, tr_len); ++ ret = mhi_cntrl->write_to_host(mhi_cntrl, &buf_info); + if (ret < 0) { + dev_err(dev, "Error writing to the channel\n"); + goto err_exit; +@@ -748,14 +782,14 @@ static void mhi_ep_ch_ring_worker(struct work_struct *work) + if (ret) { + dev_err(dev, "Error updating write offset for ring\n"); + mutex_unlock(&chan->lock); +- kfree(itr); ++ kmem_cache_free(mhi_cntrl->ring_item_cache, itr); + continue; + } + + /* Sanity check to make sure there are elements in the ring */ + if (ring->rd_offset == ring->wr_offset) { + mutex_unlock(&chan->lock); +- kfree(itr); ++ kmem_cache_free(mhi_cntrl->ring_item_cache, itr); + continue; + } + +@@ -767,12 +801,12 @@ static void mhi_ep_ch_ring_worker(struct work_struct *work) + dev_err(dev, "Error processing ring for channel (%u): %d\n", + ring->ch_id, ret); + mutex_unlock(&chan->lock); +- kfree(itr); ++ kmem_cache_free(mhi_cntrl->ring_item_cache, itr); + continue; + } + + mutex_unlock(&chan->lock); +- kfree(itr); ++ kmem_cache_free(mhi_cntrl->ring_item_cache, itr); + } + } + +@@ -828,7 +862,7 @@ static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, unsigned lon + u32 ch_id = ch_idx + i; + + ring = &mhi_cntrl->mhi_chan[ch_id].ring; +- item = kzalloc(sizeof(*item), GFP_ATOMIC); ++ item = kmem_cache_zalloc(mhi_cntrl->ring_item_cache, GFP_ATOMIC); + if (!item) + return; + +@@ -1375,6 +1409,28 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + goto err_free_ch; + } + ++ mhi_cntrl->ev_ring_el_cache = kmem_cache_create("mhi_ep_event_ring_el", ++ sizeof(struct mhi_ring_element), 0, ++ SLAB_CACHE_DMA, NULL); ++ if (!mhi_cntrl->ev_ring_el_cache) { ++ ret = -ENOMEM; ++ goto err_free_cmd; ++ } ++ ++ mhi_cntrl->tre_buf_cache = kmem_cache_create("mhi_ep_tre_buf", MHI_EP_DEFAULT_MTU, 0, ++ SLAB_CACHE_DMA, NULL); ++ if (!mhi_cntrl->tre_buf_cache) { ++ ret = -ENOMEM; ++ goto err_destroy_ev_ring_el_cache; ++ } ++ ++ mhi_cntrl->ring_item_cache = kmem_cache_create("mhi_ep_ring_item", ++ sizeof(struct mhi_ep_ring_item), 0, ++ 0, NULL); ++ if (!mhi_cntrl->ev_ring_el_cache) { ++ ret = -ENOMEM; ++ goto err_destroy_tre_buf_cache; ++ } + INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); + INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); + INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker); +@@ -1383,7 +1439,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + mhi_cntrl->wq = alloc_workqueue("mhi_ep_wq", 0, 0); + if (!mhi_cntrl->wq) { + ret = -ENOMEM; +- goto err_free_cmd; ++ goto err_destroy_ring_item_cache; + } + + INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); +@@ -1442,6 +1498,12 @@ err_ida_free: + ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); + err_destroy_wq: + destroy_workqueue(mhi_cntrl->wq); ++err_destroy_ring_item_cache: ++ kmem_cache_destroy(mhi_cntrl->ring_item_cache); ++err_destroy_ev_ring_el_cache: ++ kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache); ++err_destroy_tre_buf_cache: ++ kmem_cache_destroy(mhi_cntrl->tre_buf_cache); + err_free_cmd: + kfree(mhi_cntrl->mhi_cmd); + err_free_ch: +@@ -1463,6 +1525,9 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) + + free_irq(mhi_cntrl->irq, mhi_cntrl); + ++ kmem_cache_destroy(mhi_cntrl->tre_buf_cache); ++ kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache); ++ kmem_cache_destroy(mhi_cntrl->ring_item_cache); + kfree(mhi_cntrl->mhi_cmd); + kfree(mhi_cntrl->mhi_chan); + +diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c +index 115518ec76a43..c673d7200b3e1 100644 +--- a/drivers/bus/mhi/ep/ring.c ++++ b/drivers/bus/mhi/ep/ring.c +@@ -30,7 +30,8 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) + { + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; +- size_t start, copy_size; ++ struct mhi_ep_buf_info buf_info = {}; ++ size_t start; + int ret; + + /* Don't proceed in the case of event ring. This happens during mhi_ep_ring_start(). */ +@@ -43,30 +44,34 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) + + start = ring->wr_offset; + if (start < end) { +- copy_size = (end - start) * sizeof(struct mhi_ring_element); +- ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase + +- (start * sizeof(struct mhi_ring_element)), +- &ring->ring_cache[start], copy_size); ++ buf_info.size = (end - start) * sizeof(struct mhi_ring_element); ++ buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element)); ++ buf_info.dev_addr = &ring->ring_cache[start]; ++ ++ ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info); + if (ret < 0) + return ret; + } else { +- copy_size = (ring->ring_size - start) * sizeof(struct mhi_ring_element); +- ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase + +- (start * sizeof(struct mhi_ring_element)), +- &ring->ring_cache[start], copy_size); ++ buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element); ++ buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element)); ++ buf_info.dev_addr = &ring->ring_cache[start]; ++ ++ ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info); + if (ret < 0) + return ret; + + if (end) { +- ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase, +- &ring->ring_cache[0], +- end * sizeof(struct mhi_ring_element)); ++ buf_info.host_addr = ring->rbase; ++ buf_info.dev_addr = &ring->ring_cache[0]; ++ buf_info.size = end * sizeof(struct mhi_ring_element); ++ ++ ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info); + if (ret < 0) + return ret; + } + } + +- dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, copy_size); ++ dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, buf_info.size); + + return 0; + } +@@ -102,6 +107,7 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e + { + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; ++ struct mhi_ep_buf_info buf_info = {}; + size_t old_offset = 0; + u32 num_free_elem; + __le64 rp; +@@ -133,12 +139,11 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e + rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase); + memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64)); + +- ret = mhi_cntrl->write_to_host(mhi_cntrl, el, ring->rbase + (old_offset * sizeof(*el)), +- sizeof(*el)); +- if (ret < 0) +- return ret; ++ buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el)); ++ buf_info.dev_addr = el; ++ buf_info.size = sizeof(*el); + +- return 0; ++ return mhi_cntrl->write_to_host(mhi_cntrl, &buf_info); + } + + void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id) +diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c +index 7d7b2cb753180..3b6ad2307a41f 100644 +--- a/drivers/clk/clk-renesas-pcie.c ++++ b/drivers/clk/clk-renesas-pcie.c +@@ -163,7 +163,7 @@ static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx) + enum rs9_model model = rs9->chip_info->model; + + if (model == RENESAS_9FGV0241) +- return BIT(idx) + 1; ++ return BIT(idx + 1); + else if (model == RENESAS_9FGV0441) + return BIT(idx); + +diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c +index 9599857842c72..2920fe2e5e8be 100644 +--- a/drivers/clk/clk-si5341.c ++++ b/drivers/clk/clk-si5341.c +@@ -895,10 +895,8 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, + r[0] = r_div ? (r_div & 0xff) : 1; + r[1] = (r_div >> 8) & 0xff; + r[2] = (r_div >> 16) & 0xff; +- err = regmap_bulk_write(output->data->regmap, ++ return regmap_bulk_write(output->data->regmap, + SI5341_OUT_R_REG(output), r, 3); +- +- return 0; + } + + static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) +diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c +index 01d3c4c7b0b23..7cb7d501d7a6e 100644 +--- a/drivers/clk/clk-sp7021.c ++++ b/drivers/clk/clk-sp7021.c +@@ -604,14 +604,14 @@ static int sp7021_clk_probe(struct platform_device *pdev) + int i; + + clk_base = devm_platform_ioremap_resource(pdev, 0); +- if (!clk_base) +- return -ENXIO; ++ if (IS_ERR(clk_base)) ++ return PTR_ERR(clk_base); + pll_base = devm_platform_ioremap_resource(pdev, 1); +- if (!pll_base) +- return -ENXIO; ++ if (IS_ERR(pll_base)) ++ return PTR_ERR(pll_base); + sys_base = devm_platform_ioremap_resource(pdev, 2); +- if (!sys_base) +- return -ENXIO; ++ if (IS_ERR(sys_base)) ++ return PTR_ERR(sys_base); + + /* enable default clks */ + for (i = 0; i < ARRAY_SIZE(sp_clken); i++) +diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c +index aefa19f3c2c51..0b8f0904b339b 100644 +--- a/drivers/clk/qcom/dispcc-sm8550.c ++++ b/drivers/clk/qcom/dispcc-sm8550.c +@@ -81,6 +81,10 @@ static const struct alpha_pll_config disp_cc_pll0_config = { + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, ++ .test_ctl_val = 0x00000000, ++ .test_ctl_hi_val = 0x00000003, ++ .test_ctl_hi1_val = 0x00009000, ++ .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, + }; +@@ -108,6 +112,10 @@ static const struct alpha_pll_config disp_cc_pll1_config = { + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00182261, + .config_ctl_hi1_val = 0x82aa299c, ++ .test_ctl_val = 0x00000000, ++ .test_ctl_hi_val = 0x00000003, ++ .test_ctl_hi1_val = 0x00009000, ++ .test_ctl_hi2_val = 0x00000034, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000005, + }; +diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c +index 586126c4dd907..b883dffe5f7aa 100644 +--- a/drivers/clk/qcom/gcc-sm8550.c ++++ b/drivers/clk/qcom/gcc-sm8550.c +@@ -401,7 +401,7 @@ static struct clk_rcg2 gcc_gp1_clk_src = { + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -416,7 +416,7 @@ static struct clk_rcg2 gcc_gp2_clk_src = { + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -431,7 +431,7 @@ static struct clk_rcg2 gcc_gp3_clk_src = { + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -451,7 +451,7 @@ static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -471,7 +471,7 @@ static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -486,7 +486,7 @@ static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -501,7 +501,7 @@ static struct clk_rcg2 gcc_pcie_1_phy_rchng_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -521,7 +521,7 @@ static struct clk_rcg2 gcc_pdm2_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -536,7 +536,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -551,7 +551,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -566,7 +566,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -581,7 +581,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -596,7 +596,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -611,7 +611,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s5_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -626,7 +626,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s6_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -641,7 +641,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s7_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -656,7 +656,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s8_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -671,7 +671,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s9_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -700,7 +700,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { +@@ -717,7 +717,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { +@@ -750,7 +750,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { +@@ -767,7 +767,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { +@@ -784,7 +784,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { +@@ -801,7 +801,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { +@@ -818,7 +818,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { +@@ -835,7 +835,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { +@@ -852,7 +852,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { +@@ -869,7 +869,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { +@@ -886,7 +886,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { +@@ -903,7 +903,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { +@@ -920,7 +920,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { +@@ -937,7 +937,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { +@@ -975,7 +975,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = { + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = { +@@ -992,7 +992,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { +@@ -1025,7 +1025,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1048,7 +1048,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1071,7 +1071,7 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1093,7 +1093,7 @@ static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1114,7 +1114,7 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1136,7 +1136,7 @@ static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1159,7 +1159,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1174,7 +1174,7 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -1189,7 +1189,7 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -2998,38 +2998,46 @@ static struct clk_branch gcc_video_axi1_clk = { + + static struct gdsc pcie_0_gdsc = { + .gdscr = 0x6b004, ++ .collapse_ctrl = 0x52020, ++ .collapse_mask = BIT(0), + .pd = { + .name = "pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc pcie_0_phy_gdsc = { + .gdscr = 0x6c000, ++ .collapse_ctrl = 0x52020, ++ .collapse_mask = BIT(3), + .pd = { + .name = "pcie_0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc pcie_1_gdsc = { + .gdscr = 0x8d004, ++ .collapse_ctrl = 0x52020, ++ .collapse_mask = BIT(1), + .pd = { + .name = "pcie_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc pcie_1_phy_gdsc = { + .gdscr = 0x8e000, ++ .collapse_ctrl = 0x52020, ++ .collapse_mask = BIT(4), + .pd = { + .name = "pcie_1_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc ufs_phy_gdsc = { +@@ -3038,7 +3046,7 @@ static struct gdsc ufs_phy_gdsc = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc ufs_mem_phy_gdsc = { +@@ -3047,7 +3055,7 @@ static struct gdsc ufs_mem_phy_gdsc = { + .name = "ufs_mem_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc usb30_prim_gdsc = { +@@ -3056,7 +3064,7 @@ static struct gdsc usb30_prim_gdsc = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct gdsc usb3_phy_gdsc = { +@@ -3065,7 +3073,7 @@ static struct gdsc usb3_phy_gdsc = { + .name = "usb3_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = POLL_CFG_GDSCR, ++ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + + static struct clk_regmap *gcc_sm8550_clocks[] = { +diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c +index 8422fd0474932..c89a5b59ddb7c 100644 +--- a/drivers/clk/qcom/gpucc-sm8150.c ++++ b/drivers/clk/qcom/gpucc-sm8150.c +@@ -37,8 +37,8 @@ static struct alpha_pll_config gpu_cc_pll1_config = { + .config_ctl_hi_val = 0x00002267, + .config_ctl_hi1_val = 0x00000024, + .test_ctl_val = 0x00000000, +- .test_ctl_hi_val = 0x00000002, +- .test_ctl_hi1_val = 0x00000000, ++ .test_ctl_hi_val = 0x00000000, ++ .test_ctl_hi1_val = 0x00000020, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x000000d0, +diff --git a/drivers/clk/qcom/videocc-sm8150.c b/drivers/clk/qcom/videocc-sm8150.c +index 1afdbe4a249d6..52a9a453a1432 100644 +--- a/drivers/clk/qcom/videocc-sm8150.c ++++ b/drivers/clk/qcom/videocc-sm8150.c +@@ -33,6 +33,7 @@ static struct alpha_pll_config video_pll0_config = { + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002267, + .config_ctl_hi1_val = 0x00000024, ++ .test_ctl_hi1_val = 0x00000020, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x000000D0, +@@ -214,6 +215,10 @@ static const struct regmap_config video_cc_sm8150_regmap_config = { + + static const struct qcom_reset_map video_cc_sm8150_resets[] = { + [VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 }, ++ [VIDEO_CC_INTERFACE_BCR] = { 0x8f0 }, ++ [VIDEO_CC_MVS0_BCR] = { 0x870 }, ++ [VIDEO_CC_MVS1_BCR] = { 0x8b0 }, ++ [VIDEO_CC_MVSC_BCR] = { 0x810 }, + }; + + static const struct qcom_cc_desc video_cc_sm8150_desc = { +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 3f01620e292b6..75f9eca020ce5 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -1105,41 +1105,33 @@ fail: + + #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) + +-static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, +- unsigned long id) +-{ +- struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); +- const struct rzg2l_cpg_info *info = priv->info; +- unsigned int reg = info->resets[id].off; +- u32 dis = BIT(info->resets[id].bit); +- u32 we = dis << 16; +- +- dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); +- +- /* Reset module */ +- writel(we, priv->base + CLK_RST_R(reg)); +- +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); +- +- /* Release module from reset state */ +- writel(we | dis, priv->base + CLK_RST_R(reg)); +- +- return 0; +-} +- + static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) + { + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; +- u32 value = BIT(info->resets[id].bit) << 16; ++ u32 mask = BIT(info->resets[id].bit); ++ s8 monbit = info->resets[id].monbit; ++ u32 value = mask << 16; + + dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); +- return 0; ++ ++ if (info->has_clk_mon_regs) { ++ reg = CLK_MRST_R(reg); ++ } else if (monbit >= 0) { ++ reg = CPG_RST_MON; ++ mask = BIT(monbit); ++ } else { ++ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ ++ udelay(35); ++ return 0; ++ } ++ ++ return readl_poll_timeout_atomic(priv->base + reg, value, ++ value & mask, 10, 200); + } + + static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, +@@ -1148,14 +1140,40 @@ static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; +- u32 dis = BIT(info->resets[id].bit); +- u32 value = (dis << 16) | dis; ++ u32 mask = BIT(info->resets[id].bit); ++ s8 monbit = info->resets[id].monbit; ++ u32 value = (mask << 16) | mask; + + dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, + CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); +- return 0; ++ ++ if (info->has_clk_mon_regs) { ++ reg = CLK_MRST_R(reg); ++ } else if (monbit >= 0) { ++ reg = CPG_RST_MON; ++ mask = BIT(monbit); ++ } else { ++ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ ++ udelay(35); ++ return 0; ++ } ++ ++ return readl_poll_timeout_atomic(priv->base + reg, value, ++ !(value & mask), 10, 200); ++} ++ ++static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = rzg2l_cpg_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return rzg2l_cpg_deassert(rcdev, id); + } + + static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, +@@ -1163,18 +1181,21 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, + { + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; +- unsigned int reg = info->resets[id].off; +- u32 bitmask = BIT(info->resets[id].bit); + s8 monbit = info->resets[id].monbit; ++ unsigned int reg; ++ u32 bitmask; + + if (info->has_clk_mon_regs) { +- return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask); ++ reg = CLK_MRST_R(info->resets[id].off); ++ bitmask = BIT(info->resets[id].bit); + } else if (monbit >= 0) { +- u32 monbitmask = BIT(monbit); +- +- return !!(readl(priv->base + CPG_RST_MON) & monbitmask); ++ reg = CPG_RST_MON; ++ bitmask = BIT(monbit); ++ } else { ++ return -ENOTSUPP; + } +- return -ENOTSUPP; ++ ++ return !!(readl(priv->base + reg) & bitmask); + } + + static const struct reset_control_ops rzg2l_cpg_reset_ops = { +diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c +index 60359333f26db..9b5d3050b7422 100644 +--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c ++++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c +@@ -89,7 +89,7 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index) + static const struct clk_ops zynqmp_clk_mux_ops = { + .get_parent = zynqmp_clk_mux_get_parent, + .set_parent = zynqmp_clk_mux_set_parent, +- .determine_rate = __clk_mux_determine_rate, ++ .determine_rate = __clk_mux_determine_rate_closest, + }; + + static const struct clk_ops zynqmp_clk_mux_ro_ops = { +diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c +index 33a3b2a226595..5a00487ae408b 100644 +--- a/drivers/clk/zynqmp/divider.c ++++ b/drivers/clk/zynqmp/divider.c +@@ -110,52 +110,6 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, + return DIV_ROUND_UP_ULL(parent_rate, value); + } + +-static void zynqmp_get_divider2_val(struct clk_hw *hw, +- unsigned long rate, +- struct zynqmp_clk_divider *divider, +- u32 *bestdiv) +-{ +- int div1; +- int div2; +- long error = LONG_MAX; +- unsigned long div1_prate; +- struct clk_hw *div1_parent_hw; +- struct zynqmp_clk_divider *pdivider; +- struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw); +- +- if (!div2_parent_hw) +- return; +- +- pdivider = to_zynqmp_clk_divider(div2_parent_hw); +- if (!pdivider) +- return; +- +- div1_parent_hw = clk_hw_get_parent(div2_parent_hw); +- if (!div1_parent_hw) +- return; +- +- div1_prate = clk_hw_get_rate(div1_parent_hw); +- *bestdiv = 1; +- for (div1 = 1; div1 <= pdivider->max_div;) { +- for (div2 = 1; div2 <= divider->max_div;) { +- long new_error = ((div1_prate / div1) / div2) - rate; +- +- if (abs(new_error) < abs(error)) { +- *bestdiv = div2; +- error = new_error; +- } +- if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) +- div2 = div2 << 1; +- else +- div2++; +- } +- if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) +- div1 = div1 << 1; +- else +- div1++; +- } +-} +- + /** + * zynqmp_clk_divider_round_rate() - Round rate of divider clock + * @hw: handle between common and hardware-specific interfaces +@@ -174,6 +128,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, + u32 div_type = divider->div_type; + u32 bestdiv; + int ret; ++ u8 width; + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { +@@ -193,23 +148,12 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, + return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + } + +- bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); +- +- /* +- * In case of two divisors, compute best divider values and return +- * divider2 value based on compute value. div1 will be automatically +- * set to optimum based on required total divider value. +- */ +- if (div_type == TYPE_DIV2 && +- (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { +- zynqmp_get_divider2_val(hw, rate, divider, &bestdiv); +- } ++ width = fls(divider->max_div); + +- if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) +- bestdiv = rate % *prate ? 1 : bestdiv; ++ rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); + +- bestdiv = min_t(u32, bestdiv, divider->max_div); +- *prate = rate * bestdiv; ++ if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) ++ *prate = rate; + + return rate; + } +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index 5f60f6bd33866..56acf26172621 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -183,7 +183,7 @@ static inline u32 dmtimer_read(struct dmtimer *timer, u32 reg) + * dmtimer_write - write timer registers in posted and non-posted mode + * @timer: timer pointer over which write operation is to perform + * @reg: lowest byte holds the register offset +- * @value: data to write into the register ++ * @val: data to write into the register + * + * The posted mode bit is encoded in reg. Note that in posted mode, the write + * pending bit must be checked. Otherwise a write on a register which has a +@@ -949,7 +949,7 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *cookie, + + /** + * omap_dm_timer_set_int_disable - disable timer interrupts +- * @timer: pointer to timer handle ++ * @cookie: pointer to timer cookie + * @mask: bit mask of interrupts to be disabled + * + * Disables the specified timer interrupts for a timer. +diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c +index f34e6382a4c50..028df8a5f537a 100644 +--- a/drivers/cpufreq/scmi-cpufreq.c ++++ b/drivers/cpufreq/scmi-cpufreq.c +@@ -310,8 +310,11 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) + + #ifdef CONFIG_COMMON_CLK + /* dummy clock provider as needed by OPP if clocks property is used */ +- if (of_property_present(dev->of_node, "#clock-cells")) +- devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); ++ if (of_property_present(dev->of_node, "#clock-cells")) { ++ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); ++ if (ret) ++ return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__); ++ } + #endif + + ret = cpufreq_register_driver(&scmi_cpufreq_driver); +diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c +index e66df22f96955..d8515d5c0853d 100644 +--- a/drivers/cpuidle/cpuidle-haltpoll.c ++++ b/drivers/cpuidle/cpuidle-haltpoll.c +@@ -25,13 +25,12 @@ MODULE_PARM_DESC(force, "Load unconditionally"); + static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; + static enum cpuhp_state haltpoll_hp_state; + +-static int default_enter_idle(struct cpuidle_device *dev, +- struct cpuidle_driver *drv, int index) ++static __cpuidle int default_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) + { +- if (current_clr_polling_and_test()) { +- local_irq_enable(); ++ if (current_clr_polling_and_test()) + return index; +- } ++ + arch_cpu_idle(); + return index; + } +diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c +index aa4e1a5006919..cb8e99936abb7 100644 +--- a/drivers/crypto/ccp/ccp-ops.c ++++ b/drivers/crypto/ccp/ccp-ops.c +@@ -179,8 +179,11 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa, + + wa->dma.address = dma_map_single(wa->dev, wa->address, len, + dir); +- if (dma_mapping_error(wa->dev, wa->dma.address)) ++ if (dma_mapping_error(wa->dev, wa->dma.address)) { ++ kfree(wa->address); ++ wa->address = NULL; + return -ENOMEM; ++ } + + wa->dma.length = len; + } +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index 3dce35debf637..b97ce0ee71406 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -117,8 +117,6 @@ + #define HPRE_DFX_COMMON2_LEN 0xE + #define HPRE_DFX_CORE_LEN 0x43 + +-#define HPRE_DEV_ALG_MAX_LEN 256 +- + static const char hpre_name[] = "hisi_hpre"; + static struct dentry *hpre_debugfs_root; + static const struct pci_device_id hpre_dev_ids[] = { +@@ -134,12 +132,7 @@ struct hpre_hw_error { + const char *msg; + }; + +-struct hpre_dev_alg { +- u32 alg_msk; +- const char *alg; +-}; +- +-static const struct hpre_dev_alg hpre_dev_algs[] = { ++static const struct qm_dev_alg hpre_dev_algs[] = { + { + .alg_msk = BIT(0), + .alg = "rsa\n" +@@ -232,6 +225,20 @@ static const struct hisi_qm_cap_info hpre_basic_info[] = { + {HPRE_CORE10_ALG_BITMAP_CAP, 0x3170, 0, GENMASK(31, 0), 0x0, 0x10, 0x10} + }; + ++enum hpre_pre_store_cap_idx { ++ HPRE_CLUSTER_NUM_CAP_IDX = 0x0, ++ HPRE_CORE_ENABLE_BITMAP_CAP_IDX, ++ HPRE_DRV_ALG_BITMAP_CAP_IDX, ++ HPRE_DEV_ALG_BITMAP_CAP_IDX, ++}; ++ ++static const u32 hpre_pre_store_caps[] = { ++ HPRE_CLUSTER_NUM_CAP, ++ HPRE_CORE_ENABLE_BITMAP_CAP, ++ HPRE_DRV_ALG_BITMAP_CAP, ++ HPRE_DEV_ALG_BITMAP_CAP, ++}; ++ + static const struct hpre_hw_error hpre_hw_errors[] = { + { + .int_msk = BIT(0), +@@ -354,42 +361,13 @@ bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) + { + u32 cap_val; + +- cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DRV_ALG_BITMAP_CAP, qm->cap_ver); ++ cap_val = qm->cap_tables.dev_cap_table[HPRE_DRV_ALG_BITMAP_CAP_IDX].cap_val; + if (alg & cap_val) + return true; + + return false; + } + +-static int hpre_set_qm_algs(struct hisi_qm *qm) +-{ +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u32 alg_msk; +- int i; +- +- if (!qm->use_sva) +- return 0; +- +- algs = devm_kzalloc(dev, HPRE_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) +- return -ENOMEM; +- +- alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); +- +- for (i = 0; i < ARRAY_SIZE(hpre_dev_algs); i++) +- if (alg_msk & hpre_dev_algs[i].alg_msk) +- strcat(algs, hpre_dev_algs[i].alg); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; +- +- qm->uacce->algs = algs; +- +- return 0; +-} +- + static int hpre_diff_regs_show(struct seq_file *s, void *unused) + { + struct hisi_qm *qm = s->private; +@@ -459,16 +437,6 @@ static u32 vfs_num; + module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444); + MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)"); + +-static inline int hpre_cluster_num(struct hisi_qm *qm) +-{ +- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CLUSTER_NUM_CAP, qm->cap_ver); +-} +- +-static inline int hpre_cluster_core_mask(struct hisi_qm *qm) +-{ +- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CORE_ENABLE_BITMAP_CAP, qm->cap_ver); +-} +- + struct hisi_qp *hpre_create_qp(u8 type) + { + int node = cpu_to_node(smp_processor_id()); +@@ -535,13 +503,15 @@ static int hpre_cfg_by_dsm(struct hisi_qm *qm) + + static int hpre_set_cluster(struct hisi_qm *qm) + { +- u32 cluster_core_mask = hpre_cluster_core_mask(qm); +- u8 clusters_num = hpre_cluster_num(qm); + struct device *dev = &qm->pdev->dev; + unsigned long offset; ++ u32 cluster_core_mask; ++ u8 clusters_num; + u32 val = 0; + int ret, i; + ++ cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_ENABLE_BITMAP_CAP_IDX].cap_val; ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + offset = i * HPRE_CLSTR_ADDR_INTRVL; + +@@ -736,11 +706,12 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) + + static void hpre_cnt_regs_clear(struct hisi_qm *qm) + { +- u8 clusters_num = hpre_cluster_num(qm); + unsigned long offset; ++ u8 clusters_num; + int i; + + /* clear clusterX/cluster_ctrl */ ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; + writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); +@@ -1027,13 +998,14 @@ static int hpre_pf_comm_regs_debugfs_init(struct hisi_qm *qm) + + static int hpre_cluster_debugfs_init(struct hisi_qm *qm) + { +- u8 clusters_num = hpre_cluster_num(qm); + struct device *dev = &qm->pdev->dev; + char buf[HPRE_DBGFS_VAL_MAX_LEN]; + struct debugfs_regset32 *regset; + struct dentry *tmp_d; ++ u8 clusters_num; + int i, ret; + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); + if (ret >= HPRE_DBGFS_VAL_MAX_LEN) +@@ -1138,8 +1110,37 @@ static void hpre_debugfs_exit(struct hisi_qm *qm) + debugfs_remove_recursive(qm->debug.debug_root); + } + ++static int hpre_pre_store_cap_reg(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *hpre_cap; ++ struct device *dev = &qm->pdev->dev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(hpre_pre_store_caps); ++ hpre_cap = devm_kzalloc(dev, sizeof(*hpre_cap) * size, GFP_KERNEL); ++ if (!hpre_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ hpre_cap[i].type = hpre_pre_store_caps[i]; ++ hpre_cap[i].cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, ++ hpre_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ if (hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val > HPRE_CLUSTERS_NUM_MAX) { ++ dev_err(dev, "Device cluster num %u is out of range for driver supports %d!\n", ++ hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val, HPRE_CLUSTERS_NUM_MAX); ++ return -EINVAL; ++ } ++ ++ qm->cap_tables.dev_cap_table = hpre_cap; ++ ++ return 0; ++} ++ + static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + if (pdev->revision == QM_HW_V1) { +@@ -1170,7 +1171,16 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = hpre_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = hpre_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = qm->cap_tables.dev_cap_table[HPRE_DEV_ALG_BITMAP_CAP_IDX].cap_val; ++ ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); + if (ret) { + pci_err(pdev, "Failed to set hpre algs!\n"); + hisi_qm_uninit(qm); +@@ -1183,11 +1193,12 @@ static int hpre_show_last_regs_init(struct hisi_qm *qm) + { + int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); + int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); +- u8 clusters_num = hpre_cluster_num(qm); + struct qm_debug *debug = &qm->debug; + void __iomem *io_base; ++ u8 clusters_num; + int i, j, idx; + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); + if (!debug->last_words) +@@ -1224,10 +1235,10 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) + { + int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); + int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); +- u8 clusters_num = hpre_cluster_num(qm); + struct qm_debug *debug = &qm->debug; + struct pci_dev *pdev = qm->pdev; + void __iomem *io_base; ++ u8 clusters_num; + int i, j, idx; + u32 val; + +@@ -1242,6 +1253,7 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) + hpre_com_dfx_regs[i].name, debug->last_words[i], val); + } + ++ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; + for (i = 0; i < clusters_num; i++) { + io_base = qm->io_base + hpre_cluster_offsets[i]; + for (j = 0; j < cluster_dfx_regs_num; j++) { +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index f1589eb3b46af..e889363ed978e 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -228,6 +228,8 @@ + #define QM_QOS_MAX_CIR_U 6 + #define QM_AUTOSUSPEND_DELAY 3000 + ++#define QM_DEV_ALG_MAX_LEN 256 ++ + #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ + (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ + ((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \ +@@ -306,6 +308,13 @@ enum qm_basic_type { + QM_VF_IRQ_NUM_CAP, + }; + ++enum qm_pre_store_cap_idx { ++ QM_EQ_IRQ_TYPE_CAP_IDX = 0x0, ++ QM_AEQ_IRQ_TYPE_CAP_IDX, ++ QM_ABN_IRQ_TYPE_CAP_IDX, ++ QM_PF2VF_IRQ_TYPE_CAP_IDX, ++}; ++ + static const struct hisi_qm_cap_info qm_cap_info_comm[] = { + {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, + {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, +@@ -335,6 +344,13 @@ static const struct hisi_qm_cap_info qm_basic_info[] = { + {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, + }; + ++static const u32 qm_pre_store_caps[] = { ++ QM_EQ_IRQ_TYPE_CAP, ++ QM_AEQ_IRQ_TYPE_CAP, ++ QM_ABN_IRQ_TYPE_CAP, ++ QM_PF2VF_IRQ_TYPE_CAP, ++}; ++ + struct qm_mailbox { + __le16 w0; + __le16 queue_num; +@@ -787,6 +803,40 @@ static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits, + *high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK; + } + ++int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, ++ u32 dev_algs_size) ++{ ++ struct device *dev = &qm->pdev->dev; ++ char *algs, *ptr; ++ int i; ++ ++ if (!qm->uacce) ++ return 0; ++ ++ if (dev_algs_size >= QM_DEV_ALG_MAX_LEN) { ++ dev_err(dev, "algs size %u is equal or larger than %d.\n", ++ dev_algs_size, QM_DEV_ALG_MAX_LEN); ++ return -EINVAL; ++ } ++ ++ algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); ++ if (!algs) ++ return -ENOMEM; ++ ++ for (i = 0; i < dev_algs_size; i++) ++ if (alg_msk & dev_algs[i].alg_msk) ++ strcat(algs, dev_algs[i].alg); ++ ++ ptr = strrchr(algs, '\n'); ++ if (ptr) { ++ *ptr = '\0'; ++ qm->uacce->algs = algs; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(hisi_qm_set_algs); ++ + static u32 qm_get_irq_num(struct hisi_qm *qm) + { + if (qm->fun_type == QM_HW_PF) +@@ -4903,7 +4953,7 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm) + if (qm->fun_type == QM_HW_VF) + return; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) + return; + +@@ -4920,7 +4970,7 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm) + if (qm->fun_type == QM_HW_VF) + return 0; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) + return 0; + +@@ -4937,7 +4987,7 @@ static void qm_unregister_mb_cmd_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -4951,7 +5001,7 @@ static int qm_register_mb_cmd_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -4968,7 +5018,7 @@ static void qm_unregister_aeq_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -4982,7 +5032,7 @@ static int qm_register_aeq_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -5000,7 +5050,7 @@ static void qm_unregister_eq_irq(struct hisi_qm *qm) + struct pci_dev *pdev = qm->pdev; + u32 irq_vector, val; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return; + +@@ -5014,7 +5064,7 @@ static int qm_register_eq_irq(struct hisi_qm *qm) + u32 irq_vector, val; + int ret; + +- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); ++ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) + return 0; + +@@ -5102,7 +5152,29 @@ static int qm_get_qp_num(struct hisi_qm *qm) + return 0; + } + +-static void qm_get_hw_caps(struct hisi_qm *qm) ++static int qm_pre_store_irq_type_caps(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *qm_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(qm_pre_store_caps); ++ qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL); ++ if (!qm_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ qm_cap[i].type = qm_pre_store_caps[i]; ++ qm_cap[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info, ++ qm_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ qm->cap_tables.qm_cap_table = qm_cap; ++ ++ return 0; ++} ++ ++static int qm_get_hw_caps(struct hisi_qm *qm) + { + const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? + qm_cap_info_pf : qm_cap_info_vf; +@@ -5133,6 +5205,9 @@ static void qm_get_hw_caps(struct hisi_qm *qm) + if (val) + set_bit(cap_info[i].type, &qm->caps); + } ++ ++ /* Fetch and save the value of irq type related capability registers */ ++ return qm_pre_store_irq_type_caps(qm); + } + + static int qm_get_pci_res(struct hisi_qm *qm) +@@ -5154,7 +5229,10 @@ static int qm_get_pci_res(struct hisi_qm *qm) + goto err_request_mem_regions; + } + +- qm_get_hw_caps(qm); ++ ret = qm_get_hw_caps(qm); ++ if (ret) ++ goto err_ioremap; ++ + if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + qm->db_interval = QM_QP_DB_INTERVAL; + qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); +diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h +index 3e57fc04b3770..410c83712e285 100644 +--- a/drivers/crypto/hisilicon/sec2/sec.h ++++ b/drivers/crypto/hisilicon/sec2/sec.h +@@ -220,6 +220,13 @@ enum sec_cap_type { + SEC_CORE4_ALG_BITMAP_HIGH, + }; + ++enum sec_cap_reg_record_idx { ++ SEC_DRV_ALG_BITMAP_LOW_IDX = 0x0, ++ SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DEV_ALG_BITMAP_LOW_IDX, ++ SEC_DEV_ALG_BITMAP_HIGH_IDX, ++}; ++ + void sec_destroy_qps(struct hisi_qp **qps, int qp_num); + struct hisi_qp **sec_create_qps(void); + int sec_register_to_crypto(struct hisi_qm *qm); +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 074e50ef512c1..c3a630cb27a62 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -2543,8 +2543,12 @@ err: + + int sec_register_to_crypto(struct hisi_qm *qm) + { +- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); +- int ret; ++ u64 alg_mask; ++ int ret = 0; ++ ++ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DRV_ALG_BITMAP_LOW_IDX); ++ + + ret = sec_register_skcipher(alg_mask); + if (ret) +@@ -2559,7 +2563,10 @@ int sec_register_to_crypto(struct hisi_qm *qm) + + void sec_unregister_from_crypto(struct hisi_qm *qm) + { +- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); ++ u64 alg_mask; ++ ++ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, ++ SEC_DRV_ALG_BITMAP_LOW_IDX); + + sec_unregister_aead(alg_mask, ARRAY_SIZE(sec_aeads)); + sec_unregister_skcipher(alg_mask, ARRAY_SIZE(sec_skciphers)); +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index 62bd8936a9154..bf02a6b2eed41 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -120,7 +120,6 @@ + GENMASK_ULL(42, 25)) + #define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \ + GENMASK_ULL(45, 43)) +-#define SEC_DEV_ALG_MAX_LEN 256 + + struct sec_hw_error { + u32 int_msk; +@@ -132,11 +131,6 @@ struct sec_dfx_item { + u32 offset; + }; + +-struct sec_dev_alg { +- u64 alg_msk; +- const char *algs; +-}; +- + static const char sec_name[] = "hisi_sec2"; + static struct dentry *sec_debugfs_root; + +@@ -173,15 +167,22 @@ static const struct hisi_qm_cap_info sec_basic_info[] = { + {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, + }; + +-static const struct sec_dev_alg sec_dev_algs[] = { { ++static const u32 sec_pre_store_caps[] = { ++ SEC_DRV_ALG_BITMAP_LOW, ++ SEC_DRV_ALG_BITMAP_HIGH, ++ SEC_DEV_ALG_BITMAP_LOW, ++ SEC_DEV_ALG_BITMAP_HIGH, ++}; ++ ++static const struct qm_dev_alg sec_dev_algs[] = { { + .alg_msk = SEC_CIPHER_BITMAP, +- .algs = "cipher\n", ++ .alg = "cipher\n", + }, { + .alg_msk = SEC_DIGEST_BITMAP, +- .algs = "digest\n", ++ .alg = "digest\n", + }, { + .alg_msk = SEC_AEAD_BITMAP, +- .algs = "aead\n", ++ .alg = "aead\n", + }, + }; + +@@ -394,8 +395,8 @@ u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low) + { + u32 cap_val_h, cap_val_l; + +- cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver); +- cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver); ++ cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val; ++ cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val; + + return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l; + } +@@ -1077,37 +1078,31 @@ static int sec_pf_probe_init(struct sec_dev *sec) + return ret; + } + +-static int sec_set_qm_algs(struct hisi_qm *qm) ++static int sec_pre_store_cap_reg(struct hisi_qm *qm) + { +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u64 alg_mask; +- int i; +- +- if (!qm->use_sva) +- return 0; ++ struct hisi_qm_cap_record *sec_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; + +- algs = devm_kzalloc(dev, SEC_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) ++ size = ARRAY_SIZE(sec_pre_store_caps); ++ sec_cap = devm_kzalloc(&pdev->dev, sizeof(*sec_cap) * size, GFP_KERNEL); ++ if (!sec_cap) + return -ENOMEM; + +- alg_mask = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); +- +- for (i = 0; i < ARRAY_SIZE(sec_dev_algs); i++) +- if (alg_mask & sec_dev_algs[i].alg_msk) +- strcat(algs, sec_dev_algs[i].algs); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; ++ for (i = 0; i < size; i++) { ++ sec_cap[i].type = sec_pre_store_caps[i]; ++ sec_cap[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info, ++ sec_pre_store_caps[i], qm->cap_ver); ++ } + +- qm->uacce->algs = algs; ++ qm->cap_tables.dev_cap_table = sec_cap; + + return 0; + } + + static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + qm->pdev = pdev; +@@ -1142,7 +1137,16 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = sec_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = sec_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX); ++ ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); + if (ret) { + pci_err(qm->pdev, "Failed to set sec algs!\n"); + hisi_qm_uninit(qm); +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index 84dbaeb07ea83..cd7ecb2180bf1 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -73,7 +73,6 @@ + #define HZIP_AXI_SHUTDOWN_ENABLE BIT(14) + #define HZIP_WR_PORT BIT(11) + +-#define HZIP_DEV_ALG_MAX_LEN 256 + #define HZIP_ALG_ZLIB_BIT GENMASK(1, 0) + #define HZIP_ALG_GZIP_BIT GENMASK(3, 2) + #define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4) +@@ -106,6 +105,14 @@ + #define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \ + HZIP_CORE_GATED_OOO_EN) + ++/* zip comp high performance */ ++#define HZIP_HIGH_PERF_OFFSET 0x301208 ++ ++enum { ++ HZIP_HIGH_COMP_RATE, ++ HZIP_HIGH_COMP_PERF, ++}; ++ + static const char hisi_zip_name[] = "hisi_zip"; + static struct dentry *hzip_debugfs_root; + +@@ -119,23 +126,18 @@ struct zip_dfx_item { + u32 offset; + }; + +-struct zip_dev_alg { +- u32 alg_msk; +- const char *algs; +-}; +- +-static const struct zip_dev_alg zip_dev_algs[] = { { ++static const struct qm_dev_alg zip_dev_algs[] = { { + .alg_msk = HZIP_ALG_ZLIB_BIT, +- .algs = "zlib\n", ++ .alg = "zlib\n", + }, { + .alg_msk = HZIP_ALG_GZIP_BIT, +- .algs = "gzip\n", ++ .alg = "gzip\n", + }, { + .alg_msk = HZIP_ALG_DEFLATE_BIT, +- .algs = "deflate\n", ++ .alg = "deflate\n", + }, { + .alg_msk = HZIP_ALG_LZ77_BIT, +- .algs = "lz77_zstd\n", ++ .alg = "lz77_zstd\n", + }, + }; + +@@ -246,6 +248,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = { + {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0} + }; + ++enum zip_pre_store_cap_idx { ++ ZIP_CORE_NUM_CAP_IDX = 0x0, ++ ZIP_CLUSTER_COMP_NUM_CAP_IDX, ++ ZIP_CLUSTER_DECOMP_NUM_CAP_IDX, ++ ZIP_DECOMP_ENABLE_BITMAP_IDX, ++ ZIP_COMP_ENABLE_BITMAP_IDX, ++ ZIP_DRV_ALG_BITMAP_IDX, ++ ZIP_DEV_ALG_BITMAP_IDX, ++}; ++ ++static const u32 zip_pre_store_caps[] = { ++ ZIP_CORE_NUM_CAP, ++ ZIP_CLUSTER_COMP_NUM_CAP, ++ ZIP_CLUSTER_DECOMP_NUM_CAP, ++ ZIP_DECOMP_ENABLE_BITMAP, ++ ZIP_COMP_ENABLE_BITMAP, ++ ZIP_DRV_ALG_BITMAP, ++ ZIP_DEV_ALG_BITMAP, ++}; ++ + enum { + HZIP_COMP_CORE0, + HZIP_COMP_CORE1, +@@ -351,6 +373,37 @@ static int hzip_diff_regs_show(struct seq_file *s, void *unused) + return 0; + } + DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs); ++ ++static int perf_mode_set(const char *val, const struct kernel_param *kp) ++{ ++ int ret; ++ u32 n; ++ ++ if (!val) ++ return -EINVAL; ++ ++ ret = kstrtou32(val, 10, &n); ++ if (ret != 0 || (n != HZIP_HIGH_COMP_PERF && ++ n != HZIP_HIGH_COMP_RATE)) ++ return -EINVAL; ++ ++ return param_set_int(val, kp); ++} ++ ++static const struct kernel_param_ops zip_com_perf_ops = { ++ .set = perf_mode_set, ++ .get = param_get_int, ++}; ++ ++/* ++ * perf_mode = 0 means enable high compression rate mode, ++ * perf_mode = 1 means enable high compression performance mode. ++ * These two modes only apply to the compression direction. ++ */ ++static u32 perf_mode = HZIP_HIGH_COMP_RATE; ++module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444); ++MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)"); ++ + static const struct kernel_param_ops zip_uacce_mode_ops = { + .set = uacce_mode_set, + .get = param_get_int, +@@ -409,40 +462,33 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) + { + u32 cap_val; + +- cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver); ++ cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val; + if ((alg & cap_val) == alg) + return true; + + return false; + } + +-static int hisi_zip_set_qm_algs(struct hisi_qm *qm) ++static int hisi_zip_set_high_perf(struct hisi_qm *qm) + { +- struct device *dev = &qm->pdev->dev; +- char *algs, *ptr; +- u32 alg_mask; +- int i; +- +- if (!qm->use_sva) +- return 0; +- +- algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); +- if (!algs) +- return -ENOMEM; +- +- alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); +- +- for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++) +- if (alg_mask & zip_dev_algs[i].alg_msk) +- strcat(algs, zip_dev_algs[i].algs); +- +- ptr = strrchr(algs, '\n'); +- if (ptr) +- *ptr = '\0'; ++ u32 val; ++ int ret; + +- qm->uacce->algs = algs; ++ val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET); ++ if (perf_mode == HZIP_HIGH_COMP_PERF) ++ val |= HZIP_HIGH_COMP_PERF; ++ else ++ val &= ~HZIP_HIGH_COMP_PERF; ++ ++ /* Set perf mode */ ++ writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET); ++ ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET, ++ val, val == perf_mode, HZIP_DELAY_1_US, ++ HZIP_POLL_TIMEOUT_US); ++ if (ret) ++ pci_err(qm->pdev, "failed to set perf mode\n"); + +- return 0; ++ return ret; + } + + static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) +@@ -541,10 +587,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) + } + + /* let's open all compression/decompression cores */ +- dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, +- ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver); +- comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, +- ZIP_COMP_ENABLE_BITMAP, qm->cap_ver); ++ dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; ++ comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val; + writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL); + + /* enable sqc,cqc writeback */ +@@ -771,9 +815,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm) + char buf[HZIP_BUF_SIZE]; + int i; + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); +- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, +- qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; ++ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; + + for (i = 0; i < zip_core_num; i++) { + if (i < zip_comp_core_num) +@@ -915,7 +958,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm) + u32 zip_core_num; + int i, j, idx; + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; + + debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num, + sizeof(unsigned int), GFP_KERNEL); +@@ -971,9 +1014,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm) + hzip_com_dfx_regs[i].name, debug->last_words[i], val); + } + +- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); +- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, +- qm->cap_ver); ++ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; ++ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; ++ + for (i = 0; i < zip_core_num; i++) { + if (i < zip_comp_core_num) + scnprintf(buf, sizeof(buf), "Comp_core-%d", i); +@@ -1114,6 +1157,10 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) + if (ret) + return ret; + ++ ret = hisi_zip_set_high_perf(qm); ++ if (ret) ++ return ret; ++ + hisi_zip_open_sva_prefetch(qm); + hisi_qm_dev_err_init(qm); + hisi_zip_debug_regs_clear(qm); +@@ -1125,8 +1172,31 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) + return ret; + } + ++static int zip_pre_store_cap_reg(struct hisi_qm *qm) ++{ ++ struct hisi_qm_cap_record *zip_cap; ++ struct pci_dev *pdev = qm->pdev; ++ size_t i, size; ++ ++ size = ARRAY_SIZE(zip_pre_store_caps); ++ zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL); ++ if (!zip_cap) ++ return -ENOMEM; ++ ++ for (i = 0; i < size; i++) { ++ zip_cap[i].type = zip_pre_store_caps[i]; ++ zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ++ zip_pre_store_caps[i], qm->cap_ver); ++ } ++ ++ qm->cap_tables.dev_cap_table = zip_cap; ++ ++ return 0; ++} ++ + static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + { ++ u64 alg_msk; + int ret; + + qm->pdev = pdev; +@@ -1162,7 +1232,16 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + return ret; + } + +- ret = hisi_zip_set_qm_algs(qm); ++ /* Fetch and save the value of capability registers */ ++ ret = zip_pre_store_cap_reg(qm); ++ if (ret) { ++ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); ++ hisi_qm_uninit(qm); ++ return ret; ++ } ++ ++ alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val; ++ ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); + if (ret) { + pci_err(qm->pdev, "Failed to set zip algs!\n"); + hisi_qm_uninit(qm); +diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c +index 272c28b5a0883..b83818634ae47 100644 +--- a/drivers/crypto/inside-secure/safexcel_cipher.c ++++ b/drivers/crypto/inside-secure/safexcel_cipher.c +@@ -742,9 +742,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + max(totlen_src, totlen_dst)); + return -EINVAL; + } +- if (sreq->nr_src > 0) +- dma_map_sg(priv->dev, src, sreq->nr_src, +- DMA_BIDIRECTIONAL); ++ if (sreq->nr_src > 0 && ++ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL)) ++ return -EIO; + } else { + if (unlikely(totlen_src && (sreq->nr_src <= 0))) { + dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", +@@ -752,8 +752,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + return -EINVAL; + } + +- if (sreq->nr_src > 0) +- dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); ++ if (sreq->nr_src > 0 && ++ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE)) ++ return -EIO; + + if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { + dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", +@@ -762,9 +763,11 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, + goto unmap; + } + +- if (sreq->nr_dst > 0) +- dma_map_sg(priv->dev, dst, sreq->nr_dst, +- DMA_FROM_DEVICE); ++ if (sreq->nr_dst > 0 && ++ !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) { ++ ret = -EIO; ++ goto unmap; ++ } + } + + memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); +diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c +index 6238d34f8db2f..94eb6f6afa257 100644 +--- a/drivers/crypto/sa2ul.c ++++ b/drivers/crypto/sa2ul.c +@@ -1869,9 +1869,8 @@ static int sa_aead_setkey(struct crypto_aead *authenc, + crypto_aead_set_flags(ctx->fallback.aead, + crypto_aead_get_flags(authenc) & + CRYPTO_TFM_REQ_MASK); +- crypto_aead_setkey(ctx->fallback.aead, key, keylen); + +- return 0; ++ return crypto_aead_setkey(ctx->fallback.aead, key, keylen); + } + + static int sa_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c +index 62d93526920f8..8e84dd98a273d 100644 +--- a/drivers/crypto/sahara.c ++++ b/drivers/crypto/sahara.c +@@ -43,7 +43,6 @@ + #define FLAGS_MODE_MASK 0x000f + #define FLAGS_ENCRYPT BIT(0) + #define FLAGS_CBC BIT(1) +-#define FLAGS_NEW_KEY BIT(3) + + #define SAHARA_HDR_BASE 0x00800000 + #define SAHARA_HDR_SKHA_ALG_AES 0 +@@ -141,8 +140,6 @@ struct sahara_hw_link { + }; + + struct sahara_ctx { +- unsigned long flags; +- + /* AES-specific context */ + int keylen; + u8 key[AES_KEYSIZE_128]; +@@ -151,6 +148,7 @@ struct sahara_ctx { + + struct sahara_aes_reqctx { + unsigned long mode; ++ u8 iv_out[AES_BLOCK_SIZE]; + struct skcipher_request fallback_req; // keep at the end + }; + +@@ -446,27 +444,24 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + int ret; + int i, j; + int idx = 0; ++ u32 len; + +- /* Copy new key if necessary */ +- if (ctx->flags & FLAGS_NEW_KEY) { +- memcpy(dev->key_base, ctx->key, ctx->keylen); +- ctx->flags &= ~FLAGS_NEW_KEY; ++ memcpy(dev->key_base, ctx->key, ctx->keylen); + +- if (dev->flags & FLAGS_CBC) { +- dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; +- dev->hw_desc[idx]->p1 = dev->iv_phys_base; +- } else { +- dev->hw_desc[idx]->len1 = 0; +- dev->hw_desc[idx]->p1 = 0; +- } +- dev->hw_desc[idx]->len2 = ctx->keylen; +- dev->hw_desc[idx]->p2 = dev->key_phys_base; +- dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; ++ if (dev->flags & FLAGS_CBC) { ++ dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; ++ dev->hw_desc[idx]->p1 = dev->iv_phys_base; ++ } else { ++ dev->hw_desc[idx]->len1 = 0; ++ dev->hw_desc[idx]->p1 = 0; ++ } ++ dev->hw_desc[idx]->len2 = ctx->keylen; ++ dev->hw_desc[idx]->p2 = dev->key_phys_base; ++ dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; ++ dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + +- dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); ++ idx++; + +- idx++; +- } + + dev->nb_in_sg = sg_nents_for_len(dev->in_sg, dev->total); + if (dev->nb_in_sg < 0) { +@@ -488,24 +483,27 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + DMA_TO_DEVICE); + if (!ret) { + dev_err(dev->device, "couldn't map in sg\n"); +- goto unmap_in; ++ return -EINVAL; + } ++ + ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_FROM_DEVICE); + if (!ret) { + dev_err(dev->device, "couldn't map out sg\n"); +- goto unmap_out; ++ goto unmap_in; + } + + /* Create input links */ + dev->hw_desc[idx]->p1 = dev->hw_phys_link[0]; + sg = dev->in_sg; ++ len = dev->total; + for (i = 0; i < dev->nb_in_sg; i++) { +- dev->hw_link[i]->len = sg->length; ++ dev->hw_link[i]->len = min(len, sg->length); + dev->hw_link[i]->p = sg->dma_address; + if (i == (dev->nb_in_sg - 1)) { + dev->hw_link[i]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; + sg = sg_next(sg); + } +@@ -514,12 +512,14 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + /* Create output links */ + dev->hw_desc[idx]->p2 = dev->hw_phys_link[i]; + sg = dev->out_sg; ++ len = dev->total; + for (j = i; j < dev->nb_out_sg + i; j++) { +- dev->hw_link[j]->len = sg->length; ++ dev->hw_link[j]->len = min(len, sg->length); + dev->hw_link[j]->p = sg->dma_address; + if (j == (dev->nb_out_sg + i - 1)) { + dev->hw_link[j]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; + sg = sg_next(sg); + } +@@ -538,9 +538,6 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) + + return 0; + +-unmap_out: +- dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, +- DMA_FROM_DEVICE); + unmap_in: + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); +@@ -548,8 +545,24 @@ unmap_in: + return -EINVAL; + } + ++static void sahara_aes_cbc_update_iv(struct skcipher_request *req) ++{ ++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); ++ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); ++ ++ /* Update IV buffer to contain the last ciphertext block */ ++ if (rctx->mode & FLAGS_ENCRYPT) { ++ sg_pcopy_to_buffer(req->dst, sg_nents(req->dst), req->iv, ++ ivsize, req->cryptlen - ivsize); ++ } else { ++ memcpy(req->iv, rctx->iv_out, ivsize); ++ } ++} ++ + static int sahara_aes_process(struct skcipher_request *req) + { ++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); + struct sahara_dev *dev = dev_ptr; + struct sahara_ctx *ctx; + struct sahara_aes_reqctx *rctx; +@@ -571,8 +584,17 @@ static int sahara_aes_process(struct skcipher_request *req) + rctx->mode &= FLAGS_MODE_MASK; + dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode; + +- if ((dev->flags & FLAGS_CBC) && req->iv) +- memcpy(dev->iv_base, req->iv, AES_KEYSIZE_128); ++ if ((dev->flags & FLAGS_CBC) && req->iv) { ++ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); ++ ++ memcpy(dev->iv_base, req->iv, ivsize); ++ ++ if (!(dev->flags & FLAGS_ENCRYPT)) { ++ sg_pcopy_to_buffer(req->src, sg_nents(req->src), ++ rctx->iv_out, ivsize, ++ req->cryptlen - ivsize); ++ } ++ } + + /* assign new context to device */ + dev->ctx = ctx; +@@ -585,16 +607,20 @@ static int sahara_aes_process(struct skcipher_request *req) + + timeout = wait_for_completion_timeout(&dev->dma_completion, + msecs_to_jiffies(SAHARA_TIMEOUT_MS)); +- if (!timeout) { +- dev_err(dev->device, "AES timeout\n"); +- return -ETIMEDOUT; +- } + + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, + DMA_FROM_DEVICE); + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); + ++ if (!timeout) { ++ dev_err(dev->device, "AES timeout\n"); ++ return -ETIMEDOUT; ++ } ++ ++ if ((dev->flags & FLAGS_CBC) && req->iv) ++ sahara_aes_cbc_update_iv(req); ++ + return 0; + } + +@@ -608,7 +634,6 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, + /* SAHARA only supports 128bit keys */ + if (keylen == AES_KEYSIZE_128) { + memcpy(ctx->key, key, keylen); +- ctx->flags |= FLAGS_NEW_KEY; + return 0; + } + +@@ -624,12 +649,40 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, + return crypto_skcipher_setkey(ctx->fallback, key, keylen); + } + ++static int sahara_aes_fallback(struct skcipher_request *req, unsigned long mode) ++{ ++ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ struct sahara_ctx *ctx = crypto_skcipher_ctx( ++ crypto_skcipher_reqtfm(req)); ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); ++ skcipher_request_set_callback(&rctx->fallback_req, ++ req->base.flags, ++ req->base.complete, ++ req->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, req->src, ++ req->dst, req->cryptlen, req->iv); ++ ++ if (mode & FLAGS_ENCRYPT) ++ return crypto_skcipher_encrypt(&rctx->fallback_req); ++ ++ return crypto_skcipher_decrypt(&rctx->fallback_req); ++} ++ + static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) + { + struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); ++ struct sahara_ctx *ctx = crypto_skcipher_ctx( ++ crypto_skcipher_reqtfm(req)); + struct sahara_dev *dev = dev_ptr; + int err = 0; + ++ if (!req->cryptlen) ++ return 0; ++ ++ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) ++ return sahara_aes_fallback(req, mode); ++ + dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n", + req->cryptlen, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); + +@@ -652,81 +705,21 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) + + static int sahara_aes_ecb_encrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_encrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_ENCRYPT); + } + + static int sahara_aes_ecb_decrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_decrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, 0); + } + + static int sahara_aes_cbc_encrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_encrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); + } + + static int sahara_aes_cbc_decrypt(struct skcipher_request *req) + { +- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); +- struct sahara_ctx *ctx = crypto_skcipher_ctx( +- crypto_skcipher_reqtfm(req)); +- +- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { +- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); +- skcipher_request_set_callback(&rctx->fallback_req, +- req->base.flags, +- req->base.complete, +- req->base.data); +- skcipher_request_set_crypt(&rctx->fallback_req, req->src, +- req->dst, req->cryptlen, req->iv); +- return crypto_skcipher_decrypt(&rctx->fallback_req); +- } +- + return sahara_aes_crypt(req, FLAGS_CBC); + } + +@@ -783,6 +776,7 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, + int start) + { + struct scatterlist *sg; ++ unsigned int len; + unsigned int i; + int ret; + +@@ -804,12 +798,14 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, + if (!ret) + return -EFAULT; + ++ len = rctx->total; + for (i = start; i < dev->nb_in_sg + start; i++) { +- dev->hw_link[i]->len = sg->length; ++ dev->hw_link[i]->len = min(len, sg->length); + dev->hw_link[i]->p = sg->dma_address; + if (i == (dev->nb_in_sg + start - 1)) { + dev->hw_link[i]->next = 0; + } else { ++ len -= min(len, sg->length); + dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; + sg = sg_next(sg); + } +@@ -890,24 +886,6 @@ static int sahara_sha_hw_context_descriptor_create(struct sahara_dev *dev, + return 0; + } + +-static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes) +-{ +- if (!sg || !sg->length) +- return nbytes; +- +- while (nbytes && sg) { +- if (nbytes <= sg->length) { +- sg->length = nbytes; +- sg_mark_end(sg); +- break; +- } +- nbytes -= sg->length; +- sg = sg_next(sg); +- } +- +- return nbytes; +-} +- + static int sahara_sha_prepare_request(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -944,36 +922,20 @@ static int sahara_sha_prepare_request(struct ahash_request *req) + hash_later, 0); + } + +- /* nbytes should now be multiple of blocksize */ +- req->nbytes = req->nbytes - hash_later; +- +- sahara_walk_and_recalc(req->src, req->nbytes); +- ++ rctx->total = len - hash_later; + /* have data from previous operation and current */ + if (rctx->buf_cnt && req->nbytes) { + sg_init_table(rctx->in_sg_chain, 2); + sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt); +- + sg_chain(rctx->in_sg_chain, 2, req->src); +- +- rctx->total = req->nbytes + rctx->buf_cnt; + rctx->in_sg = rctx->in_sg_chain; +- +- req->src = rctx->in_sg_chain; + /* only data from previous operation */ + } else if (rctx->buf_cnt) { +- if (req->src) +- rctx->in_sg = req->src; +- else +- rctx->in_sg = rctx->in_sg_chain; +- /* buf was copied into rembuf above */ ++ rctx->in_sg = rctx->in_sg_chain; + sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt); +- rctx->total = rctx->buf_cnt; + /* no data from previous operation */ + } else { + rctx->in_sg = req->src; +- rctx->total = req->nbytes; +- req->src = rctx->in_sg; + } + + /* on next call, we only have the remaining data in the buffer */ +@@ -994,7 +956,10 @@ static int sahara_sha_process(struct ahash_request *req) + return ret; + + if (rctx->first) { +- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); ++ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); ++ if (ret) ++ return ret; ++ + dev->hw_desc[0]->next = 0; + rctx->first = 0; + } else { +@@ -1002,7 +967,10 @@ static int sahara_sha_process(struct ahash_request *req) + + sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0); + dev->hw_desc[0]->next = dev->hw_phys_desc[1]; +- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); ++ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); ++ if (ret) ++ return ret; ++ + dev->hw_desc[1]->next = 0; + } + +@@ -1015,18 +983,19 @@ static int sahara_sha_process(struct ahash_request *req) + + timeout = wait_for_completion_timeout(&dev->dma_completion, + msecs_to_jiffies(SAHARA_TIMEOUT_MS)); +- if (!timeout) { +- dev_err(dev->device, "SHA timeout\n"); +- return -ETIMEDOUT; +- } + + if (rctx->sg_in_idx) + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, + DMA_TO_DEVICE); + ++ if (!timeout) { ++ dev_err(dev->device, "SHA timeout\n"); ++ return -ETIMEDOUT; ++ } ++ + memcpy(rctx->context, dev->context_base, rctx->context_size); + +- if (req->result) ++ if (req->result && rctx->last) + memcpy(req->result, rctx->context, rctx->digest_size); + + return 0; +@@ -1170,8 +1139,7 @@ static int sahara_sha_import(struct ahash_request *req, const void *in) + static int sahara_sha_cra_init(struct crypto_tfm *tfm) + { + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), +- sizeof(struct sahara_sha_reqctx) + +- SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); ++ sizeof(struct sahara_sha_reqctx)); + + return 0; + } +diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c +index 08e974e0dd124..3a67ddc4d9367 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.c ++++ b/drivers/crypto/starfive/jh7110-cryp.c +@@ -180,12 +180,8 @@ static int starfive_cryp_probe(struct platform_device *pdev) + spin_unlock(&dev_list.lock); + + ret = starfive_dma_init(cryp); +- if (ret) { +- if (ret == -EPROBE_DEFER) +- goto err_probe_defer; +- else +- goto err_dma_init; +- } ++ if (ret) ++ goto err_dma_init; + + /* Initialize crypto engine */ + cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1); +@@ -233,7 +229,7 @@ err_dma_init: + + tasklet_kill(&cryp->aes_done); + tasklet_kill(&cryp->hash_done); +-err_probe_defer: ++ + return ret; + } + +diff --git a/drivers/crypto/virtio/virtio_crypto_common.h b/drivers/crypto/virtio/virtio_crypto_common.h +index 154590e1f7643..7059bbe5a2eba 100644 +--- a/drivers/crypto/virtio/virtio_crypto_common.h ++++ b/drivers/crypto/virtio/virtio_crypto_common.h +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -28,6 +29,7 @@ struct data_queue { + char name[32]; + + struct crypto_engine *engine; ++ struct tasklet_struct done_task; + }; + + struct virtio_crypto { +diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c +index 43a0838d31ff0..b909c6a2bf1c3 100644 +--- a/drivers/crypto/virtio/virtio_crypto_core.c ++++ b/drivers/crypto/virtio/virtio_crypto_core.c +@@ -72,27 +72,28 @@ int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, struct scatterl + return 0; + } + +-static void virtcrypto_dataq_callback(struct virtqueue *vq) ++static void virtcrypto_done_task(unsigned long data) + { +- struct virtio_crypto *vcrypto = vq->vdev->priv; ++ struct data_queue *data_vq = (struct data_queue *)data; ++ struct virtqueue *vq = data_vq->vq; + struct virtio_crypto_request *vc_req; +- unsigned long flags; + unsigned int len; +- unsigned int qid = vq->index; + +- spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags); + do { + virtqueue_disable_cb(vq); + while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { +- spin_unlock_irqrestore( +- &vcrypto->data_vq[qid].lock, flags); + if (vc_req->alg_cb) + vc_req->alg_cb(vc_req, len); +- spin_lock_irqsave( +- &vcrypto->data_vq[qid].lock, flags); + } + } while (!virtqueue_enable_cb(vq)); +- spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags); ++} ++ ++static void virtcrypto_dataq_callback(struct virtqueue *vq) ++{ ++ struct virtio_crypto *vcrypto = vq->vdev->priv; ++ struct data_queue *dq = &vcrypto->data_vq[vq->index]; ++ ++ tasklet_schedule(&dq->done_task); + } + + static int virtcrypto_find_vqs(struct virtio_crypto *vi) +@@ -150,6 +151,8 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi) + ret = -ENOMEM; + goto err_engine; + } ++ tasklet_init(&vi->data_vq[i].done_task, virtcrypto_done_task, ++ (unsigned long)&vi->data_vq[i]); + } + + kfree(names); +@@ -497,12 +500,15 @@ static void virtcrypto_free_unused_reqs(struct virtio_crypto *vcrypto) + static void virtcrypto_remove(struct virtio_device *vdev) + { + struct virtio_crypto *vcrypto = vdev->priv; ++ int i; + + dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); + + flush_work(&vcrypto->config_work); + if (virtcrypto_dev_started(vcrypto)) + virtcrypto_dev_stop(vcrypto); ++ for (i = 0; i < vcrypto->max_data_queues; i++) ++ tasklet_kill(&vcrypto->data_vq[i].done_task); + virtio_reset_device(vdev); + virtcrypto_free_unused_reqs(vcrypto); + virtcrypto_clear_crypto_engines(vcrypto); +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index f430280fa6bd0..c67cc8c9d5cc6 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -172,14 +172,10 @@ static ssize_t target_list_show(struct device *dev, + { + struct cxl_switch_decoder *cxlsd = to_cxl_switch_decoder(dev); + ssize_t offset; +- unsigned int seq; + int rc; + +- do { +- seq = read_seqbegin(&cxlsd->target_lock); +- rc = emit_target_list(cxlsd, buf); +- } while (read_seqretry(&cxlsd->target_lock, seq)); +- ++ guard(rwsem_read)(&cxl_region_rwsem); ++ rc = emit_target_list(cxlsd, buf); + if (rc < 0) + return rc; + offset = rc; +@@ -1579,7 +1575,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, CXL); + static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, + struct cxl_port *port, int *target_map) + { +- int i, rc = 0; ++ int i; + + if (!target_map) + return 0; +@@ -1589,19 +1585,16 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, + if (xa_empty(&port->dports)) + return -EINVAL; + +- write_seqlock(&cxlsd->target_lock); +- for (i = 0; i < cxlsd->nr_targets; i++) { ++ guard(rwsem_write)(&cxl_region_rwsem); ++ for (i = 0; i < cxlsd->cxld.interleave_ways; i++) { + struct cxl_dport *dport = find_dport(port, target_map[i]); + +- if (!dport) { +- rc = -ENXIO; +- break; +- } ++ if (!dport) ++ return -ENXIO; + cxlsd->target[i] = dport; + } +- write_sequnlock(&cxlsd->target_lock); + +- return rc; ++ return 0; + } + + struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos) +@@ -1671,7 +1664,6 @@ static int cxl_switch_decoder_init(struct cxl_port *port, + return -EINVAL; + + cxlsd->nr_targets = nr_targets; +- seqlock_init(&cxlsd->target_lock); + return cxl_decoder_init(port, &cxlsd->cxld); + } + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index e7206367ec669..472bd510b5e27 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -397,7 +397,7 @@ static ssize_t interleave_ways_store(struct device *dev, + return rc; + + /* +- * Even for x3, x9, and x12 interleaves the region interleave must be a ++ * Even for x3, x6, and x12 interleaves the region interleave must be a + * power of 2 multiple of the host bridge interleave. + */ + if (!is_power_of_2(val / cxld->interleave_ways) || +diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h +index 6c6afda0e4c61..de2c250c894b1 100644 +--- a/drivers/cxl/cxl.h ++++ b/drivers/cxl/cxl.h +@@ -404,7 +404,6 @@ struct cxl_endpoint_decoder { + /** + * struct cxl_switch_decoder - Switch specific CXL HDM Decoder + * @cxld: base cxl_decoder object +- * @target_lock: coordinate coherent reads of the target list + * @nr_targets: number of elements in @target + * @target: active ordered target list in current decoder configuration + * +@@ -416,7 +415,6 @@ struct cxl_endpoint_decoder { + */ + struct cxl_switch_decoder { + struct cxl_decoder cxld; +- seqlock_t target_lock; + int nr_targets; + struct cxl_dport *target[]; + }; +diff --git a/drivers/edac/thunderx_edac.c b/drivers/edac/thunderx_edac.c +index b9c5772da959c..90d46e5c4ff06 100644 +--- a/drivers/edac/thunderx_edac.c ++++ b/drivers/edac/thunderx_edac.c +@@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) + decode_register(other, OCX_OTHER_SIZE, + ocx_com_errors, ctx->reg_com_int); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + for (lane = 0; lane < OCX_RX_LANES; lane++) + if (ctx->reg_com_int & BIT(lane)) { +@@ -1142,12 +1142,12 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) + lane, ctx->reg_lane_int[lane], + lane, ctx->reg_lane_stat11[lane]); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + decode_register(other, OCX_OTHER_SIZE, + ocx_lane_errors, + ctx->reg_lane_int[lane]); +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + } + + if (ctx->reg_com_int & OCX_COM_INT_CE) +@@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id) + decode_register(other, OCX_OTHER_SIZE, + ocx_com_link_errors, ctx->reg_com_link_int); + +- strncat(msg, other, OCX_MESSAGE_SIZE); ++ strlcat(msg, other, OCX_MESSAGE_SIZE); + + if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) + edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); +@@ -1896,7 +1896,7 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id) + + decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); + +- strncat(msg, other, L2C_MESSAGE_SIZE); ++ strlcat(msg, other, L2C_MESSAGE_SIZE); + + if (ctx->reg_int & mask_ue) + edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index 66c3846c91476..3b4c9355cb60f 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -161,7 +161,7 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, + { + struct device *dev = &pdev->dev; + struct resource *res; +- char debug_name[50] = "ti_sci_debug@"; ++ char debug_name[50]; + + /* Debug region is optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, +@@ -178,10 +178,10 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, + /* Setup NULL termination */ + info->debug_buffer[info->debug_region_size] = 0; + +- info->d = debugfs_create_file(strncat(debug_name, dev_name(dev), +- sizeof(debug_name) - +- sizeof("ti_sci_debug@")), +- 0444, NULL, info, &ti_sci_debug_fops); ++ snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", ++ dev_name(dev)); ++ info->d = debugfs_create_file(debug_name, 0444, NULL, info, ++ &ti_sci_debug_fops); + if (IS_ERR(info->d)) + return PTR_ERR(info->d); + +diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c +index 7a3e1760fc5b7..d5906d419b0ab 100644 +--- a/drivers/gpio/gpio-mlxbf3.c ++++ b/drivers/gpio/gpio-mlxbf3.c +@@ -215,6 +215,8 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev) + gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR, + gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET, + gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0); ++ if (ret) ++ return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__); + + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; +diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c +index c7c5c19ebc66f..12d853845bb80 100644 +--- a/drivers/gpio/gpiolib-sysfs.c ++++ b/drivers/gpio/gpiolib-sysfs.c +@@ -817,7 +817,7 @@ static int __init gpiolib_sysfs_init(void) + * gpiochip_sysfs_register() acquires a mutex. This is unsafe + * and needs to be fixed. + * +- * Also it would be nice to use gpiochip_find() here so we ++ * Also it would be nice to use gpio_device_find() here so we + * can keep gpio_chips local to gpiolib.c, but the yield of + * gpio_lock prevents us from doing this. + */ +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 40a0022ea7190..71492d213ef4d 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1014,16 +1014,10 @@ void gpiochip_remove(struct gpio_chip *gc) + } + EXPORT_SYMBOL_GPL(gpiochip_remove); + +-/** +- * gpiochip_find() - iterator for locating a specific gpio_chip +- * @data: data to pass to match function +- * @match: Callback function to check gpio_chip ++/* ++ * FIXME: This will be removed soon. + * +- * Similar to bus_find_device. It returns a reference to a gpio_chip as +- * determined by a user supplied @match callback. The callback should return +- * 0 if the device doesn't match and non-zero if it does. If the callback is +- * non-zero, this function will return to the caller and not iterate over any +- * more gpio_chips. ++ * This function is depracated, don't use. + */ + struct gpio_chip *gpiochip_find(void *data, + int (*match)(struct gpio_chip *gc, +@@ -1031,21 +1025,62 @@ struct gpio_chip *gpiochip_find(void *data, + { + struct gpio_device *gdev; + struct gpio_chip *gc = NULL; +- unsigned long flags; +- +- spin_lock_irqsave(&gpio_lock, flags); +- list_for_each_entry(gdev, &gpio_devices, list) +- if (gdev->chip && match(gdev->chip, data)) { +- gc = gdev->chip; +- break; +- } + +- spin_unlock_irqrestore(&gpio_lock, flags); ++ gdev = gpio_device_find(data, match); ++ if (gdev) { ++ gc = gdev->chip; ++ gpio_device_put(gdev); ++ } + + return gc; + } + EXPORT_SYMBOL_GPL(gpiochip_find); + ++/** ++ * gpio_device_find() - find a specific GPIO device ++ * @data: data to pass to match function ++ * @match: Callback function to check gpio_chip ++ * ++ * Returns: ++ * New reference to struct gpio_device. ++ * ++ * Similar to bus_find_device(). It returns a reference to a gpio_device as ++ * determined by a user supplied @match callback. The callback should return ++ * 0 if the device doesn't match and non-zero if it does. If the callback ++ * returns non-zero, this function will return to the caller and not iterate ++ * over any more gpio_devices. ++ * ++ * The callback takes the GPIO chip structure as argument. During the execution ++ * of the callback function the chip is protected from being freed. TODO: This ++ * actually has yet to be implemented. ++ * ++ * If the function returns non-NULL, the returned reference must be freed by ++ * the caller using gpio_device_put(). ++ */ ++struct gpio_device *gpio_device_find(void *data, ++ int (*match)(struct gpio_chip *gc, ++ void *data)) ++{ ++ struct gpio_device *gdev; ++ ++ /* ++ * Not yet but in the future the spinlock below will become a mutex. ++ * Annotate this function before anyone tries to use it in interrupt ++ * context like it happened with gpiochip_find(). ++ */ ++ might_sleep(); ++ ++ guard(spinlock_irqsave)(&gpio_lock); ++ ++ list_for_each_entry(gdev, &gpio_devices, list) { ++ if (gdev->chip && match(gdev->chip, data)) ++ return gpio_device_get(gdev); ++ } ++ ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(gpio_device_find); ++ + static int gpiochip_match_name(struct gpio_chip *gc, void *data) + { + const char *name = data; +@@ -1058,6 +1093,30 @@ static struct gpio_chip *find_chip_by_name(const char *name) + return gpiochip_find((void *)name, gpiochip_match_name); + } + ++/** ++ * gpio_device_get() - Increase the reference count of this GPIO device ++ * @gdev: GPIO device to increase the refcount for ++ * ++ * Returns: ++ * Pointer to @gdev. ++ */ ++struct gpio_device *gpio_device_get(struct gpio_device *gdev) ++{ ++ return to_gpio_device(get_device(&gdev->dev)); ++} ++EXPORT_SYMBOL_GPL(gpio_device_get); ++ ++/** ++ * gpio_device_put() - Decrease the reference count of this GPIO device and ++ * possibly free all resources associated with it. ++ * @gdev: GPIO device to decrease the reference count for ++ */ ++void gpio_device_put(struct gpio_device *gdev) ++{ ++ put_device(&gdev->dev); ++} ++EXPORT_SYMBOL_GPL(gpio_device_put); ++ + #ifdef CONFIG_GPIOLIB_IRQCHIP + + /* +diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h +index a0a67569300b9..aa19260836893 100644 +--- a/drivers/gpio/gpiolib.h ++++ b/drivers/gpio/gpiolib.h +@@ -86,16 +86,6 @@ static inline struct gpio_device *to_gpio_device(struct device *dev) + return container_of(dev, struct gpio_device, dev); + } + +-static inline struct gpio_device *gpio_device_get(struct gpio_device *gdev) +-{ +- return to_gpio_device(get_device(&gdev->dev)); +-} +- +-static inline void gpio_device_put(struct gpio_device *gdev) +-{ +- put_device(&gdev->dev); +-} +- + /* gpio suffixes used for ACPI and device tree lookup */ + static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index 3f2126f99923e..418ff7cd662da 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -755,7 +755,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, + int r; + + if (!adev->smc_rreg) +- return -EPERM; ++ return -EOPNOTSUPP; + + if (size & 0x3 || *pos & 0x3) + return -EINVAL; +@@ -814,7 +814,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * + int r; + + if (!adev->smc_wreg) +- return -EPERM; ++ return -EOPNOTSUPP; + + if (size & 0x3 || *pos & 0x3) + return -EINVAL; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index 2c35036e4ba25..635b58553583b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2197,6 +2197,8 @@ retry_init: + + pci_wake_from_d3(pdev, TRUE); + ++ pci_wake_from_d3(pdev, TRUE); ++ + /* + * For runpm implemented via BACO, PMFW will handle the + * timing for BACO in and out: +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index d30dc0b718c73..58dab4f73a9a2 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -1026,7 +1026,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + if (amdgpu_dpm_read_sensor(adev, + AMDGPU_PP_SENSOR_GPU_AVG_POWER, + (void *)&ui32, &ui32_size)) { +- return -EINVAL; ++ /* fall back to input power for backwards compat */ ++ if (amdgpu_dpm_read_sensor(adev, ++ AMDGPU_PP_SENSOR_GPU_INPUT_POWER, ++ (void *)&ui32, &ui32_size)) { ++ return -EINVAL; ++ } + } + ui32 >>= 8; + break; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +index 62b205dac63a0..6604a3f99c5ec 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +@@ -330,12 +330,6 @@ static void kfd_init_apertures_vi(struct kfd_process_device *pdd, uint8_t id) + pdd->gpuvm_limit = + pdd->dev->kfd->shared_resources.gpuvm_size - 1; + +- /* dGPUs: the reserved space for kernel +- * before SVM +- */ +- pdd->qpd.cwsr_base = SVM_CWSR_BASE; +- pdd->qpd.ib_base = SVM_IB_BASE; +- + pdd->scratch_base = MAKE_SCRATCH_APP_BASE_VI(); + pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base); + } +@@ -345,18 +339,18 @@ static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id) + pdd->lds_base = MAKE_LDS_APP_BASE_V9(); + pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base); + +- pdd->gpuvm_base = PAGE_SIZE; ++ /* Raven needs SVM to support graphic handle, etc. Leave the small ++ * reserved space before SVM on Raven as well, even though we don't ++ * have to. ++ * Set gpuvm_base and gpuvm_limit to CANONICAL addresses so that they ++ * are used in Thunk to reserve SVM. ++ */ ++ pdd->gpuvm_base = SVM_USER_BASE; + pdd->gpuvm_limit = + pdd->dev->kfd->shared_resources.gpuvm_size - 1; + + pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9(); + pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base); +- +- /* +- * Place TBA/TMA on opposite side of VM hole to prevent +- * stray faults from triggering SVM on these pages. +- */ +- pdd->qpd.cwsr_base = pdd->dev->kfd->shared_resources.gpuvm_size; + } + + int kfd_init_apertures(struct kfd_process *process) +@@ -413,6 +407,12 @@ int kfd_init_apertures(struct kfd_process *process) + return -EINVAL; + } + } ++ ++ /* dGPUs: the reserved space for kernel ++ * before SVM ++ */ ++ pdd->qpd.cwsr_base = SVM_CWSR_BASE; ++ pdd->qpd.ib_base = SVM_IB_BASE; + } + + dev_dbg(kfd_device, "node id %u\n", id); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +index 7d82c7da223ab..659313648b200 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +@@ -1021,7 +1021,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev) + } else { + res = devm_request_free_mem_region(adev->dev, &iomem_resource, size); + if (IS_ERR(res)) +- return -ENOMEM; ++ return PTR_ERR(res); + pgmap->range.start = res->start; + pgmap->range.end = res->end; + pgmap->type = MEMORY_DEVICE_PRIVATE; +@@ -1037,10 +1037,10 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev) + r = devm_memremap_pages(adev->dev, pgmap); + if (IS_ERR(r)) { + pr_err("failed to register HMM device memory\n"); +- /* Disable SVM support capability */ +- pgmap->type = 0; + if (pgmap->type == MEMORY_DEVICE_PRIVATE) + devm_release_mem_region(adev->dev, res->start, resource_size(res)); ++ /* Disable SVM support capability */ ++ pgmap->type = 0; + return PTR_ERR(r); + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index df7a5cdb8693f..3287a39613959 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -971,7 +971,7 @@ struct kfd_process { + struct work_struct debug_event_workarea; + + /* Tracks debug per-vmid request for debug flags */ +- bool dbg_flags; ++ u32 dbg_flags; + + atomic_t poison; + /* Queues are in paused stated because we are in the process of doing a CRIU checkpoint */ +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index c8c75ff7cea80..6e75e8fa18be5 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -1342,10 +1342,11 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g + num_cpu++; + } + ++ if (list_empty(&kdev->io_link_props)) ++ return -ENODATA; ++ + gpu_link = list_first_entry(&kdev->io_link_props, +- struct kfd_iolink_properties, list); +- if (!gpu_link) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); + + for (i = 0; i < num_cpu; i++) { + /* CPU <--> GPU */ +@@ -1423,15 +1424,17 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, + peer->gpu->adev)) + return ret; + ++ if (list_empty(&kdev->io_link_props)) ++ return -ENODATA; ++ + iolink1 = list_first_entry(&kdev->io_link_props, +- struct kfd_iolink_properties, list); +- if (!iolink1) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); ++ ++ if (list_empty(&peer->io_link_props)) ++ return -ENODATA; + + iolink2 = list_first_entry(&peer->io_link_props, +- struct kfd_iolink_properties, list); +- if (!iolink2) +- return -ENOMEM; ++ struct kfd_iolink_properties, list); + + props = kfd_alloc_struct(props); + if (!props) +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 5084833e3608f..861b5e45e2a7c 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -6882,7 +6882,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, + max_bpc); + bpp = convert_dc_color_depth_into_bpc(color_depth) * 3; + clock = adjusted_mode->clock; +- dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false); ++ dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp << 4); + } + + dm_new_connector_state->vcpi_slots = +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 28f5eb9ecbd3e..10dd4cd6f59c9 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1636,7 +1636,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( + } else { + /* check if mode could be supported within full_pbn */ + bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; +- pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); ++ pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp << 4); + if (pbn > full_pbn) + return DC_FAIL_BANDWIDTH_VALIDATE; + } +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +index 90339c2dfd848..5a0b045189569 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +@@ -807,7 +807,7 @@ void dp_decide_lane_settings( + const struct link_training_settings *lt_settings, + const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], + struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], +- union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) ++ union dpcd_training_lane *dpcd_lane_settings) + { + uint32_t lane; + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h +index 7d027bac82551..851bd17317a0c 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h +@@ -111,7 +111,7 @@ void dp_decide_lane_settings( + const struct link_training_settings *lt_settings, + const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], + struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], +- union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); ++ union dpcd_training_lane *dpcd_lane_settings); + + enum dc_dp_training_pattern decide_cr_training_pattern( + const struct dc_link_settings *link_settings); +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +index 5d28c951a3197..5cb4725c773f6 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +@@ -2735,10 +2735,8 @@ static int kv_parse_power_table(struct amdgpu_device *adev) + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; + ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); +- if (ps == NULL) { +- kfree(adev->pm.dpm.ps); ++ if (ps == NULL) + return -ENOMEM; +- } + adev->pm.dpm.ps[i].ps_priv = ps; + k = 0; + idx = (u8 *)&power_state->v2.clockInfoIndex[0]; +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +index 81fb4e5dd804b..60377747bab4f 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +@@ -272,10 +272,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usVddciDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -283,10 +281,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usVddcDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -294,10 +290,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usMvddDependencyOnMCLKOffset) { + dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) +@@ -305,10 +299,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset)); + ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk, + dep_table); +- if (ret) { +- amdgpu_free_extended_power_table(adev); ++ if (ret) + return ret; +- } + } + if (power_info->pplib4.usMaxClockVoltageOnDCOffset) { + ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v = +@@ -339,10 +331,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + kcalloc(psl->ucNumEntries, + sizeof(struct amdgpu_phase_shedding_limits_entry), + GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) + return -ENOMEM; +- } + + entry = &psl->entries[0]; + for (i = 0; i < psl->ucNumEntries; i++) { +@@ -383,10 +373,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ATOM_PPLIB_CAC_Leakage_Record *entry; + u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table); + adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) + return -ENOMEM; +- } + entry = &cac_table->entries[0]; + for (i = 0; i < cac_table->ucNumEntries; i++) { + if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) { +@@ -438,10 +426,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_vce_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -493,10 +479,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -525,10 +509,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -548,10 +530,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + le16_to_cpu(ext_hdr->usPPMTableOffset)); + adev->pm.dpm.dyn_state.ppm_table = + kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.ppm_table) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.ppm_table) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign; + adev->pm.dpm.dyn_state.ppm_table->cpu_core_number = + le16_to_cpu(ppm->usCpuCoreNumber); +@@ -583,10 +563,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + sizeof(struct amdgpu_clock_voltage_dependency_entry); + adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries = + kzalloc(size, GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) + return -ENOMEM; +- } + adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; +@@ -606,10 +584,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ATOM_PowerTune_Table *pt; + adev->pm.dpm.dyn_state.cac_tdp_table = + kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.cac_tdp_table) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.cac_tdp_table) + return -ENOMEM; +- } + if (rev > 0) { + ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *) + (mode_info->atom_context->bios + data_offset + +@@ -645,10 +621,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) + ret = amdgpu_parse_clk_voltage_dep_table( + &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk, + dep_table); +- if (ret) { +- kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries); ++ if (ret) + return ret; +- } + } + } + +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +index 02e69ccff3bac..f81e4bd48110f 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +@@ -7379,10 +7379,9 @@ static int si_dpm_init(struct amdgpu_device *adev) + kcalloc(4, + sizeof(struct amdgpu_clock_voltage_dependency_entry), + GFP_KERNEL); +- if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { +- amdgpu_free_extended_power_table(adev); ++ if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) + return -ENOMEM; +- } ++ + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4; + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0; + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index 11372fcc59c8f..b1a8799e2dee3 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -2974,6 +2974,8 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + result = smu7_get_evv_voltages(hwmgr); + if (result) { + pr_info("Get EVV Voltage Failed. Abort Driver loading!\n"); ++ kfree(hwmgr->backend); ++ hwmgr->backend = NULL; + return -EINVAL; + } + } else { +@@ -3019,8 +3021,10 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + } + + result = smu7_update_edc_leakage_table(hwmgr); +- if (result) ++ if (result) { ++ smu7_hwmgr_backend_fini(hwmgr); + return result; ++ } + + return 0; + } +diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +index 946212a955981..5e3b8edcf7948 100644 +--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c ++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +@@ -403,7 +403,8 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp) + + static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type) + { +- int ret, tries = 3; ++ int ret = -EINVAL; ++ int tries = 3; + u32 i; + + for (i = 0; i < tries; i++) { +diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c +index b45bffab7c817..d941c3a0e6113 100644 +--- a/drivers/gpu/drm/bridge/tc358767.c ++++ b/drivers/gpu/drm/bridge/tc358767.c +@@ -2273,7 +2273,7 @@ static int tc_probe(struct i2c_client *client) + } else { + if (tc->hpd_pin < 0 || tc->hpd_pin > 1) { + dev_err(dev, "failed to parse HPD number\n"); +- return ret; ++ return -EINVAL; + } + } + +diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c b/drivers/gpu/drm/bridge/ti-tpd12s015.c +index e0e015243a602..b588fea12502d 100644 +--- a/drivers/gpu/drm/bridge/ti-tpd12s015.c ++++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c +@@ -179,7 +179,7 @@ static int tpd12s015_probe(struct platform_device *pdev) + return 0; + } + +-static int __exit tpd12s015_remove(struct platform_device *pdev) ++static int tpd12s015_remove(struct platform_device *pdev) + { + struct tpd12s015_device *tpd = platform_get_drvdata(pdev); + +@@ -197,7 +197,7 @@ MODULE_DEVICE_TABLE(of, tpd12s015_of_match); + + static struct platform_driver tpd12s015_driver = { + .probe = tpd12s015_probe, +- .remove = __exit_p(tpd12s015_remove), ++ .remove = tpd12s015_remove, + .driver = { + .name = "tpd12s015", + .of_match_table = tpd12s015_of_match, +diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c +index 8c929ef72c72c..6d169c83b0623 100644 +--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c +@@ -4690,13 +4690,12 @@ EXPORT_SYMBOL(drm_dp_check_act_status); + + /** + * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode. +- * @clock: dot clock for the mode +- * @bpp: bpp for the mode. +- * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel ++ * @clock: dot clock ++ * @bpp: bpp as .4 binary fixed point + * + * This uses the formula in the spec to calculate the PBN value for a mode. + */ +-int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc) ++int drm_dp_calc_pbn_mode(int clock, int bpp) + { + /* + * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 +@@ -4707,18 +4706,9 @@ int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc) + * peak_kbps *= (1006/1000) + * peak_kbps *= (64/54) + * peak_kbps *= 8 convert to bytes +- * +- * If the bpp is in units of 1/16, further divide by 16. Put this +- * factor in the numerator rather than the denominator to avoid +- * integer overflow + */ +- +- if (dsc) +- return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006), +- 8 * 54 * 1000 * 1000); +- +- return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006), +- 8 * 54 * 1000 * 1000); ++ return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006 >> 4), ++ 1000 * 8 * 54 * 1000); + } + EXPORT_SYMBOL(drm_dp_calc_pbn_mode); + +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 3eda026ffac6a..71bb8806dc5f5 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -940,8 +940,11 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) + goto err_minors; + } + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- drm_modeset_register_all(dev); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = drm_modeset_register_all(dev); ++ if (ret) ++ goto err_unload; ++ } + + DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + driver->name, driver->major, driver->minor, +@@ -951,6 +954,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) + + goto out_unlock; + ++err_unload: ++ if (dev->driver->unload) ++ dev->driver->unload(dev); + err_minors: + remove_compat_control_link(dev); + drm_minor_unregister(dev, DRM_MINOR_ACCEL); +diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c +index 77bd1313c808f..f104bd7f8c2a6 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c +@@ -109,8 +109,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, + continue; + + crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, +- dsc ? bpp << 4 : bpp, +- dsc); ++ bpp << 4); + + slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, + connector->port, +@@ -941,7 +940,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, + return ret; + + if (mode_rate > max_rate || mode->clock > max_dotclk || +- drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) { ++ drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) { + *status = MODE_CLOCK_HIGH; + return 0; + } +diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +index 22b65f4a0e303..4beb3b4bd6942 100644 +--- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c ++++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +@@ -342,21 +342,12 @@ static const struct drm_mode_config_helper_funcs imx_lcdc_mode_config_helpers = + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, + }; + +-static void imx_lcdc_release(struct drm_device *drm) +-{ +- struct imx_lcdc *lcdc = imx_lcdc_from_drmdev(drm); +- +- drm_kms_helper_poll_fini(drm); +- kfree(lcdc); +-} +- + DEFINE_DRM_GEM_DMA_FOPS(imx_lcdc_drm_fops); + + static struct drm_driver imx_lcdc_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .fops = &imx_lcdc_drm_fops, + DRM_GEM_DMA_DRIVER_OPS_VMAP, +- .release = imx_lcdc_release, + .name = "imx-lcdc", + .desc = "i.MX LCDC driver", + .date = "20200716", +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c +index e525a6b9e5b0b..22f768d923d5a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c +@@ -103,7 +103,7 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) + mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, + DISP_REG_MERGE_CTRL); + +- if (priv->async_clk) ++ if (!cmdq_pkt && priv->async_clk) + reset_control_reset(priv->reset_ctl); + } + +diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c +index 0e285df6577ea..4052a3133b576 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dp.c ++++ b/drivers/gpu/drm/mediatek/mtk_dp.c +@@ -2784,3 +2784,4 @@ MODULE_AUTHOR("Markus Schneider-Pargmann "); + MODULE_AUTHOR("Bo-Chen Chen "); + MODULE_DESCRIPTION("MediaTek DisplayPort Driver"); + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: phy_mtk_dp"); +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 2f931e4e2b600..bc073a6b367e5 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -957,20 +957,6 @@ static const struct mtk_dpi_conf mt8186_conf = { + .csc_enable_bit = CSC_ENABLE, + }; + +-static const struct mtk_dpi_conf mt8188_dpintf_conf = { +- .cal_factor = mt8195_dpintf_calculate_factor, +- .max_clock_khz = 600000, +- .output_fmts = mt8195_output_fmts, +- .num_output_fmts = ARRAY_SIZE(mt8195_output_fmts), +- .pixels_per_iter = 4, +- .input_2pixel = false, +- .dimension_mask = DPINTF_HPW_MASK, +- .hvsize_mask = DPINTF_HSIZE_MASK, +- .channel_swap_shift = DPINTF_CH_SWAP, +- .yuv422_en_bit = DPINTF_YUV422_EN, +- .csc_enable_bit = DPINTF_CSC_ENABLE, +-}; +- + static const struct mtk_dpi_conf mt8192_conf = { + .cal_factor = mt8183_calculate_factor, + .reg_h_fre_con = 0xe0, +@@ -1094,7 +1080,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = { + { .compatible = "mediatek,mt8173-dpi", .data = &mt8173_conf }, + { .compatible = "mediatek,mt8183-dpi", .data = &mt8183_conf }, + { .compatible = "mediatek,mt8186-dpi", .data = &mt8186_conf }, +- { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8188_dpintf_conf }, ++ { .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf }, + { .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf }, + { .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf }, + { /* sentinel */ }, +diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +index c3adaeefd551a..c7233d0ac210f 100644 +--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c ++++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +@@ -246,8 +246,7 @@ int mtk_mdp_rdma_clk_enable(struct device *dev) + { + struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); + +- clk_prepare_enable(rdma->clk); +- return 0; ++ return clk_prepare_enable(rdma->clk); + } + + void mtk_mdp_rdma_clk_disable(struct device *dev) +diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c +index f2d9d34ed50f9..b7b527e21dac8 100644 +--- a/drivers/gpu/drm/msm/adreno/adreno_device.c ++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c +@@ -462,7 +462,7 @@ static const struct adreno_info gpulist[] = { + { 190, 1 }, + ), + }, { +- .chip_ids = ADRENO_CHIP_IDS(0x06080000), ++ .chip_ids = ADRENO_CHIP_IDS(0x06080001), + .family = ADRENO_6XX_GEN2, + .revn = 680, + .fw = { +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +index f3de21025ca73..c92fbf24fbac1 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +@@ -377,6 +377,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = { + .min_llcc_ib = 800000, + .min_dram_ib = 800000, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, ++ .safe_lut_tbl = {0xfff0, 0xf000, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +index 5f9b437b82a68..ee781037ada93 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +@@ -32,7 +32,7 @@ static const struct dpu_mdp_cfg sm8250_mdp = { + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, +- [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, ++ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + }, + }; + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +index d030c08636b4c..69d3f7e5e095b 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +@@ -25,7 +25,7 @@ static const struct dpu_mdp_cfg sc7180_mdp = { + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, +- [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, ++ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + }, + }; + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +index 3b5061c4402a6..9195cb996f444 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +@@ -25,7 +25,7 @@ static const struct dpu_mdp_cfg sc7280_mdp = { + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, +- [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, ++ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, + }, + }; + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +index 8ce7586e2ddf7..e238e4e8116ca 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (C) 2013 Red Hat + * Author: Rob Clark +@@ -125,7 +125,7 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) + continue; + + /* Calculate MISR over 1 frame */ +- m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); ++ m->hw_lm->ops.setup_misr(m->hw_lm); + } + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index d34e684a41789..b02aa2eb6c176 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -2,7 +2,7 @@ + /* + * Copyright (C) 2013 Red Hat + * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Author: Rob Clark + */ +@@ -255,7 +255,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) + if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) + continue; + +- phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); ++ phys->hw_intf->ops.setup_misr(phys->hw_intf); + } + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +index 8ec6505d9e786..da071b1c02afe 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + +@@ -318,9 +318,9 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) + return DPU_REG_READ(c, INTF_LINE_COUNT); + } + +-static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) ++static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) + { +- dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); ++ dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1); + } + + static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +index 77f80531782b5..4e86108bee289 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + +@@ -94,7 +94,7 @@ struct dpu_hw_intf_ops { + + void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, + const enum dpu_pingpong pp); +- void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); ++ void (*setup_misr)(struct dpu_hw_intf *intf); + int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); + + // Tearcheck on INTF since DPU 5.0.0 +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +index d1c3bd8379ea9..a590c1f7465fb 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -81,9 +81,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, + } + } + +-static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) ++static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) + { +- dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); ++ dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); + } + + static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +index 36992d046a533..98b77cda65472 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +@@ -1,5 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -57,7 +58,7 @@ struct dpu_hw_lm_ops { + /** + * setup_misr: Enable/disable MISR + */ +- void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); ++ void (*setup_misr)(struct dpu_hw_mixer *ctx); + + /** + * collect_misr: Read MISR signature +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +index 9d2273fd2fed5..6eee9f68ab4c7 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + */ + #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ +@@ -481,9 +481,11 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, + cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); + } + ++/* ++ * note: Aside from encoders, input_sel should be set to 0x0 by default ++ */ + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, +- u32 misr_ctrl_offset, +- bool enable, u32 frame_count) ++ u32 misr_ctrl_offset, u8 input_sel) + { + u32 config = 0; + +@@ -492,15 +494,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, + /* Clear old MISR value (in case it's read before a new value is calculated)*/ + wmb(); + +- if (enable) { +- config = (frame_count & MISR_FRAME_COUNT_MASK) | +- MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; +- +- DPU_REG_WRITE(c, misr_ctrl_offset, config); +- } else { +- DPU_REG_WRITE(c, misr_ctrl_offset, 0); +- } +- ++ config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | ++ ((input_sel & 0xF) << 24); ++ DPU_REG_WRITE(c, misr_ctrl_offset, config); + } + + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +index 1f6079f470710..0aed54d7f6c94 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + /* +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +@@ -13,7 +13,7 @@ + #include "dpu_hw_catalog.h" + + #define REG_MASK(n) ((BIT(n)) - 1) +-#define MISR_FRAME_COUNT_MASK 0xFF ++#define MISR_FRAME_COUNT 0x1 + #define MISR_CTRL_ENABLE BIT(8) + #define MISR_CTRL_STATUS BIT(9) + #define MISR_CTRL_STATUS_CLEAR BIT(10) +@@ -358,9 +358,7 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, + const struct dpu_hw_qos_cfg *cfg); + + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, +- u32 misr_ctrl_offset, +- bool enable, +- u32 frame_count); ++ u32 misr_ctrl_offset, u8 input_sel); + + int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, + u32 misr_ctrl_offset, +diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +index 169f9de4a12a7..3100957225a70 100644 +--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c ++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +@@ -269,6 +269,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, + { + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct mdp4_kms *mdp4_kms = get_kms(crtc); ++ unsigned long flags; + + DBG("%s", mdp4_crtc->name); + +@@ -281,6 +282,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, + mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); + mdp4_disable(mdp4_kms); + ++ if (crtc->state->event && !crtc->state->active) { ++ WARN_ON(mdp4_crtc->event); ++ spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); ++ drm_crtc_send_vblank_event(crtc, crtc->state->event); ++ crtc->state->event = NULL; ++ spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); ++ } ++ + mdp4_crtc->enabled = false; + } + +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +index 05621e5e7d634..b6314bb66d2fd 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +@@ -516,7 +516,9 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) + struct device *dev = &phy->pdev->dev; + int ret; + +- pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); ++ if (ret) ++ return ret; + + ret = clk_prepare_enable(phy->ahb_clk); + if (ret) { +diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c +index 617162aac060f..de8041c94de5d 100644 +--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c +@@ -966,8 +966,7 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, + const int clock = crtc_state->adjusted_mode.clock; + + asyh->or.bpc = connector->display_info.bpc; +- asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3, +- false); ++ asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3 << 4); + } + + mst_state = drm_atomic_get_mst_topology_state(state, &mstm->mgr); +diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c +index 5b71a5a5cd85c..cdbc75e3d1f66 100644 +--- a/drivers/gpu/drm/nouveau/nv04_fence.c ++++ b/drivers/gpu/drm/nouveau/nv04_fence.c +@@ -39,7 +39,7 @@ struct nv04_fence_priv { + static int + nv04_fence_emit(struct nouveau_fence *fence) + { +- struct nvif_push *push = fence->channel->chan.push; ++ struct nvif_push *push = unrcu_pointer(fence->channel)->chan.push; + int ret = PUSH_WAIT(push, 2); + if (ret == 0) { + PUSH_NVSQ(push, NV_SW, 0x0150, fence->base.seqno); +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index afeeb77375525..e000577a95dd7 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -69,7 +69,6 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + { + struct drm_device *dev = old_state->dev; + struct omap_drm_private *priv = dev->dev_private; +- bool fence_cookie = dma_fence_begin_signalling(); + + dispc_runtime_get(priv->dispc); + +@@ -92,6 +91,8 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + omap_atomic_wait_for_completion(dev, old_state); + + drm_atomic_helper_commit_planes(dev, old_state, 0); ++ ++ drm_atomic_helper_commit_hw_done(old_state); + } else { + /* + * OMAP3 DSS seems to have issues with the work-around above, +@@ -101,11 +102,9 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) + drm_atomic_helper_commit_planes(dev, old_state, 0); + + drm_atomic_helper_commit_modeset_enables(dev, old_state); +- } + +- drm_atomic_helper_commit_hw_done(old_state); +- +- dma_fence_end_signalling(fence_cookie); ++ drm_atomic_helper_commit_hw_done(old_state); ++ } + + /* + * Wait for completion of the page flips to ensure that old buffers +diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +index e7be15b681021..6de1172323464 100644 +--- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c ++++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c +@@ -104,6 +104,8 @@ static int kd35t133_unprepare(struct drm_panel *panel) + return ret; + } + ++ gpiod_set_value_cansleep(ctx->reset_gpio, 1); ++ + regulator_disable(ctx->iovcc); + regulator_disable(ctx->vdd); + +diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +index ad98dd9322b4a..227937afe2572 100644 +--- a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c ++++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +@@ -261,6 +261,8 @@ static int panel_nv3051d_unprepare(struct drm_panel *panel) + + usleep_range(10000, 15000); + ++ gpiod_set_value_cansleep(ctx->reset_gpio, 1); ++ + regulator_disable(ctx->vdd); + + return 0; +diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c +index 0459965e1b4f7..036ac403ed213 100644 +--- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c ++++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c +@@ -288,7 +288,7 @@ static void st7701_init_sequence(struct st7701 *st7701) + FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVDD_MASK, + DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | + FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVCL_MASK, +- DIV_ROUND_CLOSEST(-4400 + desc->avcl_mv, 200))); ++ DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); + + /* T2D = 0.2us * T2D[3:0] */ + ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, +diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c +index d28b99732ddeb..eca45b83e4e67 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c +@@ -71,7 +71,12 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev) + } + + gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL); +- gpu_write(pfdev, GPU_INT_MASK, GPU_IRQ_MASK_ALL); ++ ++ /* Only enable the interrupts we care about */ ++ gpu_write(pfdev, GPU_INT_MASK, ++ GPU_IRQ_MASK_ERROR | ++ GPU_IRQ_PERFCNT_SAMPLE_COMPLETED | ++ GPU_IRQ_CLEAN_CACHES_COMPLETED); + + return 0; + } +@@ -321,28 +326,38 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) + pfdev->features.shader_present, pfdev->features.l2_present); + } + ++static u64 panfrost_get_core_mask(struct panfrost_device *pfdev) ++{ ++ u64 core_mask; ++ ++ if (pfdev->features.l2_present == 1) ++ return U64_MAX; ++ ++ /* ++ * Only support one core group now. ++ * ~(l2_present - 1) unsets all bits in l2_present except ++ * the bottom bit. (l2_present - 2) has all the bits in ++ * the first core group set. AND them together to generate ++ * a mask of cores in the first core group. ++ */ ++ core_mask = ~(pfdev->features.l2_present - 1) & ++ (pfdev->features.l2_present - 2); ++ dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", ++ hweight64(core_mask), ++ hweight64(pfdev->features.shader_present)); ++ ++ return core_mask; ++} ++ + void panfrost_gpu_power_on(struct panfrost_device *pfdev) + { + int ret; + u32 val; +- u64 core_mask = U64_MAX; ++ u64 core_mask; + + panfrost_gpu_init_quirks(pfdev); ++ core_mask = panfrost_get_core_mask(pfdev); + +- if (pfdev->features.l2_present != 1) { +- /* +- * Only support one core group now. +- * ~(l2_present - 1) unsets all bits in l2_present except +- * the bottom bit. (l2_present - 2) has all the bits in +- * the first core group set. AND them together to generate +- * a mask of cores in the first core group. +- */ +- core_mask = ~(pfdev->features.l2_present - 1) & +- (pfdev->features.l2_present - 2); +- dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", +- hweight64(core_mask), +- hweight64(pfdev->features.shader_present)); +- } + gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask); + ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, + val, val == (pfdev->features.l2_present & core_mask), +@@ -367,9 +382,26 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev) + + void panfrost_gpu_power_off(struct panfrost_device *pfdev) + { +- gpu_write(pfdev, TILER_PWROFF_LO, 0); +- gpu_write(pfdev, SHADER_PWROFF_LO, 0); +- gpu_write(pfdev, L2_PWROFF_LO, 0); ++ int ret; ++ u32 val; ++ ++ gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present); ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO, ++ val, !val, 1, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "shader power transition timeout"); ++ ++ gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); ++ ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO, ++ val, !val, 1, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "tiler power transition timeout"); ++ ++ gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); ++ ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO, ++ val, !val, 0, 1000); ++ if (ret) ++ dev_err(pfdev->dev, "l2 power transition timeout"); + } + + int panfrost_gpu_init(struct panfrost_device *pfdev) +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index affa9e0309b27..cfeca2694d5f9 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -2321,7 +2321,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) + switch (prim_walk) { + case 1: + for (i = 0; i < track->num_arrays; i++) { +- size = track->arrays[i].esize * track->max_indx * 4; ++ size = track->arrays[i].esize * track->max_indx * 4UL; + if (track->arrays[i].robj == NULL) { + DRM_ERROR("(PW %u) Vertex array %u no buffer " + "bound\n", prim_walk, i); +@@ -2340,7 +2340,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) + break; + case 2: + for (i = 0; i < track->num_arrays; i++) { +- size = track->arrays[i].esize * (nverts - 1) * 4; ++ size = track->arrays[i].esize * (nverts - 1) * 4UL; + if (track->arrays[i].robj == NULL) { + DRM_ERROR("(PW %u) Vertex array %u no buffer " + "bound\n", prim_walk, i); +diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c +index 638f861af80fa..6cf54a747749d 100644 +--- a/drivers/gpu/drm/radeon/r600_cs.c ++++ b/drivers/gpu/drm/radeon/r600_cs.c +@@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) + return -EINVAL; + } + tmp = (reg - CB_COLOR0_BASE) / 4; +- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; ++ track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); + track->cb_color_base_last[tmp] = ib[idx]; + track->cb_color_bo[tmp] = reloc->robj; +@@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) + "0x%04X\n", reg); + return -EINVAL; + } +- track->htile_offset = radeon_get_ib_value(p, idx) << 8; ++ track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8; + ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); + track->htile_bo = reloc->robj; + track->db_dirty = true; +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 901e75ec70ff4..efd18c8d84c83 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -687,11 +687,16 @@ static void radeon_crtc_init(struct drm_device *dev, int index) + if (radeon_crtc == NULL) + return; + ++ radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); ++ if (!radeon_crtc->flip_queue) { ++ kfree(radeon_crtc); ++ return; ++ } ++ + drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); + + drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); + radeon_crtc->crtc_id = index; +- radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); + rdev->mode_info.crtcs[index] = radeon_crtc; + + if (rdev->family >= CHIP_BONAIRE) { +diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c +index 987cabbf1318e..c38b4d5d6a14f 100644 +--- a/drivers/gpu/drm/radeon/radeon_vm.c ++++ b/drivers/gpu/drm/radeon/radeon_vm.c +@@ -1204,13 +1204,17 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) + r = radeon_bo_create(rdev, pd_size, align, true, + RADEON_GEM_DOMAIN_VRAM, 0, NULL, + NULL, &vm->page_directory); +- if (r) ++ if (r) { ++ kfree(vm->page_tables); ++ vm->page_tables = NULL; + return r; +- ++ } + r = radeon_vm_clear_bo(rdev, vm->page_directory); + if (r) { + radeon_bo_unref(&vm->page_directory); + vm->page_directory = NULL; ++ kfree(vm->page_tables); ++ vm->page_tables = NULL; + return r; + } + +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index a91012447b56e..85e9cba49cecb 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -3611,6 +3611,10 @@ static int si_cp_start(struct radeon_device *rdev) + for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { + ring = &rdev->ring[i]; + r = radeon_ring_lock(rdev, ring, 2); ++ if (r) { ++ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); ++ return r; ++ } + + /* clear the compute context state */ + radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); +diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c +index f74f381af05fd..d49c145db4370 100644 +--- a/drivers/gpu/drm/radeon/sumo_dpm.c ++++ b/drivers/gpu/drm/radeon/sumo_dpm.c +@@ -1493,8 +1493,10 @@ static int sumo_parse_power_table(struct radeon_device *rdev) + non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; +- if (!rdev->pm.power_state[i].clock_info) ++ if (!rdev->pm.power_state[i].clock_info) { ++ kfree(rdev->pm.dpm.ps); + return -EINVAL; ++ } + ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + if (ps == NULL) { + kfree(rdev->pm.dpm.ps); +diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c +index 08ea1c864cb23..ef1cc7bad20a7 100644 +--- a/drivers/gpu/drm/radeon/trinity_dpm.c ++++ b/drivers/gpu/drm/radeon/trinity_dpm.c +@@ -1726,8 +1726,10 @@ static int trinity_parse_power_table(struct radeon_device *rdev) + non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; +- if (!rdev->pm.power_state[i].clock_info) ++ if (!rdev->pm.power_state[i].clock_info) { ++ kfree(rdev->pm.dpm.ps); + return -EINVAL; ++ } + ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + if (ps == NULL) { + kfree(rdev->pm.dpm.ps); +diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +index 545beea33e8c7..e3c818dfc0e6d 100644 +--- a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c ++++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +@@ -42,13 +42,13 @@ static const struct drm_dp_mst_calc_pbn_mode_test drm_dp_mst_calc_pbn_mode_cases + .clock = 332880, + .bpp = 24, + .dsc = true, +- .expected = 50 ++ .expected = 1191 + }, + { + .clock = 324540, + .bpp = 24, + .dsc = true, +- .expected = 49 ++ .expected = 1161 + }, + }; + +@@ -56,7 +56,7 @@ static void drm_test_dp_mst_calc_pbn_mode(struct kunit *test) + { + const struct drm_dp_mst_calc_pbn_mode_test *params = test->param_value; + +- KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp, params->dsc), ++ KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp << 4), + params->expected); + } + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 9d9dee7abaefd..98efbaf3b0c23 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -2702,18 +2702,69 @@ static void dispc_init_errata(struct dispc_device *dispc) + } + } + +-static void dispc_softreset(struct dispc_device *dispc) ++static int dispc_softreset(struct dispc_device *dispc) + { + u32 val; + int ret = 0; + ++ /* K2G display controller does not support soft reset */ ++ if (dispc->feat->subrev == DISPC_K2G) ++ return 0; ++ + /* Soft reset */ + REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); + /* Wait for reset to complete */ + ret = readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS, + val, val & 1, 100, 5000); ++ if (ret) { ++ dev_err(dispc->dev, "failed to reset dispc\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int dispc_init_hw(struct dispc_device *dispc) ++{ ++ struct device *dev = dispc->dev; ++ int ret; ++ ++ ret = pm_runtime_set_active(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to active\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(dispc->fclk); ++ if (ret) { ++ dev_err(dev, "Failed to enable DSS fclk\n"); ++ goto err_runtime_suspend; ++ } ++ ++ ret = dispc_softreset(dispc); + if (ret) +- dev_warn(dispc->dev, "failed to reset dispc\n"); ++ goto err_clk_disable; ++ ++ clk_disable_unprepare(dispc->fclk); ++ ret = pm_runtime_set_suspended(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to suspended\n"); ++ return ret; ++ } ++ ++ return 0; ++ ++err_clk_disable: ++ clk_disable_unprepare(dispc->fclk); ++ ++err_runtime_suspend: ++ ret = pm_runtime_set_suspended(dev); ++ if (ret) { ++ dev_err(dev, "Failed to set DSS PM to suspended\n"); ++ return ret; ++ } ++ ++ return ret; + } + + int dispc_init(struct tidss_device *tidss) +@@ -2777,10 +2828,6 @@ int dispc_init(struct tidss_device *tidss) + return r; + } + +- /* K2G display controller does not support soft reset */ +- if (feat->subrev != DISPC_K2G) +- dispc_softreset(dispc); +- + for (i = 0; i < dispc->feat->num_vps; i++) { + u32 gamma_size = dispc->feat->vp_feat.color.gamma_size; + u32 *gamma_table; +@@ -2829,6 +2876,10 @@ int dispc_init(struct tidss_device *tidss) + of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth", + &dispc->memory_bandwidth_limit); + ++ r = dispc_init_hw(dispc); ++ if (r) ++ return r; ++ + tidss->dispc = dispc; + + return 0; +diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c +index c979ad1af2366..d096d8d2bc8f8 100644 +--- a/drivers/gpu/drm/tidss/tidss_kms.c ++++ b/drivers/gpu/drm/tidss/tidss_kms.c +@@ -4,8 +4,6 @@ + * Author: Tomi Valkeinen + */ + +-#include +- + #include + #include + #include +@@ -25,7 +23,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) + { + struct drm_device *ddev = old_state->dev; + struct tidss_device *tidss = to_tidss(ddev); +- bool fence_cookie = dma_fence_begin_signalling(); + + dev_dbg(ddev->dev, "%s\n", __func__); + +@@ -36,7 +33,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) + drm_atomic_helper_commit_modeset_enables(ddev, old_state); + + drm_atomic_helper_commit_hw_done(old_state); +- dma_fence_end_signalling(fence_cookie); + drm_atomic_helper_wait_for_flip_done(ddev, old_state); + + drm_atomic_helper_cleanup_planes(ddev, old_state); +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +index 8ebd7134ee21b..2f6eaac7f659b 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -138,7 +138,7 @@ static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) + if (ret) + return ret; + +- priv->irq_enabled = false; ++ priv->irq_enabled = true; + + return 0; + } +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index 2eba152e8b905..26e93a331a510 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -632,7 +632,7 @@ static int sensor_hub_probe(struct hid_device *hdev, + } + INIT_LIST_HEAD(&hdev->inputs); + +- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); ++ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_DRIVER); + if (ret) { + hid_err(hdev, "hw start failed\n"); + return ret; +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 471db78dbbf02..8289ce7637044 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -2649,8 +2649,8 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + { + struct hid_data *hid_data = &wacom_wac->hid_data; + bool mt = wacom_wac->features.touch_max > 1; +- bool prox = hid_data->tipswitch && +- report_touch_events(wacom_wac); ++ bool touch_down = hid_data->tipswitch && hid_data->confidence; ++ bool prox = touch_down && report_touch_events(wacom_wac); + + if (touch_is_muted(wacom_wac)) { + if (!wacom_wac->shared->touch_down) +@@ -2700,24 +2700,6 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, + } + } + +-static bool wacom_wac_slot_is_active(struct input_dev *dev, int key) +-{ +- struct input_mt *mt = dev->mt; +- struct input_mt_slot *s; +- +- if (!mt) +- return false; +- +- for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { +- if (s->key == key && +- input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) { +- return true; +- } +- } +- +- return false; +-} +- + static void wacom_wac_finger_event(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage, __s32 value) + { +@@ -2768,14 +2750,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev, + } + + if (usage->usage_index + 1 == field->report_count) { +- if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { +- bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input, +- wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch; +- +- if (wacom_wac->hid_data.confidence || touch_removed) { +- wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); +- } +- } ++ if (equivalent_usage == wacom_wac->hid_data.last_slot_field) ++ wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); + } + } + +diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c +index 127eb3805facb..c324cb3c97e2b 100644 +--- a/drivers/i2c/busses/i2c-s3c2410.c ++++ b/drivers/i2c/busses/i2c-s3c2410.c +@@ -216,8 +216,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c) + int tries; + + for (tries = 50; tries; --tries) { +- if (readl(i2c->regs + S3C2410_IICCON) +- & S3C2410_IICCON_IRQPEND) { ++ unsigned long tmp = readl(i2c->regs + S3C2410_IICCON); ++ ++ if (!(tmp & S3C2410_IICCON_ACKEN)) { ++ /* ++ * Wait a bit for the bus to stabilize, ++ * delay estimated experimentally. ++ */ ++ usleep_range(100, 200); ++ return true; ++ } ++ if (tmp & S3C2410_IICCON_IRQPEND) { + if (!(readl(i2c->regs + S3C2410_IICSTAT) + & S3C2410_IICSTAT_LASTBIT)) + return true; +@@ -270,16 +279,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, + + stat |= S3C2410_IICSTAT_START; + writel(stat, i2c->regs + S3C2410_IICSTAT); +- +- if (i2c->quirks & QUIRK_POLL) { +- while ((i2c->msg_num != 0) && is_ack(i2c)) { +- i2c_s3c_irq_nextbyte(i2c, stat); +- stat = readl(i2c->regs + S3C2410_IICSTAT); +- +- if (stat & S3C2410_IICSTAT_ARBITR) +- dev_err(i2c->dev, "deal with arbitration loss\n"); +- } +- } + } + + static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) +@@ -686,7 +685,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c) + static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, + struct i2c_msg *msgs, int num) + { +- unsigned long timeout; ++ unsigned long timeout = 0; + int ret; + + ret = s3c24xx_i2c_set_master(i2c); +@@ -706,16 +705,19 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, + s3c24xx_i2c_message_start(i2c, msgs); + + if (i2c->quirks & QUIRK_POLL) { +- ret = i2c->msg_idx; ++ while ((i2c->msg_num != 0) && is_ack(i2c)) { ++ unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT); + +- if (ret != num) +- dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); ++ i2c_s3c_irq_nextbyte(i2c, stat); + +- goto out; ++ stat = readl(i2c->regs + S3C2410_IICSTAT); ++ if (stat & S3C2410_IICSTAT_ARBITR) ++ dev_err(i2c->dev, "deal with arbitration loss\n"); ++ } ++ } else { ++ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); + } + +- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); +- + ret = i2c->msg_idx; + + /* +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index ea5a6a14c5537..45500d2d5b4bb 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -131,11 +131,12 @@ static unsigned int mwait_substates __initdata; + #define MWAIT2flg(eax) ((eax & 0xFF) << 24) + + static __always_inline int __intel_idle(struct cpuidle_device *dev, +- struct cpuidle_driver *drv, int index) ++ struct cpuidle_driver *drv, ++ int index, bool irqoff) + { + struct cpuidle_state *state = &drv->states[index]; + unsigned long eax = flg2MWAIT(state->flags); +- unsigned long ecx = 1; /* break on interrupt flag */ ++ unsigned long ecx = 1*irqoff; /* break on interrupt flag */ + + mwait_idle_with_hints(eax, ecx); + +@@ -159,19 +160,13 @@ static __always_inline int __intel_idle(struct cpuidle_device *dev, + static __cpuidle int intel_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) + { +- return __intel_idle(dev, drv, index); ++ return __intel_idle(dev, drv, index, true); + } + + static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) + { +- int ret; +- +- raw_local_irq_enable(); +- ret = __intel_idle(dev, drv, index); +- raw_local_irq_disable(); +- +- return ret; ++ return __intel_idle(dev, drv, index, false); + } + + static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, +@@ -184,7 +179,7 @@ static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, + if (smt_active) + native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); + +- ret = __intel_idle(dev, drv, index); ++ ret = __intel_idle(dev, drv, index, true); + + if (smt_active) + native_wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); +@@ -196,7 +191,7 @@ static __cpuidle int intel_idle_xstate(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) + { + fpu_idle_fpregs(); +- return __intel_idle(dev, drv, index); ++ return __intel_idle(dev, drv, index, true); + } + + /** +diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c +index 8e252cde735b9..0e5d3d2e9c985 100644 +--- a/drivers/iio/adc/ad7091r-base.c ++++ b/drivers/iio/adc/ad7091r-base.c +@@ -174,8 +174,8 @@ static const struct iio_info ad7091r_info = { + + static irqreturn_t ad7091r_event_handler(int irq, void *private) + { +- struct ad7091r_state *st = (struct ad7091r_state *) private; +- struct iio_dev *iio_dev = dev_get_drvdata(st->dev); ++ struct iio_dev *iio_dev = private; ++ struct ad7091r_state *st = iio_priv(iio_dev); + unsigned int i, read_val; + int ret; + s64 timestamp = iio_get_time_ns(iio_dev); +@@ -234,7 +234,7 @@ int ad7091r_probe(struct device *dev, const char *name, + if (irq) { + ret = devm_request_threaded_irq(dev, irq, NULL, + ad7091r_event_handler, +- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st); ++ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev); + if (ret) + return ret; + } +diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c +index 39eccc28debe4..f668313730cb6 100644 +--- a/drivers/iio/adc/ad9467.c ++++ b/drivers/iio/adc/ad9467.c +@@ -4,8 +4,9 @@ + * + * Copyright 2012-2020 Analog Devices Inc. + */ +- ++#include + #include ++#include + #include + #include + #include +@@ -119,9 +120,11 @@ struct ad9467_state { + struct spi_device *spi; + struct clk *clk; + unsigned int output_mode; ++ unsigned int (*scales)[2]; + + struct gpio_desc *pwrdown_gpio; +- struct gpio_desc *reset_gpio; ++ /* ensure consistent state obtained on multiple related accesses */ ++ struct mutex lock; + }; + + static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) +@@ -162,10 +165,12 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg, + int ret; + + if (readval == NULL) { ++ guard(mutex)(&st->lock); + ret = ad9467_spi_write(spi, reg, writeval); +- ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, +- AN877_ADC_TRANSFER_SYNC); +- return ret; ++ if (ret) ++ return ret; ++ return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, ++ AN877_ADC_TRANSFER_SYNC); + } + + ret = ad9467_spi_read(spi, reg); +@@ -212,6 +217,7 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, + .channel = _chan, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ ++ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = _si, \ + .scan_type = { \ + .sign = _sign, \ +@@ -273,10 +279,13 @@ static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2) + const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + unsigned int i, vref_val; ++ int ret; + +- vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); ++ ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); ++ if (ret < 0) ++ return ret; + +- vref_val &= info1->vref_mask; ++ vref_val = ret & info1->vref_mask; + + for (i = 0; i < info->num_scales; i++) { + if (vref_val == info->scale_table[i][1]) +@@ -297,6 +306,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + unsigned int scale_val[2]; + unsigned int i; ++ int ret; + + if (val != 0) + return -EINVAL; +@@ -306,11 +316,14 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) + if (scale_val[0] != val || scale_val[1] != val2) + continue; + +- ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, +- info->scale_table[i][1]); +- ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, +- AN877_ADC_TRANSFER_SYNC); +- return 0; ++ guard(mutex)(&st->lock); ++ ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, ++ info->scale_table[i][1]); ++ if (ret < 0) ++ return ret; ++ ++ return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, ++ AN877_ADC_TRANSFER_SYNC); + } + + return -EINVAL; +@@ -359,6 +372,26 @@ static int ad9467_write_raw(struct adi_axi_adc_conv *conv, + } + } + ++static int ad9467_read_avail(struct adi_axi_adc_conv *conv, ++ struct iio_chan_spec const *chan, ++ const int **vals, int *type, int *length, ++ long mask) ++{ ++ const struct adi_axi_adc_chip_info *info = conv->chip_info; ++ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_SCALE: ++ *vals = (const int *)st->scales; ++ *type = IIO_VAL_INT_PLUS_MICRO; ++ /* Values are stored in a 2D matrix */ ++ *length = info->num_scales * 2; ++ return IIO_AVAIL_LIST; ++ default: ++ return -EINVAL; ++ } ++} ++ + static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) + { + int ret; +@@ -371,6 +404,26 @@ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) + AN877_ADC_TRANSFER_SYNC); + } + ++static int ad9467_scale_fill(struct adi_axi_adc_conv *conv) ++{ ++ const struct adi_axi_adc_chip_info *info = conv->chip_info; ++ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); ++ unsigned int i, val1, val2; ++ ++ st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, ++ sizeof(*st->scales), GFP_KERNEL); ++ if (!st->scales) ++ return -ENOMEM; ++ ++ for (i = 0; i < info->num_scales; i++) { ++ __ad9467_get_scale(conv, i, &val1, &val2); ++ st->scales[i][0] = val1; ++ st->scales[i][1] = val2; ++ } ++ ++ return 0; ++} ++ + static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) + { + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); +@@ -378,6 +431,21 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) + return ad9467_outputmode_set(st->spi, st->output_mode); + } + ++static int ad9467_reset(struct device *dev) ++{ ++ struct gpio_desc *gpio; ++ ++ gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR_OR_NULL(gpio)) ++ return PTR_ERR_OR_ZERO(gpio); ++ ++ fsleep(1); ++ gpiod_set_value_cansleep(gpio, 0); ++ fsleep(10 * USEC_PER_MSEC); ++ ++ return 0; ++} ++ + static int ad9467_probe(struct spi_device *spi) + { + const struct ad9467_chip_info *info; +@@ -408,21 +476,16 @@ static int ad9467_probe(struct spi_device *spi) + if (IS_ERR(st->pwrdown_gpio)) + return PTR_ERR(st->pwrdown_gpio); + +- st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", +- GPIOD_OUT_LOW); +- if (IS_ERR(st->reset_gpio)) +- return PTR_ERR(st->reset_gpio); +- +- if (st->reset_gpio) { +- udelay(1); +- ret = gpiod_direction_output(st->reset_gpio, 1); +- if (ret) +- return ret; +- mdelay(10); +- } ++ ret = ad9467_reset(&spi->dev); ++ if (ret) ++ return ret; + + conv->chip_info = &info->axi_adc_info; + ++ ret = ad9467_scale_fill(conv); ++ if (ret) ++ return ret; ++ + id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); + if (id != conv->chip_info->id) { + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", +@@ -433,6 +496,7 @@ static int ad9467_probe(struct spi_device *spi) + conv->reg_access = ad9467_reg_access; + conv->write_raw = ad9467_write_raw; + conv->read_raw = ad9467_read_raw; ++ conv->read_avail = ad9467_read_avail; + conv->preenable_setup = ad9467_preenable_setup; + + st->output_mode = info->default_output_mode | +diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c +index aff0532a974aa..ae83ada7f9f2d 100644 +--- a/drivers/iio/adc/adi-axi-adc.c ++++ b/drivers/iio/adc/adi-axi-adc.c +@@ -144,6 +144,20 @@ static int adi_axi_adc_write_raw(struct iio_dev *indio_dev, + return conv->write_raw(conv, chan, val, val2, mask); + } + ++static int adi_axi_adc_read_avail(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ const int **vals, int *type, int *length, ++ long mask) ++{ ++ struct adi_axi_adc_state *st = iio_priv(indio_dev); ++ struct adi_axi_adc_conv *conv = &st->client->conv; ++ ++ if (!conv->read_avail) ++ return -EOPNOTSUPP; ++ ++ return conv->read_avail(conv, chan, vals, type, length, mask); ++} ++ + static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) + { +@@ -228,69 +242,11 @@ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev, + } + EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI); + +-static ssize_t in_voltage_scale_available_show(struct device *dev, +- struct device_attribute *attr, +- char *buf) +-{ +- struct iio_dev *indio_dev = dev_to_iio_dev(dev); +- struct adi_axi_adc_state *st = iio_priv(indio_dev); +- struct adi_axi_adc_conv *conv = &st->client->conv; +- size_t len = 0; +- int i; +- +- for (i = 0; i < conv->chip_info->num_scales; i++) { +- const unsigned int *s = conv->chip_info->scale_table[i]; +- +- len += scnprintf(buf + len, PAGE_SIZE - len, +- "%u.%06u ", s[0], s[1]); +- } +- buf[len - 1] = '\n'; +- +- return len; +-} +- +-static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); +- +-enum { +- ADI_AXI_ATTR_SCALE_AVAIL, +-}; +- +-#define ADI_AXI_ATTR(_en_, _file_) \ +- [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr +- +-static struct attribute *adi_axi_adc_attributes[] = { +- ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available), +- NULL +-}; +- +-static umode_t axi_adc_attr_is_visible(struct kobject *kobj, +- struct attribute *attr, int n) +-{ +- struct device *dev = kobj_to_dev(kobj); +- struct iio_dev *indio_dev = dev_to_iio_dev(dev); +- struct adi_axi_adc_state *st = iio_priv(indio_dev); +- struct adi_axi_adc_conv *conv = &st->client->conv; +- +- switch (n) { +- case ADI_AXI_ATTR_SCALE_AVAIL: +- if (!conv->chip_info->num_scales) +- return 0; +- return attr->mode; +- default: +- return attr->mode; +- } +-} +- +-static const struct attribute_group adi_axi_adc_attribute_group = { +- .attrs = adi_axi_adc_attributes, +- .is_visible = axi_adc_attr_is_visible, +-}; +- + static const struct iio_info adi_axi_adc_info = { + .read_raw = &adi_axi_adc_read_raw, + .write_raw = &adi_axi_adc_write_raw, +- .attrs = &adi_axi_adc_attribute_group, + .update_scan_mode = &adi_axi_adc_update_scan_mode, ++ .read_avail = &adi_axi_adc_read_avail, + }; + + static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = { +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 486d635b6e3ab..3c62a0042da48 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -2693,6 +2693,10 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev) + return 0; + + create_failed_qp: ++ for (i--; i >= 0; i--) { ++ hns_roce_v2_destroy_qp(&free_mr->rsv_qp[i]->ibqp, NULL); ++ kfree(free_mr->rsv_qp[i]); ++ } + hns_roce_destroy_cq(cq, NULL); + kfree(cq); + +@@ -5634,7 +5638,7 @@ static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq, + + /* Resizing SRQs is not supported yet */ + if (srq_attr_mask & IB_SRQ_MAX_WR) +- return -EINVAL; ++ return -EOPNOTSUPP; + + if (srq_attr_mask & IB_SRQ_LIMIT) { + if (srq_attr->srq_limit > srq->wqe_cnt) +diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c +index 783e71852c503..bd1fe89ca205e 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_pd.c ++++ b/drivers/infiniband/hw/hns/hns_roce_pd.c +@@ -150,7 +150,7 @@ int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) + int ret; + + if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) +- return -EINVAL; ++ return -EOPNOTSUPP; + + ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); + if (ret) +diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c +index f330ce895d884..8fe0cef7e2be6 100644 +--- a/drivers/infiniband/hw/mthca/mthca_cmd.c ++++ b/drivers/infiniband/hw/mthca/mthca_cmd.c +@@ -635,7 +635,7 @@ void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox) + + int mthca_SYS_EN(struct mthca_dev *dev) + { +- u64 out; ++ u64 out = 0; + int ret; + + ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); +@@ -1955,7 +1955,7 @@ int mthca_WRITE_MGM(struct mthca_dev *dev, int index, + int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, + u16 *hash) + { +- u64 imm; ++ u64 imm = 0; + int err; + + err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, +diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c +index b54bc8865daec..1ab268b770968 100644 +--- a/drivers/infiniband/hw/mthca/mthca_main.c ++++ b/drivers/infiniband/hw/mthca/mthca_main.c +@@ -382,7 +382,7 @@ static int mthca_init_icm(struct mthca_dev *mdev, + struct mthca_init_hca_param *init_hca, + u64 icm_size) + { +- u64 aux_pages; ++ u64 aux_pages = 0; + int err; + + err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages); +diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h +index dee8c97ff0568..d967d55324596 100644 +--- a/drivers/infiniband/ulp/iser/iscsi_iser.h ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h +@@ -317,12 +317,10 @@ struct iser_device { + * + * @mr: memory region + * @sig_mr: signature memory region +- * @mr_valid: is mr valid indicator + */ + struct iser_reg_resources { + struct ib_mr *mr; + struct ib_mr *sig_mr; +- u8 mr_valid:1; + }; + + /** +diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c +index 39ea73f690168..f5f090dc4f1eb 100644 +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -581,7 +581,10 @@ static inline int iser_inv_desc(struct iser_fr_desc *desc, u32 rkey) + return -EINVAL; + } + +- desc->rsc.mr_valid = 0; ++ if (desc->sig_protected) ++ desc->rsc.sig_mr->need_inval = false; ++ else ++ desc->rsc.mr->need_inval = false; + + return 0; + } +diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c +index 29ae2c6a250a3..6efcb79c8efe3 100644 +--- a/drivers/infiniband/ulp/iser/iser_memory.c ++++ b/drivers/infiniband/ulp/iser/iser_memory.c +@@ -264,7 +264,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, + + iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask); + +- if (rsc->mr_valid) ++ if (rsc->sig_mr->need_inval) + iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); + + ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); +@@ -288,7 +288,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, + wr->access = IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_READ | + IB_ACCESS_REMOTE_WRITE; +- rsc->mr_valid = 1; ++ rsc->sig_mr->need_inval = true; + + sig_reg->sge.lkey = mr->lkey; + sig_reg->rkey = mr->rkey; +@@ -313,7 +313,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, + struct ib_reg_wr *wr = &tx_desc->reg_wr; + int n; + +- if (rsc->mr_valid) ++ if (rsc->mr->need_inval) + iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); + + ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); +@@ -336,7 +336,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, + IB_ACCESS_REMOTE_WRITE | + IB_ACCESS_REMOTE_READ; + +- rsc->mr_valid = 1; ++ rsc->mr->need_inval = true; + + reg->sge.lkey = mr->lkey; + reg->rkey = mr->rkey; +diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c +index 95b8eebf7e045..6801b70dc9e0e 100644 +--- a/drivers/infiniband/ulp/iser/iser_verbs.c ++++ b/drivers/infiniband/ulp/iser/iser_verbs.c +@@ -129,7 +129,6 @@ iser_create_fastreg_desc(struct iser_device *device, + goto err_alloc_mr_integrity; + } + } +- desc->rsc.mr_valid = 0; + + return desc; + +diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c +index 786f00f6b7fd8..13ef6284223da 100644 +--- a/drivers/input/keyboard/atkbd.c ++++ b/drivers/input/keyboard/atkbd.c +@@ -791,9 +791,9 @@ static bool atkbd_is_portable_device(void) + * not work. So in this case simply assume a keyboard is connected to avoid + * confusing some laptop keyboards. + * +- * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is +- * ok in translated mode, only atkbd_select_set() checks atkbd->id and in +- * translated mode that is a no-op. ++ * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard ++ * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id ++ * and in translated mode that is a no-op. + */ + static bool atkbd_skip_getid(struct atkbd *atkbd) + { +@@ -811,6 +811,7 @@ static int atkbd_probe(struct atkbd *atkbd) + { + struct ps2dev *ps2dev = &atkbd->ps2dev; + unsigned char param[2]; ++ bool skip_getid; + + /* + * Some systems, where the bit-twiddling when testing the io-lines of the +@@ -832,7 +833,8 @@ static int atkbd_probe(struct atkbd *atkbd) + */ + + param[0] = param[1] = 0xa5; /* initialize with invalid values */ +- if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { ++ skip_getid = atkbd_skip_getid(atkbd); ++ if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { + + /* + * If the get ID command was skipped or failed, we check if we can at least set +@@ -842,7 +844,7 @@ static int atkbd_probe(struct atkbd *atkbd) + param[0] = 0; + if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) + return -1; +- atkbd->id = 0xabba; ++ atkbd->id = skip_getid ? 0xab83 : 0xabba; + return 0; + } + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 7f52ac67495fd..40503376d80cc 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -243,6 +243,7 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain, + + static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = { + { .compatible = "qcom,adreno" }, ++ { .compatible = "qcom,adreno-gmu" }, + { .compatible = "qcom,mdp4" }, + { .compatible = "qcom,mdss" }, + { .compatible = "qcom,sc7180-mdss" }, +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 4b1a88f514c9c..e5d087bd6da15 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #include "dma-iommu.h" + +@@ -1052,6 +1053,8 @@ static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, + return DMA_MAPPING_ERROR; + } + ++ trace_swiotlb_bounced(dev, phys, size); ++ + aligned_size = iova_align(iovad, size); + phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, + iova_mask(iovad), dir, attrs); +diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c +index 35ba090f3b5e2..42cffb0ee5e28 100644 +--- a/drivers/iommu/of_iommu.c ++++ b/drivers/iommu/of_iommu.c +@@ -260,7 +260,14 @@ void of_iommu_get_resv_regions(struct device *dev, struct list_head *list) + phys_addr_t iova; + size_t length; + ++ if (of_dma_is_coherent(dev->of_node)) ++ prot |= IOMMU_CACHE; ++ + maps = of_translate_dma_region(np, maps, &iova, &length); ++ if (length == 0) { ++ dev_warn(dev, "Cannot reserve IOVA region of 0 size\n"); ++ continue; ++ } + type = iommu_resv_region_get_type(dev, &phys, iova, length); + + region = iommu_alloc_resv_region(iova, length, prot, type, +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index b92208eccdea9..3132439f99e03 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -110,6 +110,7 @@ config LEDS_AW200XX + config LEDS_AW2013 + tristate "LED support for Awinic AW2013" + depends on LEDS_CLASS && I2C && OF ++ select REGMAP_I2C + help + This option enables support for the AW2013 3-channel + LED driver. +diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c +index 691a743cc9b0f..5142efea2339d 100644 +--- a/drivers/leds/leds-aw200xx.c ++++ b/drivers/leds/leds-aw200xx.c +@@ -74,6 +74,10 @@ + #define AW200XX_LED2REG(x, columns) \ + ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns)))) + ++/* DIM current configuration register on page 1 */ ++#define AW200XX_REG_DIM_PAGE1(x, columns) \ ++ AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns)) ++ + /* + * DIM current configuration register (page 4). + * The even address for current DIM configuration. +@@ -153,7 +157,8 @@ static ssize_t dim_store(struct device *dev, struct device_attribute *devattr, + + if (dim >= 0) { + ret = regmap_write(chip->regmap, +- AW200XX_REG_DIM(led->num, columns), dim); ++ AW200XX_REG_DIM_PAGE1(led->num, columns), ++ dim); + if (ret) + goto out_unlock; + } +diff --git a/drivers/md/md.c b/drivers/md/md.c +index b2ef6af8376a5..8c40c1c3959c9 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -494,6 +494,9 @@ static void md_end_flush(struct bio *bio) + rdev_dec_pending(rdev, mddev); + + if (atomic_dec_and_test(&mddev->flush_pending)) { ++ /* The pair is percpu_ref_get() from md_flush_request() */ ++ percpu_ref_put(&mddev->active_io); ++ + /* The pre-request flush has finished */ + queue_work(md_wq, &mddev->flush_work); + } +@@ -513,12 +516,8 @@ static void submit_flushes(struct work_struct *ws) + rdev_for_each_rcu(rdev, mddev) + if (rdev->raid_disk >= 0 && + !test_bit(Faulty, &rdev->flags)) { +- /* Take two references, one is dropped +- * when request finishes, one after +- * we reclaim rcu_read_lock +- */ + struct bio *bi; +- atomic_inc(&rdev->nr_pending); ++ + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + bi = bio_alloc_bioset(rdev->bdev, 0, +@@ -529,7 +528,6 @@ static void submit_flushes(struct work_struct *ws) + atomic_inc(&mddev->flush_pending); + submit_bio(bi); + rcu_read_lock(); +- rdev_dec_pending(rdev, mddev); + } + rcu_read_unlock(); + if (atomic_dec_and_test(&mddev->flush_pending)) +@@ -582,6 +580,18 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio) + /* new request after previous flush is completed */ + if (ktime_after(req_start, mddev->prev_flush_start)) { + WARN_ON(mddev->flush_bio); ++ /* ++ * Grab a reference to make sure mddev_suspend() will wait for ++ * this flush to be done. ++ * ++ * md_flush_reqeust() is called under md_handle_request() and ++ * 'active_io' is already grabbed, hence percpu_ref_is_zero() ++ * won't pass, percpu_ref_tryget_live() can't be used because ++ * percpu_ref_kill() can be called by mddev_suspend() ++ * concurrently. ++ */ ++ WARN_ON(percpu_ref_is_zero(&mddev->active_io)); ++ percpu_ref_get(&mddev->active_io); + mddev->flush_bio = bio; + bio = NULL; + } +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 2aabac773fe72..911670273d1b6 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -1983,12 +1983,12 @@ static void end_sync_write(struct bio *bio) + } + + static int r1_sync_page_io(struct md_rdev *rdev, sector_t sector, +- int sectors, struct page *page, int rw) ++ int sectors, struct page *page, blk_opf_t rw) + { + if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) + /* success */ + return 1; +- if (rw == WRITE) { ++ if (rw == REQ_OP_WRITE) { + set_bit(WriteErrorSeen, &rdev->flags); + if (!test_and_set_bit(WantReplacement, + &rdev->flags)) +@@ -2105,7 +2105,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) + rdev = conf->mirrors[d].rdev; + if (r1_sync_page_io(rdev, sect, s, + pages[idx], +- WRITE) == 0) { ++ REQ_OP_WRITE) == 0) { + r1_bio->bios[d]->bi_end_io = NULL; + rdev_dec_pending(rdev, mddev); + } +@@ -2120,7 +2120,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) + rdev = conf->mirrors[d].rdev; + if (r1_sync_page_io(rdev, sect, s, + pages[idx], +- READ) != 0) ++ REQ_OP_READ) != 0) + atomic_add(s, &rdev->corrected_errors); + } + sectors -= s; +@@ -2332,7 +2332,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + r1_sync_page_io(rdev, sect, s, +- conf->tmppage, WRITE); ++ conf->tmppage, REQ_OP_WRITE); + rdev_dec_pending(rdev, mddev); + } else + rcu_read_unlock(); +@@ -2349,7 +2349,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + if (r1_sync_page_io(rdev, sect, s, +- conf->tmppage, READ)) { ++ conf->tmppage, REQ_OP_READ)) { + atomic_add(s, &rdev->corrected_errors); + pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %pg)\n", + mdname(mddev), s, +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 4bbd2a247dc71..68d86dbecb4ac 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -36,6 +36,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -6842,7 +6843,18 @@ static void raid5d(struct md_thread *thread) + spin_unlock_irq(&conf->device_lock); + md_check_recovery(mddev); + spin_lock_irq(&conf->device_lock); ++ ++ /* ++ * Waiting on MD_SB_CHANGE_PENDING below may deadlock ++ * seeing md_check_recovery() is needed to clear ++ * the flag when using mdmon. ++ */ ++ continue; + } ++ ++ wait_event_lock_irq(mddev->sb_wait, ++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), ++ conf->device_lock); + } + pr_debug("%d stripes handled\n", handled); + +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 305bb21d843c8..49f0eb7d0b9d3 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -104,6 +104,8 @@ static int dvb_device_open(struct inode *inode, struct file *file) + err = file->f_op->open(inode, file); + up_read(&minor_rwsem); + mutex_unlock(&dvbdev_mutex); ++ if (err) ++ dvb_device_put(dvbdev); + return err; + } + fail: +diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c +index cf037b61b226b..affaa36d31477 100644 +--- a/drivers/media/dvb-frontends/m88ds3103.c ++++ b/drivers/media/dvb-frontends/m88ds3103.c +@@ -1894,7 +1894,7 @@ static int m88ds3103_probe(struct i2c_client *client) + /* get frontend address */ + ret = regmap_read(dev->regmap, 0x29, &utmp); + if (ret) +- goto err_kfree; ++ goto err_del_adapters; + dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1; + dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr); + +@@ -1902,11 +1902,14 @@ static int m88ds3103_probe(struct i2c_client *client) + dev->dt_addr); + if (IS_ERR(dev->dt_client)) { + ret = PTR_ERR(dev->dt_client); +- goto err_kfree; ++ goto err_del_adapters; + } + } + + return 0; ++ ++err_del_adapters: ++ i2c_mux_del_adapters(dev->muxc); + err_kfree: + kfree(dev); + err: +diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c +index 09a193bb87df3..49a3dd70ec0f7 100644 +--- a/drivers/media/pci/bt8xx/bttv-driver.c ++++ b/drivers/media/pci/bt8xx/bttv-driver.c +@@ -1536,13 +1536,11 @@ static void buf_cleanup(struct vb2_buffer *vb) + + static int start_streaming(struct vb2_queue *q, unsigned int count) + { +- int ret = 1; + int seqnr = 0; + struct bttv_buffer *buf; + struct bttv *btv = vb2_get_drv_priv(q); + +- ret = check_alloc_btres_lock(btv, RESOURCE_VIDEO_STREAM); +- if (ret == 0) { ++ if (!check_alloc_btres_lock(btv, RESOURCE_VIDEO_STREAM)) { + if (btv->field_count) + seqnr++; + while (!list_empty(&btv->capture)) { +@@ -1553,7 +1551,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) + vb2_buffer_done(&buf->vbuf.vb2_buf, + VB2_BUF_STATE_QUEUED); + } +- return !ret; ++ return -EBUSY; + } + if (!vb2_is_streaming(&btv->vbiq)) { + init_irqreg(btv); +@@ -2774,6 +2772,27 @@ bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup, + return; + wakeup->vbuf.vb2_buf.timestamp = ktime_get_ns(); + wakeup->vbuf.sequence = btv->field_count >> 1; ++ ++ /* ++ * Ugly hack for backwards compatibility. ++ * Some applications expect that the last 4 bytes of ++ * the VBI data contains the sequence number. ++ * ++ * This makes it possible to associate the VBI data ++ * with the video frame if you use read() to get the ++ * VBI data. ++ */ ++ if (vb2_fileio_is_active(wakeup->vbuf.vb2_buf.vb2_queue)) { ++ u32 *vaddr = vb2_plane_vaddr(&wakeup->vbuf.vb2_buf, 0); ++ unsigned long size = ++ vb2_get_plane_payload(&wakeup->vbuf.vb2_buf, 0) / 4; ++ ++ if (vaddr && size) { ++ vaddr += size - 1; ++ *vaddr = wakeup->vbuf.sequence; ++ } ++ } ++ + vb2_buffer_done(&wakeup->vbuf.vb2_buf, state); + if (btv->field_count == 0) + btor(BT848_INT_VSYNC, BT848_INT_MASK); +diff --git a/drivers/media/pci/bt8xx/bttv-vbi.c b/drivers/media/pci/bt8xx/bttv-vbi.c +index ab213e51ec95f..e489a3acb4b98 100644 +--- a/drivers/media/pci/bt8xx/bttv-vbi.c ++++ b/drivers/media/pci/bt8xx/bttv-vbi.c +@@ -123,14 +123,12 @@ static void buf_cleanup_vbi(struct vb2_buffer *vb) + + static int start_streaming_vbi(struct vb2_queue *q, unsigned int count) + { +- int ret; + int seqnr = 0; + struct bttv_buffer *buf; + struct bttv *btv = vb2_get_drv_priv(q); + + btv->framedrop = 0; +- ret = check_alloc_btres_lock(btv, RESOURCE_VBI); +- if (ret == 0) { ++ if (!check_alloc_btres_lock(btv, RESOURCE_VBI)) { + if (btv->field_count) + seqnr++; + while (!list_empty(&btv->vcapture)) { +@@ -141,13 +139,13 @@ static int start_streaming_vbi(struct vb2_queue *q, unsigned int count) + vb2_buffer_done(&buf->vbuf.vb2_buf, + VB2_BUF_STATE_QUEUED); + } +- return !ret; ++ return -EBUSY; + } + if (!vb2_is_streaming(&btv->capq)) { + init_irqreg(btv); + btv->field_count = 0; + } +- return !ret; ++ return 0; + } + + static void stop_streaming_vbi(struct vb2_queue *q) +diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c +index 1af6fc9460d4d..3a2030d02e45e 100644 +--- a/drivers/media/platform/amphion/vpu_core.c ++++ b/drivers/media/platform/amphion/vpu_core.c +@@ -642,7 +642,7 @@ static int vpu_core_probe(struct platform_device *pdev) + return -ENODEV; + + core->type = core->res->type; +- core->id = of_alias_get_id(dev->of_node, "vpu_core"); ++ core->id = of_alias_get_id(dev->of_node, "vpu-core"); + if (core->id < 0) { + dev_err(dev, "can't get vpu core id\n"); + return core->id; +diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +index 7194f88edc0fb..60425c99a2b8b 100644 +--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c ++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +@@ -1403,7 +1403,6 @@ static void mtk_jpeg_remove(struct platform_device *pdev) + { + struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); + +- cancel_delayed_work_sync(&jpeg->job_timeout_work); + pm_runtime_disable(&pdev->dev); + video_unregister_device(jpeg->vdev); + v4l2_m2m_release(jpeg->m2m_dev); +diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c +index 5f93712bf4854..142ac7b73e14a 100644 +--- a/drivers/media/platform/nxp/imx-mipi-csis.c ++++ b/drivers/media/platform/nxp/imx-mipi-csis.c +@@ -1437,24 +1437,18 @@ static int mipi_csis_probe(struct platform_device *pdev) + /* Reset PHY and enable the clocks. */ + mipi_csis_phy_reset(csis); + +- ret = mipi_csis_clk_enable(csis); +- if (ret < 0) { +- dev_err(csis->dev, "failed to enable clocks: %d\n", ret); +- return ret; +- } +- + /* Now that the hardware is initialized, request the interrupt. */ + ret = devm_request_irq(dev, irq, mipi_csis_irq_handler, 0, + dev_name(dev), csis); + if (ret) { + dev_err(dev, "Interrupt request failed\n"); +- goto err_disable_clock; ++ return ret; + } + + /* Initialize and register the subdev. */ + ret = mipi_csis_subdev_init(csis); + if (ret < 0) +- goto err_disable_clock; ++ return ret; + + platform_set_drvdata(pdev, &csis->sd); + +@@ -1488,8 +1482,6 @@ err_cleanup: + v4l2_async_nf_unregister(&csis->notifier); + v4l2_async_nf_cleanup(&csis->notifier); + v4l2_async_unregister_subdev(&csis->sd); +-err_disable_clock: +- mipi_csis_clk_disable(csis); + + return ret; + } +@@ -1504,9 +1496,10 @@ static void mipi_csis_remove(struct platform_device *pdev) + v4l2_async_nf_cleanup(&csis->notifier); + v4l2_async_unregister_subdev(&csis->sd); + ++ if (!pm_runtime_enabled(&pdev->dev)) ++ mipi_csis_runtime_suspend(&pdev->dev); ++ + pm_runtime_disable(&pdev->dev); +- mipi_csis_runtime_suspend(&pdev->dev); +- mipi_csis_clk_disable(csis); + v4l2_subdev_cleanup(&csis->sd); + media_entity_cleanup(&csis->sd.entity); + pm_runtime_set_suspended(&pdev->dev); +diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +index c41abd2833f12..894d5afaff4e1 100644 +--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c ++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +@@ -582,7 +582,7 @@ static int rkisp1_probe(struct platform_device *pdev) + + ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev); + if (ret) +- goto err_pm_runtime_disable; ++ goto err_media_dev_cleanup; + + ret = media_device_register(&rkisp1->media_dev); + if (ret) { +@@ -617,6 +617,8 @@ err_unreg_media_dev: + media_device_unregister(&rkisp1->media_dev); + err_unreg_v4l2_dev: + v4l2_device_unregister(&rkisp1->v4l2_dev); ++err_media_dev_cleanup: ++ media_device_cleanup(&rkisp1->media_dev); + err_pm_runtime_disable: + pm_runtime_disable(&pdev->dev); + return ret; +@@ -637,6 +639,8 @@ static void rkisp1_remove(struct platform_device *pdev) + media_device_unregister(&rkisp1->media_dev); + v4l2_device_unregister(&rkisp1->v4l2_dev); + ++ media_device_cleanup(&rkisp1->media_dev); ++ + pm_runtime_disable(&pdev->dev); + } + +diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c +index 50ec24c753e9e..1874c976081f8 100644 +--- a/drivers/media/platform/verisilicon/hantro_drv.c ++++ b/drivers/media/platform/verisilicon/hantro_drv.c +@@ -904,6 +904,8 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) + + if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { + vpu->encoder = func; ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); + } else { + vpu->decoder = func; + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); +diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c +index b3ae037a50f61..db145519fc5d3 100644 +--- a/drivers/media/platform/verisilicon/hantro_v4l2.c ++++ b/drivers/media/platform/verisilicon/hantro_v4l2.c +@@ -785,6 +785,9 @@ const struct v4l2_ioctl_ops hantro_ioctl_ops = { + .vidioc_g_selection = vidioc_g_selection, + .vidioc_s_selection = vidioc_s_selection, + ++ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, ++ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, ++ + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, + .vidioc_encoder_cmd = vidioc_encoder_cmd, + }; +diff --git a/drivers/media/test-drivers/visl/visl-video.c b/drivers/media/test-drivers/visl/visl-video.c +index 7cac6a6456eb6..9303a3e118d77 100644 +--- a/drivers/media/test-drivers/visl/visl-video.c ++++ b/drivers/media/test-drivers/visl/visl-video.c +@@ -525,6 +525,9 @@ const struct v4l2_ioctl_ops visl_ioctl_ops = { + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + ++ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, ++ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, ++ + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + }; +diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c +index 727e6268567f7..f1feccc28bf05 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-core.c ++++ b/drivers/media/usb/cx231xx/cx231xx-core.c +@@ -1024,6 +1024,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, + if (!dev->video_mode.isoc_ctl.urb) { + dev_err(dev->dev, + "cannot alloc memory for usb buffers\n"); ++ kfree(dma_q->p_left_data); + return -ENOMEM; + } + +@@ -1033,6 +1034,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, + dev_err(dev->dev, + "cannot allocate memory for usbtransfer\n"); + kfree(dev->video_mode.isoc_ctl.urb); ++ kfree(dma_q->p_left_data); + return -ENOMEM; + } + +diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c +index 14170a5d72b35..1764674de98bc 100644 +--- a/drivers/media/usb/pvrusb2/pvrusb2-context.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c +@@ -268,7 +268,8 @@ void pvr2_context_disconnect(struct pvr2_context *mp) + { + pvr2_hdw_disconnect(mp->hdw); + mp->disconnect_flag = !0; +- pvr2_context_notify(mp); ++ if (!pvr2_context_shutok()) ++ pvr2_context_notify(mp); + } + + +diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c +index 091e8cf4114ba..8cfd593d293d1 100644 +--- a/drivers/media/v4l2-core/v4l2-async.c ++++ b/drivers/media/v4l2-core/v4l2-async.c +@@ -880,7 +880,6 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) + &asc->notifier->waiting_list); + + v4l2_async_unbind_subdev_one(asc->notifier, asc); +- list_del(&asc->asc_subdev_entry); + } + } + +diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c +index 7392b3d2e6b96..4be4df9dd8cf1 100644 +--- a/drivers/mfd/cs42l43-sdw.c ++++ b/drivers/mfd/cs42l43-sdw.c +@@ -17,13 +17,12 @@ + + #include "cs42l43.h" + +-enum cs42l43_sdw_ports { +- CS42L43_DMIC_DEC_ASP_PORT = 1, +- CS42L43_SPK_TX_PORT, +- CS42L43_SPDIF_HP_PORT, +- CS42L43_SPK_RX_PORT, +- CS42L43_ASP_PORT, +-}; ++#define CS42L43_SDW_PORT(port, chans) { \ ++ .num = port, \ ++ .max_ch = chans, \ ++ .type = SDW_DPN_FULL, \ ++ .max_word = 24, \ ++} + + static const struct regmap_config cs42l43_sdw_regmap = { + .reg_bits = 32, +@@ -42,65 +41,48 @@ static const struct regmap_config cs42l43_sdw_regmap = { + .num_reg_defaults = ARRAY_SIZE(cs42l43_reg_default), + }; + ++static const struct sdw_dpn_prop cs42l43_src_port_props[] = { ++ CS42L43_SDW_PORT(1, 4), ++ CS42L43_SDW_PORT(2, 2), ++ CS42L43_SDW_PORT(3, 2), ++ CS42L43_SDW_PORT(4, 2), ++}; ++ ++static const struct sdw_dpn_prop cs42l43_sink_port_props[] = { ++ CS42L43_SDW_PORT(5, 2), ++ CS42L43_SDW_PORT(6, 2), ++ CS42L43_SDW_PORT(7, 2), ++}; ++ + static int cs42l43_read_prop(struct sdw_slave *sdw) + { + struct sdw_slave_prop *prop = &sdw->prop; + struct device *dev = &sdw->dev; +- struct sdw_dpn_prop *dpn; +- unsigned long addr; +- int nval; + int i; +- u32 bit; + + prop->use_domain_irq = true; + prop->paging_support = true; + prop->wake_capable = true; +- prop->source_ports = BIT(CS42L43_DMIC_DEC_ASP_PORT) | BIT(CS42L43_SPK_TX_PORT); +- prop->sink_ports = BIT(CS42L43_SPDIF_HP_PORT) | +- BIT(CS42L43_SPK_RX_PORT) | BIT(CS42L43_ASP_PORT); + prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY | + SDW_SCP_INT1_IMPL_DEF; + +- nval = hweight32(prop->source_ports); +- prop->src_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->src_dpn_prop), +- GFP_KERNEL); ++ for (i = 0; i < ARRAY_SIZE(cs42l43_src_port_props); i++) ++ prop->source_ports |= BIT(cs42l43_src_port_props[i].num); ++ ++ prop->src_dpn_prop = devm_kmemdup(dev, cs42l43_src_port_props, ++ sizeof(cs42l43_src_port_props), GFP_KERNEL); + if (!prop->src_dpn_prop) + return -ENOMEM; + +- i = 0; +- dpn = prop->src_dpn_prop; +- addr = prop->source_ports; +- for_each_set_bit(bit, &addr, 32) { +- dpn[i].num = bit; +- dpn[i].max_ch = 2; +- dpn[i].type = SDW_DPN_FULL; +- dpn[i].max_word = 24; +- i++; +- } +- /* +- * All ports are 2 channels max, except the first one, +- * CS42L43_DMIC_DEC_ASP_PORT. +- */ +- dpn[CS42L43_DMIC_DEC_ASP_PORT].max_ch = 4; ++ for (i = 0; i < ARRAY_SIZE(cs42l43_sink_port_props); i++) ++ prop->sink_ports |= BIT(cs42l43_sink_port_props[i].num); + +- nval = hweight32(prop->sink_ports); +- prop->sink_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->sink_dpn_prop), +- GFP_KERNEL); ++ prop->sink_dpn_prop = devm_kmemdup(dev, cs42l43_sink_port_props, ++ sizeof(cs42l43_sink_port_props), GFP_KERNEL); + if (!prop->sink_dpn_prop) + return -ENOMEM; + +- i = 0; +- dpn = prop->sink_dpn_prop; +- addr = prop->sink_ports; +- for_each_set_bit(bit, &addr, 32) { +- dpn[i].num = bit; +- dpn[i].max_ch = 2; +- dpn[i].type = SDW_DPN_FULL; +- dpn[i].max_word = 24; +- i++; +- } +- + return 0; + } + +diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c +index 9591b354072ad..00e7b578bb3e8 100644 +--- a/drivers/mfd/intel-lpss.c ++++ b/drivers/mfd/intel-lpss.c +@@ -301,8 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss, + + snprintf(name, sizeof(name), "%s-div", devname); + tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp), ++ 0, lpss->priv, 1, 15, 16, 15, + CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, +- lpss->priv, 1, 15, 16, 15, 0, + NULL); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); +diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c +index 11a831e92da83..a577f950c6324 100644 +--- a/drivers/mfd/rk8xx-core.c ++++ b/drivers/mfd/rk8xx-core.c +@@ -53,76 +53,68 @@ static const struct resource rk817_charger_resources[] = { + }; + + static const struct mfd_cell rk805s[] = { +- { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, +- { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, +- { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_NONE, }, ++ { .name = "rk808-clkout", }, ++ { .name = "rk808-regulator", }, ++ { .name = "rk805-pinctrl", }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = &rtc_resources[0], +- .id = PLATFORM_DEVID_NONE, + }, + { .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk805_key_resources), + .resources = &rk805_key_resources[0], +- .id = PLATFORM_DEVID_NONE, + }, + }; + + static const struct mfd_cell rk806s[] = { +- { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, }, +- { .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, }, ++ { .name = "rk805-pinctrl", }, ++ { .name = "rk808-regulator", }, + { + .name = "rk805-pwrkey", + .resources = rk806_pwrkey_resources, + .num_resources = ARRAY_SIZE(rk806_pwrkey_resources), +- .id = PLATFORM_DEVID_AUTO, + }, + }; + + static const struct mfd_cell rk808s[] = { +- { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, +- { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, ++ { .name = "rk808-clkout", }, ++ { .name = "rk808-regulator", }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = rtc_resources, +- .id = PLATFORM_DEVID_NONE, + }, + }; + + static const struct mfd_cell rk817s[] = { +- { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, +- { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, ++ { .name = "rk808-clkout", }, ++ { .name = "rk808-regulator", }, + { + .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk817_pwrkey_resources), + .resources = &rk817_pwrkey_resources[0], +- .id = PLATFORM_DEVID_NONE, + }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rk817_rtc_resources), + .resources = &rk817_rtc_resources[0], +- .id = PLATFORM_DEVID_NONE, + }, +- { .name = "rk817-codec", .id = PLATFORM_DEVID_NONE, }, ++ { .name = "rk817-codec", }, + { + .name = "rk817-charger", + .num_resources = ARRAY_SIZE(rk817_charger_resources), + .resources = &rk817_charger_resources[0], +- .id = PLATFORM_DEVID_NONE, + }, + }; + + static const struct mfd_cell rk818s[] = { +- { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, +- { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, ++ { .name = "rk808-clkout", }, ++ { .name = "rk808-regulator", }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = rtc_resources, +- .id = PLATFORM_DEVID_NONE, + }, + }; + +@@ -680,7 +672,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap + pre_init_reg[i].addr); + } + +- ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0, ++ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0, + regmap_irq_get_domain(rk808->irq_data)); + if (ret) + return dev_err_probe(dev, ret, "failed to add MFD devices\n"); +diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c +index 57b29c3251312..c9550368d9ea5 100644 +--- a/drivers/mfd/syscon.c ++++ b/drivers/mfd/syscon.c +@@ -105,6 +105,10 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res) + } + + syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start); ++ if (!syscon_config.name) { ++ ret = -ENOMEM; ++ goto err_regmap; ++ } + syscon_config.reg_stride = reg_io_width; + syscon_config.val_bits = reg_io_width * 8; + syscon_config.max_register = resource_size(&res) - reg_io_width; +diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c +index 0fb9c5cf213a4..783ee59901e86 100644 +--- a/drivers/mfd/tps6594-core.c ++++ b/drivers/mfd/tps6594-core.c +@@ -433,6 +433,9 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc) + tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x", + dev->driver->name, tps->chip_id, tps->reg); + ++ if (!tps6594_irq_chip.name) ++ return -ENOMEM; ++ + ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT, + 0, &tps6594_irq_chip, &tps->irq_data); + if (ret) +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 554e67103c1a1..bc7e2ad370021 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -1018,14 +1018,15 @@ config MMC_SDHCI_XENON + + config MMC_SDHCI_OMAP + tristate "TI SDHCI Controller Support" ++ depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST + depends on MMC_SDHCI_PLTFM && OF + select THERMAL + imply TI_SOC_THERMAL + select MMC_SDHCI_EXTERNAL_DMA if DMA_ENGINE + help + This selects the Secure Digital Host Controller Interface (SDHCI) +- support present in TI's DRA7 SOCs. The controller supports +- SD/MMC/SDIO devices. ++ support present in TI's Keystone/OMAP2+/DRA7 SOCs. The controller ++ supports SD/MMC/SDIO devices. + + If you have a controller with this interface, say Y or M here. + +@@ -1033,14 +1034,15 @@ config MMC_SDHCI_OMAP + + config MMC_SDHCI_AM654 + tristate "Support for the SDHCI Controller in TI's AM654 SOCs" ++ depends on ARCH_K3 || COMPILE_TEST + depends on MMC_SDHCI_PLTFM && OF + select MMC_SDHCI_IO_ACCESSORS + select MMC_CQHCI + select REGMAP_MMIO + help + This selects the Secure Digital Host Controller Interface (SDHCI) +- support present in TI's AM654 SOCs. The controller supports +- SD/MMC/SDIO devices. ++ support present in TI's AM65x/AM64x/AM62x/J721E SOCs. The controller ++ supports SD/MMC/SDIO devices. + + If you have a controller with this interface, say Y or M here. + +diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c +index ff18636e08897..5bc32108ca03b 100644 +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -463,7 +463,7 @@ static void blktrans_notify_add(struct mtd_info *mtd) + { + struct mtd_blktrans_ops *tr; + +- if (mtd->type == MTD_ABSENT) ++ if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) + return; + + list_for_each_entry(tr, &blktrans_majors, list) +@@ -503,7 +503,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) + mutex_lock(&mtd_table_mutex); + list_add(&tr->list, &blktrans_majors); + mtd_for_each_device(mtd) +- if (mtd->type != MTD_ABSENT) ++ if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) + tr->add_mtd(tr, mtd); + mutex_unlock(&mtd_table_mutex); + return 0; +diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c +index 20bb1e0cb5ebf..f0e2318ce088c 100644 +--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c ++++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c +@@ -21,7 +21,7 @@ + + #define ERR_BYTE 0xFF /* Value returned for read + bytes when read failed */ +-#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait ++#define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait + for IFC NAND Machine */ + + struct fsl_ifc_ctrl; +diff --git a/drivers/net/amt.c b/drivers/net/amt.c +index 2d20be6ffb7e5..ddd087c2c3ed4 100644 +--- a/drivers/net/amt.c ++++ b/drivers/net/amt.c +@@ -11,7 +11,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -80,11 +80,11 @@ static struct mld2_grec mldv2_zero_grec; + + static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb) + { +- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct qdisc_skb_cb) > ++ BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) > + sizeof_field(struct sk_buff, cb)); + + return (struct amt_skb_cb *)((void *)skb->cb + +- sizeof(struct qdisc_skb_cb)); ++ sizeof(struct tc_skb_cb)); + } + + static void __amt_source_gc_work(void) +diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c +index 4f09e7438f3b9..c99fb1bd4c25a 100644 +--- a/drivers/net/dsa/vitesse-vsc73xx-core.c ++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c +@@ -1118,6 +1118,8 @@ static int vsc73xx_gpio_probe(struct vsc73xx *vsc) + + vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x", + vsc->chipid); ++ if (!vsc->gc.label) ++ return -ENOMEM; + vsc->gc.ngpio = 4; + vsc->gc.owner = THIS_MODULE; + vsc->gc.parent = vsc->dev; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c +index 4728ba34b0e34..76218f1cb4595 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c +@@ -506,6 +506,7 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id) + rpm_t *rpm = rpmd; + u8 num_lmacs; + u32 fifo_len; ++ u16 max_lmac; + + lmac_info = rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS); + /* LMACs are divided into two groups and each group +@@ -513,7 +514,11 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id) + * Group0 lmac_id range {0..3} + * Group1 lmac_id range {4..7} + */ +- fifo_len = rpm->mac_ops->fifo_len / 2; ++ max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF; ++ if (max_lmac > 4) ++ fifo_len = rpm->mac_ops->fifo_len / 2; ++ else ++ fifo_len = rpm->mac_ops->fifo_len; + + if (lmac_id < 4) { + num_lmacs = hweight8(lmac_info & 0xF); +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +index 694de9513b9fc..aaf1faed4133e 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +@@ -130,9 +130,15 @@ static int mlxbf_gige_open(struct net_device *netdev) + { + struct mlxbf_gige *priv = netdev_priv(netdev); + struct phy_device *phydev = netdev->phydev; ++ u64 control; + u64 int_en; + int err; + ++ /* Perform general init of GigE block */ ++ control = readq(priv->base + MLXBF_GIGE_CONTROL); ++ control |= MLXBF_GIGE_CONTROL_PORT_EN; ++ writeq(control, priv->base + MLXBF_GIGE_CONTROL); ++ + err = mlxbf_gige_request_irqs(priv); + if (err) + return err; +@@ -147,14 +153,14 @@ static int mlxbf_gige_open(struct net_device *netdev) + */ + priv->valid_polarity = 0; + +- err = mlxbf_gige_rx_init(priv); ++ phy_start(phydev); ++ ++ err = mlxbf_gige_tx_init(priv); + if (err) + goto free_irqs; +- err = mlxbf_gige_tx_init(priv); ++ err = mlxbf_gige_rx_init(priv); + if (err) +- goto rx_deinit; +- +- phy_start(phydev); ++ goto tx_deinit; + + netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll); + napi_enable(&priv->napi); +@@ -176,8 +182,8 @@ static int mlxbf_gige_open(struct net_device *netdev) + + return 0; + +-rx_deinit: +- mlxbf_gige_rx_deinit(priv); ++tx_deinit: ++ mlxbf_gige_tx_deinit(priv); + + free_irqs: + mlxbf_gige_free_irqs(priv); +@@ -365,7 +371,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + void __iomem *plu_base; + void __iomem *base; + int addr, phy_irq; +- u64 control; + int err; + + base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC); +@@ -380,11 +385,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) + if (IS_ERR(plu_base)) + return PTR_ERR(plu_base); + +- /* Perform general init of GigE block */ +- control = readq(base + MLXBF_GIGE_CONTROL); +- control |= MLXBF_GIGE_CONTROL_PORT_EN; +- writeq(control, base + MLXBF_GIGE_CONTROL); +- + netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv)); + if (!netdev) + return -ENOMEM; +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 227d01cace3f0..6999843584934 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +@@ -142,6 +142,9 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) + writeq(MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS_EN, + priv->base + MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS); + ++ writeq(ilog2(priv->rx_q_entries), ++ priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); ++ + /* Clear MLXBF_GIGE_INT_MASK 'receive pkt' bit to + * indicate readiness to receive interrupts + */ +@@ -154,9 +157,6 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) + data |= MLXBF_GIGE_RX_DMA_EN; + writeq(data, priv->base + MLXBF_GIGE_RX_DMA); + +- writeq(ilog2(priv->rx_q_entries), +- priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); +- + return 0; + + free_wqe_and_skb: +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +index 4c98950380d53..d231f4d2888be 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, + unsigned long *p_index) + { + unsigned int num_rows, entry_size; ++ unsigned long index; + + /* We only allow allocations of entire rows */ + if (num_erps % erp_core->num_erp_banks != 0) +@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, + entry_size = erp_core->erpt_entries_size[region_type]; + num_rows = num_erps / erp_core->num_erp_banks; + +- *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); +- if (*p_index == 0) ++ index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); ++ if (!index) + return -ENOBUFS; +- *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; ++ ++ *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; + + return 0; + } +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +index d50786b0a6ce4..50ea1eff02b2f 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +@@ -681,13 +681,13 @@ static void + mlxsw_sp_acl_tcam_region_destroy(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_tcam_region *region) + { ++ struct mlxsw_sp_acl_tcam *tcam = mlxsw_sp_acl_to_tcam(mlxsw_sp->acl); + const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops; + + ops->region_fini(mlxsw_sp, region->priv); + mlxsw_sp_acl_tcam_region_disable(mlxsw_sp, region); + mlxsw_sp_acl_tcam_region_free(mlxsw_sp, region); +- mlxsw_sp_acl_tcam_region_id_put(region->group->tcam, +- region->id); ++ mlxsw_sp_acl_tcam_region_id_put(tcam, region->id); + kfree(region); + } + +@@ -1564,6 +1564,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, + tcam->max_groups = max_groups; + tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, + ACL_MAX_GROUP_SIZE); ++ tcam->max_group_size = min_t(unsigned int, tcam->max_group_size, ++ MLXSW_REG_PAGT_ACL_MAX_NUM); + + err = ops->init(mlxsw_sp, tcam->priv, tcam); + if (err) +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +index debd2c466f11c..ae2fb9efbc509 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +@@ -11458,6 +11458,13 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, + if (err) + goto err_register_netevent_notifier; + ++ mlxsw_sp->router->netdevice_nb.notifier_call = ++ mlxsw_sp_router_netdevice_event; ++ err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), ++ &mlxsw_sp->router->netdevice_nb); ++ if (err) ++ goto err_register_netdev_notifier; ++ + mlxsw_sp->router->nexthop_nb.notifier_call = + mlxsw_sp_nexthop_obj_event; + err = register_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), +@@ -11473,22 +11480,15 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, + if (err) + goto err_register_fib_notifier; + +- mlxsw_sp->router->netdevice_nb.notifier_call = +- mlxsw_sp_router_netdevice_event; +- err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), +- &mlxsw_sp->router->netdevice_nb); +- if (err) +- goto err_register_netdev_notifier; +- + return 0; + +-err_register_netdev_notifier: +- unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), +- &mlxsw_sp->router->fib_nb); + err_register_fib_notifier: + unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), + &mlxsw_sp->router->nexthop_nb); + err_register_nexthop_notifier: ++ unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), ++ &router->netdevice_nb); ++err_register_netdev_notifier: + unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); + err_register_netevent_notifier: + unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); +@@ -11536,11 +11536,11 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) + { + struct mlxsw_sp_router *router = mlxsw_sp->router; + +- unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), +- &router->netdevice_nb); + unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb); + unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), + &router->nexthop_nb); ++ unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), ++ &router->netdevice_nb); + unregister_netevent_notifier(&router->netevent_nb); + unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); + unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb); +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +index 39d24e07f3067..5b69b9268c757 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -396,7 +396,7 @@ nla_put_failure: + + struct rtnl_link_ops rmnet_link_ops __read_mostly = { + .kind = "rmnet", +- .maxtype = __IFLA_RMNET_MAX, ++ .maxtype = IFLA_RMNET_MAX, + .priv_size = sizeof(struct rmnet_priv), + .setup = rmnet_vnd_setup, + .validate = rmnet_rtnl_validate, +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index 3c2a6b23c202a..8fec0dbbbe7bb 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1949,7 +1949,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) + struct ravb_tstamp_skb *ts_skb; + struct ravb_tx_desc *desc; + unsigned long flags; +- u32 dma_addr; ++ dma_addr_t dma_addr; + void *buffer; + u32 entry; + u32 len; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +index cd7a9768de5f1..b8c93b881a653 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +@@ -255,6 +255,7 @@ struct stmmac_priv { + u32 msg_enable; + int wolopts; + int wol_irq; ++ bool wol_irq_disabled; + int clk_csr; + struct timer_list eee_ctrl_timer; + int lpi_irq; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 6aa5c0556d220..69c8c25285243 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -311,8 +311,9 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (priv->hw->pcs & STMMAC_PCS_RGMII || +- priv->hw->pcs & STMMAC_PCS_SGMII) { ++ if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) && ++ (priv->hw->pcs & STMMAC_PCS_RGMII || ++ priv->hw->pcs & STMMAC_PCS_SGMII)) { + struct rgmii_adv adv; + u32 supported, advertising, lp_advertising; + +@@ -397,8 +398,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, + { + struct stmmac_priv *priv = netdev_priv(dev); + +- if (priv->hw->pcs & STMMAC_PCS_RGMII || +- priv->hw->pcs & STMMAC_PCS_SGMII) { ++ if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) && ++ (priv->hw->pcs & STMMAC_PCS_RGMII || ++ priv->hw->pcs & STMMAC_PCS_SGMII)) { + /* Only support ANE */ + if (cmd->base.autoneg != AUTONEG_ENABLE) + return -EINVAL; +@@ -543,15 +545,12 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) + u32 rx_cnt = priv->plat->rx_queues_to_use; + unsigned int start; + int q, stat; +- u64 *pos; + char *p; + +- pos = data; + for (q = 0; q < tx_cnt; q++) { + struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; + struct stmmac_txq_stats snapshot; + +- data = pos; + do { + start = u64_stats_fetch_begin(&txq_stats->syncp); + snapshot = *txq_stats; +@@ -559,17 +558,15 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) + + p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); + for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { +- *data++ += (*(u64 *)p); ++ *data++ = (*(u64 *)p); + p += sizeof(u64); + } + } + +- pos = data; + for (q = 0; q < rx_cnt; q++) { + struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; + struct stmmac_rxq_stats snapshot; + +- data = pos; + do { + start = u64_stats_fetch_begin(&rxq_stats->syncp); + snapshot = *rxq_stats; +@@ -577,7 +574,7 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) + + p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); + for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { +- *data++ += (*(u64 *)p); ++ *data++ = (*(u64 *)p); + p += sizeof(u64); + } + } +@@ -825,10 +822,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) + if (wol->wolopts) { + pr_info("stmmac: wakeup enable\n"); + device_set_wakeup_enable(priv->device, 1); +- enable_irq_wake(priv->wol_irq); ++ /* Avoid unbalanced enable_irq_wake calls */ ++ if (priv->wol_irq_disabled) ++ enable_irq_wake(priv->wol_irq); ++ priv->wol_irq_disabled = false; + } else { + device_set_wakeup_enable(priv->device, 0); +- disable_irq_wake(priv->wol_irq); ++ /* Avoid unbalanced disable_irq_wake calls */ ++ if (!priv->wol_irq_disabled) ++ disable_irq_wake(priv->wol_irq); ++ priv->wol_irq_disabled = true; + } + + mutex_lock(&priv->lock); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 69b9c71f0eded..1bfcf673b3ce7 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3549,6 +3549,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) + /* Request the Wake IRQ in case of another line + * is used for WoL + */ ++ priv->wol_irq_disabled = true; + if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) { + int_name = priv->int_name_wol; + sprintf(int_name, "%s:%s", dev->name, "wol"); +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index 24120605502f9..c62b0f99f2bc4 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -56,7 +56,7 @@ + #define AM65_CPSW_MAX_PORTS 8 + + #define AM65_CPSW_MIN_PACKET_SIZE VLAN_ETH_ZLEN +-#define AM65_CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) ++#define AM65_CPSW_MAX_PACKET_SIZE 2024 + + #define AM65_CPSW_REG_CTL 0x004 + #define AM65_CPSW_REG_STAT_PORT_EN 0x014 +@@ -2167,7 +2167,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) + eth_hw_addr_set(port->ndev, port->slave.mac_addr); + + port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; +- port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; ++ port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE - ++ (VLAN_ETH_HLEN + ETH_FCS_LEN); + port->ndev->hw_features = NETIF_F_SG | + NETIF_F_RXCSUM | + NETIF_F_HW_CSUM | +diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c +index 2eac92f49631f..d8ca82addfe1b 100644 +--- a/drivers/net/netdevsim/netdev.c ++++ b/drivers/net/netdevsim/netdev.c +@@ -369,6 +369,12 @@ static int nsim_init_netdevsim_vf(struct netdevsim *ns) + return err; + } + ++static void nsim_exit_netdevsim(struct netdevsim *ns) ++{ ++ nsim_udp_tunnels_info_destroy(ns->netdev); ++ mock_phc_destroy(ns->phc); ++} ++ + struct netdevsim * + nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port) + { +@@ -417,8 +423,7 @@ void nsim_destroy(struct netdevsim *ns) + } + rtnl_unlock(); + if (nsim_dev_port_is_pf(ns->nsim_dev_port)) +- nsim_udp_tunnels_info_destroy(dev); +- mock_phc_destroy(ns->phc); ++ nsim_exit_netdevsim(ns); + free_netdev(dev); + } + +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 927d3d54658ef..dfd5f8e78e291 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -3313,8 +3313,10 @@ static int lan8814_probe(struct phy_device *phydev) + #define LAN8841_ADC_CHANNEL_MASK 198 + #define LAN8841_PTP_RX_PARSE_L2_ADDR_EN 370 + #define LAN8841_PTP_RX_PARSE_IP_ADDR_EN 371 ++#define LAN8841_PTP_RX_VERSION 374 + #define LAN8841_PTP_TX_PARSE_L2_ADDR_EN 434 + #define LAN8841_PTP_TX_PARSE_IP_ADDR_EN 435 ++#define LAN8841_PTP_TX_VERSION 438 + #define LAN8841_PTP_CMD_CTL 256 + #define LAN8841_PTP_CMD_CTL_PTP_ENABLE BIT(2) + #define LAN8841_PTP_CMD_CTL_PTP_DISABLE BIT(1) +@@ -3358,6 +3360,12 @@ static int lan8841_config_init(struct phy_device *phydev) + phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, + LAN8841_PTP_RX_PARSE_IP_ADDR_EN, 0); + ++ /* Disable checking for minorVersionPTP field */ ++ phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, ++ LAN8841_PTP_RX_VERSION, 0xff00); ++ phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, ++ LAN8841_PTP_TX_VERSION, 0xff00); ++ + /* 100BT Clause 40 improvenent errata */ + phy_write_mmd(phydev, LAN8841_MMD_ANALOG_REG, + LAN8841_ANALOG_CONTROL_1, +@@ -4820,6 +4828,7 @@ static struct phy_driver ksphy_driver[] = { + .flags = PHY_POLL_CABLE_TEST, + .driver_data = &ksz9131_type, + .probe = kszphy_probe, ++ .soft_reset = genphy_soft_reset, + .config_init = ksz9131_config_init, + .config_intr = kszphy_config_intr, + .config_aneg = ksz9131_config_aneg, +diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c +index 1215ebdf173a8..ef11c138bf307 100644 +--- a/drivers/net/wireless/ath/ath11k/ahb.c ++++ b/drivers/net/wireless/ath/ath11k/ahb.c +@@ -802,8 +802,8 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab) + + prproc = rproc_get_by_phandle(rproc_phandle); + if (!prproc) { +- ath11k_err(ab, "failed to get rproc\n"); +- return -EINVAL; ++ ath11k_dbg(ab, ATH11K_DBG_AHB, "failed to get rproc, deferring\n"); ++ return -EPROBE_DEFER; + } + ab_ahb->tgt_rproc = prproc; + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +index 31176897b7463..e3120ab893f4e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +@@ -1012,7 +1012,8 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, + IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK | + IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | + IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | +- IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK); ++ IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK | ++ IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK); + iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] &= + ~(IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO | + IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +index cf27f106d4d56..7057421e513ba 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +@@ -1673,7 +1673,7 @@ static ssize_t _iwl_dbgfs_link_sta_##name##_write(struct file *file, \ + char buf[buflen] = {}; \ + size_t buf_size = min(count, sizeof(buf) - 1); \ + \ +- if (copy_from_user(buf, user_buf, sizeof(buf))) \ ++ if (copy_from_user(buf, user_buf, buf_size)) \ + return -EFAULT; \ + \ + return _iwl_dbgfs_link_sta_wrap_write(iwl_dbgfs_##name##_write, \ +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +index 2ddb6f763a0b3..1e58f02342934 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +@@ -269,17 +269,17 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, + } + } + ++ mvmvif->link[link_id]->phy_ctxt = phy_ctxt; ++ + if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { + mvmvif->link[link_id]->listen_lmac = true; + ret = iwl_mvm_esr_mode_active(mvm, vif); + if (ret) { + IWL_ERR(mvm, "failed to activate ESR mode (%d)\n", ret); +- return ret; ++ goto out; + } + } + +- mvmvif->link[link_id]->phy_ctxt = phy_ctxt; +- + if (switching_chanctx) { + /* reactivate if we turned this off during channel switch */ + if (vif->type == NL80211_IFTYPE_AP) +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +index a5b432bc9e2f8..9c582e23ebbaf 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +@@ -99,17 +99,6 @@ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm, + active_cnt = 2; + } + +- /* +- * If the firmware requested it, then we know that it supports +- * getting zero for the values to indicate "use one, but pick +- * which one yourself", which means it can dynamically pick one +- * that e.g. has better RSSI. +- */ +- if (mvm->fw_static_smps_request && active_cnt == 1 && idle_cnt == 1) { +- idle_cnt = 0; +- active_cnt = 0; +- } +- + *rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << + PHY_RX_CHAIN_VALID_POS); + *rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 177a4628a913e..6fdb2c38518e3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -2236,7 +2236,7 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids) + WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); + + if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TXPATH_FLUSH, 0) > 0) +- cmd.flags |= CMD_WANT_SKB; ++ cmd.flags |= CMD_WANT_SKB | CMD_SEND_IN_RFKILL; + + IWL_DEBUG_TX_QUEUES(mvm, "flush for sta id %d tid mask 0x%x\n", + sta_id, tids); +diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig +index 6d62ab49aa8d4..c7d02adb3eead 100644 +--- a/drivers/net/wireless/marvell/libertas/Kconfig ++++ b/drivers/net/wireless/marvell/libertas/Kconfig +@@ -2,8 +2,6 @@ + config LIBERTAS + tristate "Marvell 8xxx Libertas WLAN driver support" + depends on CFG80211 +- select WIRELESS_EXT +- select WEXT_SPY + select LIB80211 + select FW_LOADER + help +diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +index ba4e29713a8c9..4389cf3f889f9 100644 +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -2046,6 +2046,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, + + mwifiex_set_sys_config_invalid_data(bss_cfg); + ++ memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN); ++ + if (params->beacon_interval) + bss_cfg->beacon_period = params->beacon_interval; + if (params->dtim_period) +diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h +index 8e6db904e5b2d..62f3c9a52a1d5 100644 +--- a/drivers/net/wireless/marvell/mwifiex/fw.h ++++ b/drivers/net/wireless/marvell/mwifiex/fw.h +@@ -165,6 +165,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { + #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) + #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) + #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) ++#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43) + #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) + #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) + #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) +diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h +index 091e7ca793762..e8825f302de8a 100644 +--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h ++++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h +@@ -107,6 +107,7 @@ struct mwifiex_uap_bss_param { + u8 qos_info; + u8 power_constraint; + struct mwifiex_types_wmm_info wmm_info; ++ u8 mac_addr[ETH_ALEN]; + }; + + enum { +diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c +index 774858cfe86f2..e66ba0d156f85 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sdio.c ++++ b/drivers/net/wireless/marvell/mwifiex/sdio.c +@@ -331,6 +331,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { + .can_dump_fw = false, + .can_auto_tdls = false, + .can_ext_scan = false, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { +@@ -346,6 +347,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { + .can_dump_fw = false, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { +@@ -361,6 +363,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { + .can_dump_fw = false, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { +@@ -376,6 +379,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { + .can_dump_fw = true, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { +@@ -392,6 +396,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { + .fw_dump_enh = true, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { +@@ -408,6 +413,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { + .fw_dump_enh = true, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = true, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { +@@ -425,6 +431,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { + .fw_dump_enh = true, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { +@@ -440,6 +447,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { + .can_dump_fw = false, + .can_auto_tdls = true, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { +@@ -456,6 +464,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { + .fw_dump_enh = true, + .can_auto_tdls = true, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { +@@ -471,6 +480,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { + .can_dump_fw = false, + .can_auto_tdls = false, + .can_ext_scan = true, ++ .fw_ready_extra_delay = false, + }; + + static struct memory_type_mapping generic_mem_type_map[] = { +@@ -563,6 +573,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) + card->fw_dump_enh = data->fw_dump_enh; + card->can_auto_tdls = data->can_auto_tdls; + card->can_ext_scan = data->can_ext_scan; ++ card->fw_ready_extra_delay = data->fw_ready_extra_delay; + INIT_WORK(&card->work, mwifiex_sdio_work); + } + +@@ -766,8 +777,9 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) + static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, + u32 poll_num) + { ++ struct sdio_mmc_card *card = adapter->card; + int ret = 0; +- u16 firmware_stat; ++ u16 firmware_stat = 0; + u32 tries; + + for (tries = 0; tries < poll_num; tries++) { +@@ -783,6 +795,13 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, + ret = -1; + } + ++ if (card->fw_ready_extra_delay && ++ firmware_stat == FIRMWARE_READY_SDIO) ++ /* firmware might pretend to be ready, when it's not. ++ * Wait a little bit more as a workaround. ++ */ ++ msleep(100); ++ + return ret; + } + +diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h +index ae94c172310ff..a5112cb35cdcd 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sdio.h ++++ b/drivers/net/wireless/marvell/mwifiex/sdio.h +@@ -258,6 +258,7 @@ struct sdio_mmc_card { + bool fw_dump_enh; + bool can_auto_tdls; + bool can_ext_scan; ++ bool fw_ready_extra_delay; + + struct mwifiex_sdio_mpa_tx mpa_tx; + struct mwifiex_sdio_mpa_rx mpa_rx; +@@ -281,6 +282,7 @@ struct mwifiex_sdio_device { + bool fw_dump_enh; + bool can_auto_tdls; + bool can_ext_scan; ++ bool fw_ready_extra_delay; + }; + + /* +diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +index e78a201cd1507..491e366119096 100644 +--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c ++++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +@@ -468,6 +468,7 @@ void mwifiex_config_uap_11d(struct mwifiex_private *priv, + static int + mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) + { ++ struct host_cmd_tlv_mac_addr *mac_tlv; + struct host_cmd_tlv_dtim_period *dtim_period; + struct host_cmd_tlv_beacon_period *beacon_period; + struct host_cmd_tlv_ssid *ssid; +@@ -487,6 +488,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) + int i; + u16 cmd_size = *param_size; + ++ mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv; ++ mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS); ++ mac_tlv->header.len = cpu_to_le16(ETH_ALEN); ++ memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN); ++ cmd_size += sizeof(struct host_cmd_tlv_mac_addr); ++ tlv += sizeof(struct host_cmd_tlv_mac_addr); ++ + if (bss_cfg->ssid.ssid_len) { + ssid = (struct host_cmd_tlv_ssid *)tlv; + ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID); +diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c +index 36564930aef12..1de3c734e136a 100644 +--- a/drivers/net/wireless/mediatek/mt76/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c +@@ -67,7 +67,7 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs + goto out_put_node; + } + +- offset = be32_to_cpup(list); ++ offset += be32_to_cpup(list); + ret = mtd_read(mtd, offset, len, &retlen, eep); + put_mtd_device(mtd); + if (mtd_is_bitflip(ret)) +@@ -106,7 +106,7 @@ out_put_node: + #endif + } + +-static int mt76_get_of_epprom_from_nvmem(struct mt76_dev *dev, void *eep, int len) ++static int mt76_get_of_eeprom_from_nvmem(struct mt76_dev *dev, void *eep, int len) + { + struct device_node *np = dev->dev->of_node; + struct nvmem_cell *cell; +@@ -153,7 +153,7 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) + if (!ret) + return 0; + +- return mt76_get_of_epprom_from_nvmem(dev, eep, len); ++ return mt76_get_of_eeprom_from_nvmem(dev, eep, len); + } + EXPORT_SYMBOL_GPL(mt76_get_of_eeprom); + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index dae5410d67e83..7f44736ca26f0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -572,8 +572,7 @@ struct mt76_sdio { + struct mt76_worker txrx_worker; + struct mt76_worker status_worker; + struct mt76_worker net_worker; +- +- struct work_struct stat_work; ++ struct mt76_worker stat_worker; + + u8 *xmit_buf; + u32 xmit_buf_sz; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +index fc547a0031eae..67cedd2555f97 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +@@ -204,8 +204,8 @@ static int mt7663s_suspend(struct device *dev) + mt76_worker_disable(&mdev->mt76.sdio.txrx_worker); + mt76_worker_disable(&mdev->mt76.sdio.status_worker); + mt76_worker_disable(&mdev->mt76.sdio.net_worker); ++ mt76_worker_disable(&mdev->mt76.sdio.stat_worker); + +- cancel_work_sync(&mdev->mt76.sdio.stat_work); + clear_bit(MT76_READING_STATS, &mdev->mphy.state); + + mt76_tx_status_check(&mdev->mt76, true); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h +index f3e56817d36e9..adc26a222823b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h +@@ -144,7 +144,8 @@ static inline bool + mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band) + { + u8 *eep = dev->mt76.eeprom.data; +- u8 val = eep[MT_EE_WIFI_CONF + 7]; ++ u8 offs = is_mt7981(&dev->mt76) ? 8 : 7; ++ u8 val = eep[MT_EE_WIFI_CONF + offs]; + + if (band == NL80211_BAND_2GHZ) + return val & MT_EE_WIFI_CONF7_TSSI0_2G; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +index d85105a43d704..3196f56cdf4ab 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +@@ -1047,8 +1047,9 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) + + phy->mt76->antenna_mask = tx_ant; + +- /* handle a variant of mt7916 which has 3T3R but nss2 on 5 GHz band */ +- if (is_mt7916(&dev->mt76) && band && hweight8(tx_ant) == max_nss) ++ /* handle a variant of mt7916/mt7981 which has 3T3R but nss2 on 5 GHz band */ ++ if ((is_mt7916(&dev->mt76) || is_mt7981(&dev->mt76)) && ++ band && hweight8(tx_ant) == max_nss) + phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift; + else + phy->mt76->chainmask = tx_ant << (chainshift * band); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +index fc7ace638ce8e..f4ad7219f94f4 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +@@ -742,7 +742,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, + + res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); + if (!res) +- return -ENOMEM; ++ return 0; + + wed->wlan.platform_dev = plat_dev; + wed->wlan.bus_type = MTK_WED_BUS_AXI; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 90c93970acabc..d1b1b8f767fc8 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -1136,22 +1136,27 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, + u8 type[2]; + u8 rsvd[64]; + } __packed req = { ++ .ver = 1, + .idx = idx, + .env = env_cap, + .acpi_conf = mt792x_acpi_get_flags(&dev->phy), + }; + int ret, valid_cnt = 0; +- u8 i, *pos; ++ u16 buf_len = 0; ++ u8 *pos; + + if (!clc) + return 0; + ++ buf_len = le16_to_cpu(clc->len) - sizeof(*clc); + pos = clc->data; +- for (i = 0; i < clc->nr_country; i++) { ++ while (buf_len > 16) { + struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos; + u16 len = le16_to_cpu(rule->len); ++ u16 offset = len + sizeof(*rule); + +- pos += len + sizeof(*rule); ++ pos += offset; ++ buf_len -= offset; + if (rule->alpha2[0] != alpha2[0] || + rule->alpha2[1] != alpha2[1]) + continue; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +index dc1beb76df3e1..7591e54d28973 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +@@ -228,7 +228,7 @@ static int mt7921s_suspend(struct device *__dev) + mt76_txq_schedule_all(&dev->mphy); + mt76_worker_disable(&mdev->tx_worker); + mt76_worker_disable(&mdev->sdio.status_worker); +- cancel_work_sync(&mdev->sdio.stat_work); ++ mt76_worker_disable(&mdev->sdio.stat_worker); + clear_bit(MT76_READING_STATS, &dev->mphy.state); + mt76_tx_status_check(mdev, true); + +@@ -260,6 +260,7 @@ restore_txrx_worker: + restore_worker: + mt76_worker_enable(&mdev->tx_worker); + mt76_worker_enable(&mdev->sdio.status_worker); ++ mt76_worker_enable(&mdev->sdio.stat_worker); + + if (!pm->ds_enable) + mt76_connac_mcu_set_deep_sleep(mdev, false); +@@ -292,6 +293,7 @@ static int mt7921s_resume(struct device *__dev) + mt76_worker_enable(&mdev->sdio.txrx_worker); + mt76_worker_enable(&mdev->sdio.status_worker); + mt76_worker_enable(&mdev->sdio.net_worker); ++ mt76_worker_enable(&mdev->sdio.stat_worker); + + /* restore previous ds setting */ + if (!pm->ds_enable) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +index 8edd0291c1280..389eb0903807e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +@@ -107,7 +107,7 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) + mt76_worker_disable(&dev->mt76.sdio.txrx_worker); + mt76_worker_disable(&dev->mt76.sdio.status_worker); + mt76_worker_disable(&dev->mt76.sdio.net_worker); +- cancel_work_sync(&dev->mt76.sdio.stat_work); ++ mt76_worker_disable(&dev->mt76.sdio.stat_worker); + + mt7921s_disable_irq(&dev->mt76); + mt7921s_wfsys_reset(dev); +@@ -115,6 +115,7 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) + mt76_worker_enable(&dev->mt76.sdio.txrx_worker); + mt76_worker_enable(&dev->mt76.sdio.status_worker); + mt76_worker_enable(&dev->mt76.sdio.net_worker); ++ mt76_worker_enable(&dev->mt76.sdio.stat_worker); + + dev->fw_assert = false; + clear_bit(MT76_MCU_RESET, &dev->mphy.state); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index c43839a205088..26d5675202ba9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -840,10 +840,10 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, + struct mt76_vif *mvif; + u16 tx_count = 15; + u32 val; +- bool beacon = !!(changed & (BSS_CHANGED_BEACON | +- BSS_CHANGED_BEACON_ENABLED)); + bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | + BSS_CHANGED_FILS_DISCOVERY)); ++ bool beacon = !!(changed & (BSS_CHANGED_BEACON | ++ BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc); + + mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL; + if (mvif) { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +index e4b31228ba0d2..dc8d0a30c707c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +@@ -221,7 +221,7 @@ struct bss_rate_tlv { + u8 short_preamble; + u8 bc_fixed_rate; + u8 mc_fixed_rate; +- u8 __rsv2[1]; ++ u8 __rsv2[9]; + } __packed; + + struct bss_ra_tlv { +diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c +index 419723118ded8..c52d550f0c32a 100644 +--- a/drivers/net/wireless/mediatek/mt76/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/sdio.c +@@ -481,21 +481,21 @@ static void mt76s_status_worker(struct mt76_worker *w) + if (dev->drv->tx_status_data && ndata_frames > 0 && + !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) && + !test_bit(MT76_STATE_SUSPEND, &dev->phy.state)) +- ieee80211_queue_work(dev->hw, &dev->sdio.stat_work); ++ mt76_worker_schedule(&sdio->stat_worker); + } while (nframes > 0); + + if (resched) + mt76_worker_schedule(&dev->tx_worker); + } + +-static void mt76s_tx_status_data(struct work_struct *work) ++static void mt76s_tx_status_data(struct mt76_worker *worker) + { + struct mt76_sdio *sdio; + struct mt76_dev *dev; + u8 update = 1; + u16 count = 0; + +- sdio = container_of(work, struct mt76_sdio, stat_work); ++ sdio = container_of(worker, struct mt76_sdio, stat_worker); + dev = container_of(sdio, struct mt76_dev, sdio); + + while (true) { +@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work) + } + + if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state)) +- ieee80211_queue_work(dev->hw, &sdio->stat_work); ++ mt76_worker_schedule(&sdio->status_worker); + else + clear_bit(MT76_READING_STATS, &dev->phy.state); + } +@@ -600,8 +600,8 @@ void mt76s_deinit(struct mt76_dev *dev) + mt76_worker_teardown(&sdio->txrx_worker); + mt76_worker_teardown(&sdio->status_worker); + mt76_worker_teardown(&sdio->net_worker); ++ mt76_worker_teardown(&sdio->stat_worker); + +- cancel_work_sync(&sdio->stat_work); + clear_bit(MT76_READING_STATS, &dev->phy.state); + + mt76_tx_status_check(dev, true); +@@ -644,10 +644,14 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, + if (err) + return err; + ++ err = mt76_worker_setup(dev->hw, &sdio->stat_worker, mt76s_tx_status_data, ++ "sdio-sta"); ++ if (err) ++ return err; ++ + sched_set_fifo_low(sdio->status_worker.task); + sched_set_fifo_low(sdio->net_worker.task); +- +- INIT_WORK(&sdio->stat_work, mt76s_tx_status_data); ++ sched_set_fifo_low(sdio->stat_worker.task); + + dev->queue_ops = &sdio_queue_ops; + dev->bus = bus_ops; +diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c +index 76d0a778636a4..311676c1ece0a 100644 +--- a/drivers/net/wireless/purelifi/plfxlc/usb.c ++++ b/drivers/net/wireless/purelifi/plfxlc/usb.c +@@ -493,9 +493,12 @@ int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, + void *context) + { + struct usb_device *udev = interface_to_usbdev(usb->ez_usb); +- struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); ++ struct urb *urb; + int r; + ++ urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!urb) ++ return -ENOMEM; + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), + (void *)buffer, buffer_len, complete_fn, context); + +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c +index 9886e719739be..b118df035243c 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.c ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c +@@ -164,21 +164,29 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + ++ value &= PCI_EXP_LNKCTL_ASPMC; ++ + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) +- value |= 0x40; ++ value |= PCI_EXP_LNKCTL_CCC; + +- pci_write_config_byte(rtlpci->pdev, 0x80, value); ++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, ++ PCI_EXP_LNKCTL_ASPMC | value, ++ value); + + return false; + } + +-/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ +-static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) ++/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ ++static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) + { + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +- pci_write_config_byte(rtlpci->pdev, 0x81, value); ++ value &= PCI_EXP_LNKCTL_CLKREQ_EN; ++ ++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, ++ PCI_EXP_LNKCTL_CLKREQ_EN, ++ value); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) + udelay(100); +@@ -192,11 +200,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; +- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + /*Retrieve original configuration settings. */ + u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; +- u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. +- pcibridge_linkctrlreg; + u16 aspmlevel = 0; + u8 tmp_u1b = 0; + +@@ -221,16 +226,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) + /*Set corresponding value. */ + aspmlevel |= BIT(0) | BIT(1); + linkctrl_reg &= ~aspmlevel; +- pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); + + _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); +- udelay(50); +- +- /*4 Disable Pci Bridge ASPM */ +- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), +- pcibridge_linkctrlreg); +- +- udelay(50); + } + + /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for +@@ -245,9 +242,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; +- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; + u16 aspmlevel; +- u8 u_pcibridge_aspmsetting; + u8 u_device_aspmsetting; + + if (!ppsc->support_aspm) +@@ -259,25 +254,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + return; + } + +- /*4 Enable Pci Bridge ASPM */ +- +- u_pcibridge_aspmsetting = +- pcipriv->ndis_adapter.pcibridge_linkctrlreg | +- rtlpci->const_hostpci_aspm_setting; +- +- if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) +- u_pcibridge_aspmsetting &= ~BIT(0); +- +- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), +- u_pcibridge_aspmsetting); +- +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "PlatformEnableASPM(): Write reg[%x] = %x\n", +- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), +- u_pcibridge_aspmsetting); +- +- udelay(50); +- + /*Get ASPM level (with/without Clock Req) */ + aspmlevel = rtlpci->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; +@@ -291,7 +267,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & +- RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); ++ RT_RF_OFF_LEVL_CLK_REQ) ? ++ PCI_EXP_LNKCTL_CLKREQ_EN : 0); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); + } + udelay(100); +@@ -358,22 +335,6 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, + return tpriv != NULL; + } + +-static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) +-{ +- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); +- u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; +- u8 linkctrl_reg; +- u8 num4bbytes; +- +- num4bbytes = (capabilityoffset + 0x10) / 4; +- +- /*Read Link Control Register */ +- pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg); +- +- pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; +-} +- + static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) + { +@@ -2028,12 +1989,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + PCI_SLOT(bridge_pdev->devfn); + pcipriv->ndis_adapter.pcibridge_funcnum = + PCI_FUNC(bridge_pdev->devfn); +- pcipriv->ndis_adapter.pcibridge_pciehdr_offset = +- pci_pcie_cap(bridge_pdev); +- pcipriv->ndis_adapter.num4bytes = +- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; +- +- rtl_pci_get_linkcontrol_field(hw); + + if (pcipriv->ndis_adapter.pcibridge_vendor == + PCI_BRIDGE_VENDOR_AMD) { +@@ -2050,13 +2005,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, +- "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", ++ "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], +- pcipriv->ndis_adapter.pcibridge_pciehdr_offset, +- pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); + + rtl_pci_parse_configuration(pdev, hw); +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h +index 866861626a0a1..d6307197dfea0 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.h ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.h +@@ -236,11 +236,6 @@ struct mp_adapter { + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + +- u8 num4bytes; +- +- u8 pcibridge_pciehdr_offset; +- u8 pcibridge_linkctrlreg; +- + bool amd_l1_patch; + }; + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +index 12d0b3a87af7c..0fab3a0c7d49d 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +@@ -16,12 +16,6 @@ static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, + static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +-static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} + static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); + static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +@@ -51,7 +45,7 @@ u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -74,7 +68,7 @@ void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -99,7 +93,7 @@ u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + + + original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -127,7 +121,7 @@ void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl88e_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +index 3d29c8dbb2559..144ee780e1b6a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +@@ -17,7 +17,7 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -40,7 +40,7 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -143,14 +143,6 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + } + EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); + +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +-EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); +- + static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) + { + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +index 75afa6253ad02..e64d377dfe9e2 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +@@ -196,7 +196,6 @@ bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); + void rtl92c_phy_set_io(struct ieee80211_hw *hw); + void rtl92c_bb_block_on(struct ieee80211_hw *hw); +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); + long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +index da54e51badd3a..fa70a7d5539fd 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +@@ -39,7 +39,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + rfpath, regaddr); + } + +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -110,7 +110,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +@@ -122,7 +122,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +index 7582a162bd112..c7a0d4c776f0a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +@@ -94,7 +94,6 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 offset); + u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +-u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); + void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, u32 data); + void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +index a8d9fe269f313..0b8cb7e61fd80 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +@@ -32,7 +32,7 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", +@@ -56,7 +56,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +@@ -67,7 +67,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); +- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +index d18c092b61426..d835a27429f0f 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +@@ -169,13 +169,6 @@ static const u8 channel_all[59] = { + 157, 159, 161, 163, 165 + }; + +-static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); +@@ -198,7 +191,7 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + } else { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + } +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", +@@ -230,7 +223,7 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + dbi_direct); + else + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) +@@ -317,7 +310,7 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + regaddr, rfpath, bitmask); + spin_lock(&rtlpriv->locks.rf_lock); + original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + spin_unlock(&rtlpriv->locks.rf_lock); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -343,7 +336,7 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92d_phy_rf_serial_read(hw, + rfpath, regaddr); +- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | + (data << bitshift)); + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +index cc0bcaf13e96e..73ef602bfb01a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +@@ -16,7 +16,6 @@ static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, + static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +-static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask); + static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); + static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, +@@ -46,7 +45,7 @@ u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, +@@ -68,7 +67,7 @@ void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -92,7 +91,7 @@ u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, + spin_lock(&rtlpriv->locks.rf_lock); + + original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -119,7 +118,7 @@ void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, + + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); +- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = (original_value & (~bitmask)) | (data << bitshift); + } + +@@ -201,13 +200,6 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, + pphyreg->rf3wire_offset, data_and_addr); + } + +-static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) + { + return _rtl92ee_phy_config_mac_with_headerfile(hw); +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +index 09591a0b5a818..d9ef7e1da1db4 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +@@ -14,13 +14,6 @@ + #include "hw.h" + #include "table.h" + +-static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) +-{ +- u32 i = ffs(bitmask); +- +- return i ? i - 1 : 32; +-} +- + u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + { + struct rtl_priv *rtlpriv = rtl_priv(hw); +@@ -30,7 +23,7 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) + regaddr, bitmask); + + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", +@@ -52,7 +45,7 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + +@@ -157,7 +150,7 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); + +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + + spin_unlock(&rtlpriv->locks.rf_lock); +@@ -188,7 +181,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, + regaddr); +- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); ++ bitshift = calculate_bit_shift(bitmask); + data = ((original_value & (~bitmask)) | (data << bitshift)); + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +index 5323ead30db03..fa1839d8ee55f 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +@@ -29,9 +29,10 @@ static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, + u32 data); + static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) + { +- u32 i = ffs(bitmask); ++ if (WARN_ON_ONCE(!bitmask)) ++ return 0; + +- return i ? i - 1 : 32; ++ return __ffs(bitmask); + } + static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); + /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 2e7e04f912793..8cbf3fb388539 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -3080,4 +3080,11 @@ static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, + return ieee80211_find_sta(mac->vif, mac_addr); + } + ++static inline u32 calculate_bit_shift(u32 bitmask) ++{ ++ if (WARN_ON_ONCE(!bitmask)) ++ return 0; ++ ++ return __ffs(bitmask); ++} + #endif +diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c +index a99b53d442676..d8d68f16014e3 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c +@@ -280,9 +280,9 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw, + + if (changed_flags & FIF_ALLMULTI) { + if (*new_flags & FIF_ALLMULTI) +- rtwdev->hal.rcr |= BIT_AM | BIT_AB; ++ rtwdev->hal.rcr |= BIT_AM; + else +- rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); ++ rtwdev->hal.rcr &= ~(BIT_AM); + } + if (changed_flags & FIF_FCSFAIL) { + if (*new_flags & FIF_FCSFAIL) +diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 2c1fb2dabd40a..0cae5746f540f 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -500,19 +500,40 @@ static u32 rtw_sdio_get_tx_addr(struct rtw_dev *rtwdev, size_t size, + static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count) + { + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; ++ struct mmc_host *host = rtwsdio->sdio_func->card->host; + bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); + u32 rxaddr = rtwsdio->rx_addr++; +- int ret; ++ int ret = 0, err; ++ size_t bytes; + + if (bus_claim) + sdio_claim_host(rtwsdio->sdio_func); + +- ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, +- RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count); +- if (ret) +- rtw_warn(rtwdev, +- "Failed to read %zu byte(s) from SDIO port 0x%08x", +- count, rxaddr); ++ while (count > 0) { ++ bytes = min_t(size_t, host->max_req_size, count); ++ ++ err = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, ++ RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), ++ bytes); ++ if (err) { ++ rtw_warn(rtwdev, ++ "Failed to read %zu byte(s) from SDIO port 0x%08x: %d", ++ bytes, rxaddr, err); ++ ++ /* Signal to the caller that reading did not work and ++ * that the data in the buffer is short/corrupted. ++ */ ++ ret = err; ++ ++ /* Don't stop here - instead drain the remaining data ++ * from the card's buffer, else the card will return ++ * corrupt data for the next rtw_sdio_read_port() call. ++ */ ++ } ++ ++ count -= bytes; ++ buf += bytes; ++ } + + if (bus_claim) + sdio_release_host(rtwsdio->sdio_func); +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index 88f760a7cbc35..d7503aef599f0 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -463,12 +463,25 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + } + + for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; +- shinfo->nr_frags++, gop++, nr_slots--) { ++ nr_slots--) { ++ if (unlikely(!txp->size)) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->response_lock, flags); ++ make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); ++ push_tx_responses(queue); ++ spin_unlock_irqrestore(&queue->response_lock, flags); ++ ++txp; ++ continue; ++ } ++ + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; + xenvif_tx_create_map_op(queue, pending_idx, txp, + txp == first ? extra_count : 0, gop); + frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); ++ ++shinfo->nr_frags; ++ ++gop; + + if (txp == first) + txp = txfrags; +@@ -481,20 +494,39 @@ static void xenvif_get_requests(struct xenvif_queue *queue, + shinfo = skb_shinfo(nskb); + frags = shinfo->frags; + +- for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; +- shinfo->nr_frags++, txp++, gop++) { ++ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { ++ if (unlikely(!txp->size)) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->response_lock, flags); ++ make_tx_response(queue, txp, 0, ++ XEN_NETIF_RSP_OKAY); ++ push_tx_responses(queue); ++ spin_unlock_irqrestore(&queue->response_lock, ++ flags); ++ continue; ++ } ++ + index = pending_index(queue->pending_cons++); + pending_idx = queue->pending_ring[index]; + xenvif_tx_create_map_op(queue, pending_idx, txp, 0, + gop); + frag_set_pending_idx(&frags[shinfo->nr_frags], + pending_idx); ++ ++shinfo->nr_frags; ++ ++gop; + } + +- skb_shinfo(skb)->frag_list = nskb; +- } else if (nskb) { ++ if (shinfo->nr_frags) { ++ skb_shinfo(skb)->frag_list = nskb; ++ nskb = NULL; ++ } ++ } ++ ++ if (nskb) { + /* A frag_list skb was allocated but it is no longer needed +- * because enough slots were converted to copy ops above. ++ * because enough slots were converted to copy ops above or some ++ * were empty. + */ + kfree_skb(nskb); + } +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 197fc2ecb164d..a4f802790ca02 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -19,6 +19,7 @@ + #include "nvmet.h" + + #define NVMET_TCP_DEF_INLINE_DATA_SIZE (4 * PAGE_SIZE) ++#define NVMET_TCP_MAXH2CDATA 0x400000 /* 16M arbitrary limit */ + + static int param_store_val(const char *str, int *val, int min, int max) + { +@@ -900,7 +901,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + icresp->hdr.pdo = 0; + icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen); + icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0); +- icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */ ++ icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA); + icresp->cpda = 0; + if (queue->hdr_digest) + icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE; +@@ -953,6 +954,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) + { + struct nvme_tcp_data_pdu *data = &queue->pdu.data; + struct nvmet_tcp_cmd *cmd; ++ unsigned int exp_data_len; + + if (likely(queue->nr_cmds)) { + if (unlikely(data->ttag >= queue->nr_cmds)) { +@@ -971,12 +973,24 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) + data->ttag, le32_to_cpu(data->data_offset), + cmd->rbytes_done); + /* FIXME: use path and transport errors */ +- nvmet_req_complete(&cmd->req, +- NVME_SC_INVALID_FIELD | NVME_SC_DNR); ++ nvmet_tcp_fatal_error(queue); + return -EPROTO; + } + ++ exp_data_len = le32_to_cpu(data->hdr.plen) - ++ nvmet_tcp_hdgst_len(queue) - ++ nvmet_tcp_ddgst_len(queue) - ++ sizeof(*data); ++ + cmd->pdu_len = le32_to_cpu(data->data_length); ++ if (unlikely(cmd->pdu_len != exp_data_len || ++ cmd->pdu_len == 0 || ++ cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { ++ pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); ++ /* FIXME: use proper transport errors */ ++ nvmet_tcp_fatal_error(queue); ++ return -EPROTO; ++ } + cmd->pdu_recv = 0; + nvmet_tcp_build_pdu_iovec(cmd); + queue->cmd = cmd; +diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h +index 6109b3806b12b..974d99d47f514 100644 +--- a/drivers/nvme/target/trace.h ++++ b/drivers/nvme/target/trace.h +@@ -53,8 +53,7 @@ static inline void __assign_req_name(char *name, struct nvmet_req *req) + return; + } + +- strncpy(name, req->ns->device_path, +- min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path))); ++ strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN); + } + #endif + +@@ -85,7 +84,7 @@ TRACE_EVENT(nvmet_req_init, + __entry->flags = cmd->common.flags; + __entry->nsid = le32_to_cpu(cmd->common.nsid); + __entry->metadata = le64_to_cpu(cmd->common.metadata); +- memcpy(__entry->cdw10, &cmd->common.cdw10, ++ memcpy(__entry->cdw10, &cmd->common.cdws, + sizeof(__entry->cdw10)); + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 8d93cb6ea9cde..b0ad8fc06e80e 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1464,6 +1464,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + out_args->np = new; + of_node_put(cur); + cur = new; ++ new = NULL; + } + put: + of_node_put(cur); +diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi +index d01f92f0f0db7..554a996b2ef18 100644 +--- a/drivers/of/unittest-data/tests-phandle.dtsi ++++ b/drivers/of/unittest-data/tests-phandle.dtsi +@@ -40,6 +40,13 @@ + phandle-map-pass-thru = <0x0 0xf0>; + }; + ++ provider5: provider5 { ++ #phandle-cells = <2>; ++ phandle-map = <2 7 &provider4 2 3>; ++ phandle-map-mask = <0xff 0xf>; ++ phandle-map-pass-thru = <0x0 0xf0>; ++ }; ++ + consumer-a { + phandle-list = <&provider1 1>, + <&provider2 2 0>, +@@ -66,7 +73,8 @@ + <&provider4 4 0x100>, + <&provider4 0 0x61>, + <&provider0>, +- <&provider4 19 0x20>; ++ <&provider4 19 0x20>, ++ <&provider5 2 7>; + phandle-list-bad-phandle = <12345678 0 0>; + phandle-list-bad-args = <&provider2 1 0>, + <&provider4 0>; +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index ad2b7879cc675..f278def7ef038 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -456,6 +456,9 @@ static void __init of_unittest_parse_phandle_with_args(void) + + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); ++ ++ if (rc == 0) ++ of_node_put(args.np); + } + + /* Check for missing list property */ +@@ -545,8 +548,9 @@ static void __init of_unittest_parse_phandle_with_args(void) + + static void __init of_unittest_parse_phandle_with_args_map(void) + { +- struct device_node *np, *p0, *p1, *p2, *p3; ++ struct device_node *np, *p[6] = {}; + struct of_phandle_args args; ++ unsigned int prefs[6]; + int i, rc; + + np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b"); +@@ -555,34 +559,24 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + return; + } + +- p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); +- if (!p0) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); +- if (!p1) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); +- if (!p2) { +- pr_err("missing testcase data\n"); +- return; +- } +- +- p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); +- if (!p3) { +- pr_err("missing testcase data\n"); +- return; ++ p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); ++ p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); ++ p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); ++ p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); ++ p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4"); ++ p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5"); ++ for (i = 0; i < ARRAY_SIZE(p); ++i) { ++ if (!p[i]) { ++ pr_err("missing testcase data\n"); ++ return; ++ } ++ prefs[i] = kref_read(&p[i]->kobj.kref); + } + + rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); +- unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); ++ unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc); + +- for (i = 0; i < 8; i++) { ++ for (i = 0; i < 9; i++) { + bool passed = true; + + memset(&args, 0, sizeof(args)); +@@ -593,13 +587,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + switch (i) { + case 0: + passed &= !rc; +- passed &= (args.np == p1); ++ passed &= (args.np == p[1]); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 1); + break; + case 1: + passed &= !rc; +- passed &= (args.np == p3); ++ passed &= (args.np == p[3]); + passed &= (args.args_count == 3); + passed &= (args.args[0] == 2); + passed &= (args.args[1] == 5); +@@ -610,28 +604,36 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + break; + case 3: + passed &= !rc; +- passed &= (args.np == p0); ++ passed &= (args.np == p[0]); + passed &= (args.args_count == 0); + break; + case 4: + passed &= !rc; +- passed &= (args.np == p1); ++ passed &= (args.np == p[1]); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 3); + break; + case 5: + passed &= !rc; +- passed &= (args.np == p0); ++ passed &= (args.np == p[0]); + passed &= (args.args_count == 0); + break; + case 6: + passed &= !rc; +- passed &= (args.np == p2); ++ passed &= (args.np == p[2]); + passed &= (args.args_count == 2); + passed &= (args.args[0] == 15); + passed &= (args.args[1] == 0x20); + break; + case 7: ++ passed &= !rc; ++ passed &= (args.np == p[3]); ++ passed &= (args.args_count == 3); ++ passed &= (args.args[0] == 2); ++ passed &= (args.args[1] == 5); ++ passed &= (args.args[2] == 3); ++ break; ++ case 8: + passed &= (rc == -ENOENT); + break; + default: +@@ -640,6 +642,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + + unittest(passed, "index %i - data error on node %s rc=%i\n", + i, args.np->full_name, rc); ++ ++ if (rc == 0) ++ of_node_put(args.np); + } + + /* Check for missing list property */ +@@ -686,6 +691,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) + "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); + + unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); ++ ++ for (i = 0; i < ARRAY_SIZE(p); ++i) { ++ unittest(prefs[i] == kref_read(&p[i]->kobj.kref), ++ "provider%d: expected:%d got:%d\n", ++ i, prefs[i], kref_read(&p[i]->kobj.kref)); ++ of_node_put(p[i]); ++ } + } + + static void __init of_unittest_property_string(void) +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 0def919f89faf..cf3836561316d 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1218,7 +1218,16 @@ static int ks_pcie_probe(struct platform_device *pdev) + goto err_link; + } + ++ /* Obtain references to the PHYs */ ++ for (i = 0; i < num_lanes; i++) ++ phy_pm_runtime_get_sync(ks_pcie->phy[i]); ++ + ret = ks_pcie_enable_phy(ks_pcie); ++ ++ /* Release references to the PHYs */ ++ for (i = 0; i < num_lanes; i++) ++ phy_pm_runtime_put_sync(ks_pcie->phy[i]); ++ + if (ret) { + dev_err(dev, "failed to enable phy\n"); + goto err_link; +diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c +index f9182f8d552f4..8d79dd0e1d605 100644 +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -598,6 +598,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, + } + + aligned_offset = msg_addr & (epc->mem->window.page_size - 1); ++ msg_addr &= ~aligned_offset; + ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, + epc->mem->window.page_size); + if (ret) +diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c +index e0e27645fdf4c..975b3024fb08c 100644 +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -245,35 +245,60 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie, + resource_size_t cpu_addr, + resource_size_t pci_addr, + resource_size_t size, +- unsigned long type, int num) ++ unsigned long type, int *num) + { ++ resource_size_t remaining = size; ++ resource_size_t table_size; ++ resource_size_t addr_align; ++ const char *range_type; + void __iomem *table; + u32 val; + +- if (num >= PCIE_MAX_TRANS_TABLES) { +- dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", +- (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); +- return -ENODEV; +- } ++ while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) { ++ /* Table size needs to be a power of 2 */ ++ table_size = BIT(fls(remaining) - 1); ++ ++ if (cpu_addr > 0) { ++ addr_align = BIT(ffs(cpu_addr) - 1); ++ table_size = min(table_size, addr_align); ++ } ++ ++ /* Minimum size of translate table is 4KiB */ ++ if (table_size < 0x1000) { ++ dev_err(pcie->dev, "illegal table size %#llx\n", ++ (unsigned long long)table_size); ++ return -EINVAL; ++ } + +- table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + +- num * PCIE_ATR_TLB_SET_OFFSET; ++ table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET; ++ writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table); ++ writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); ++ writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); ++ writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); + +- writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1), +- table); +- writel_relaxed(upper_32_bits(cpu_addr), +- table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); +- writel_relaxed(lower_32_bits(pci_addr), +- table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); +- writel_relaxed(upper_32_bits(pci_addr), +- table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); ++ if (type == IORESOURCE_IO) { ++ val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; ++ range_type = "IO"; ++ } else { ++ val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; ++ range_type = "MEM"; ++ } + +- if (type == IORESOURCE_IO) +- val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; +- else +- val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; ++ writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); + +- writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); ++ dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", ++ range_type, *num, (unsigned long long)cpu_addr, ++ (unsigned long long)pci_addr, (unsigned long long)table_size); ++ ++ cpu_addr += table_size; ++ pci_addr += table_size; ++ remaining -= table_size; ++ (*num)++; ++ } ++ ++ if (remaining) ++ dev_warn(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", ++ (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); + + return 0; + } +@@ -380,30 +405,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) + resource_size_t cpu_addr; + resource_size_t pci_addr; + resource_size_t size; +- const char *range_type; + +- if (type == IORESOURCE_IO) { ++ if (type == IORESOURCE_IO) + cpu_addr = pci_pio_to_address(res->start); +- range_type = "IO"; +- } else if (type == IORESOURCE_MEM) { ++ else if (type == IORESOURCE_MEM) + cpu_addr = res->start; +- range_type = "MEM"; +- } else { ++ else + continue; +- } + + pci_addr = res->start - entry->offset; + size = resource_size(res); + err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size, +- type, table_index); ++ type, &table_index); + if (err) + return err; +- +- dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", +- range_type, table_index, (unsigned long long)cpu_addr, +- (unsigned long long)pci_addr, (unsigned long long)size); +- +- table_index++; + } + + return 0; +diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c +index 66a8f73296fc8..48372013f26d2 100644 +--- a/drivers/pci/controller/pcie-mediatek.c ++++ b/drivers/pci/controller/pcie-mediatek.c +@@ -617,12 +617,18 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) + if (status & MSI_STATUS){ + unsigned long imsi_status; + ++ /* ++ * The interrupt status can be cleared even if the ++ * MSI status remains pending. As such, given the ++ * edge-triggered interrupt type, its status should ++ * be cleared before being dispatched to the ++ * handler of the underlying device. ++ */ ++ writel(MSI_STATUS, port->base + PCIE_INT_STATUS); + while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { + for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) + generic_handle_domain_irq(port->inner_domain, bit); + } +- /* Clear MSI interrupt status */ +- writel(MSI_STATUS, port->base + PCIE_INT_STATUS); + } + } + +diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c +index b7b9d3e21f97d..6dc918a8a0235 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c ++++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c +@@ -209,28 +209,28 @@ static void pci_epf_mhi_raise_irq(struct mhi_ep_cntrl *mhi_cntrl, u32 vector) + vector + 1); + } + +-static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, +- void *to, size_t size) ++static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl, ++ struct mhi_ep_buf_info *buf_info) + { + struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl); +- size_t offset = get_align_offset(epf_mhi, from); ++ size_t offset = get_align_offset(epf_mhi, buf_info->host_addr); + void __iomem *tre_buf; + phys_addr_t tre_phys; + int ret; + + mutex_lock(&epf_mhi->lock); + +- ret = __pci_epf_mhi_alloc_map(mhi_cntrl, from, &tre_phys, &tre_buf, +- offset, size); ++ ret = __pci_epf_mhi_alloc_map(mhi_cntrl, buf_info->host_addr, &tre_phys, ++ &tre_buf, offset, buf_info->size); + if (ret) { + mutex_unlock(&epf_mhi->lock); + return ret; + } + +- memcpy_fromio(to, tre_buf, size); ++ memcpy_fromio(buf_info->dev_addr, tre_buf, buf_info->size); + +- __pci_epf_mhi_unmap_free(mhi_cntrl, from, tre_phys, tre_buf, offset, +- size); ++ __pci_epf_mhi_unmap_free(mhi_cntrl, buf_info->host_addr, tre_phys, ++ tre_buf, offset, buf_info->size); + + mutex_unlock(&epf_mhi->lock); + +@@ -238,27 +238,27 @@ static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, + } + + static int pci_epf_mhi_iatu_write(struct mhi_ep_cntrl *mhi_cntrl, +- void *from, u64 to, size_t size) ++ struct mhi_ep_buf_info *buf_info) + { + struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl); +- size_t offset = get_align_offset(epf_mhi, to); ++ size_t offset = get_align_offset(epf_mhi, buf_info->host_addr); + void __iomem *tre_buf; + phys_addr_t tre_phys; + int ret; + + mutex_lock(&epf_mhi->lock); + +- ret = __pci_epf_mhi_alloc_map(mhi_cntrl, to, &tre_phys, &tre_buf, +- offset, size); ++ ret = __pci_epf_mhi_alloc_map(mhi_cntrl, buf_info->host_addr, &tre_phys, ++ &tre_buf, offset, buf_info->size); + if (ret) { + mutex_unlock(&epf_mhi->lock); + return ret; + } + +- memcpy_toio(tre_buf, from, size); ++ memcpy_toio(tre_buf, buf_info->dev_addr, buf_info->size); + +- __pci_epf_mhi_unmap_free(mhi_cntrl, to, tre_phys, tre_buf, offset, +- size); ++ __pci_epf_mhi_unmap_free(mhi_cntrl, buf_info->host_addr, tre_phys, ++ tre_buf, offset, buf_info->size); + + mutex_unlock(&epf_mhi->lock); + +@@ -270,8 +270,8 @@ static void pci_epf_mhi_dma_callback(void *param) + complete(param); + } + +-static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, +- void *to, size_t size) ++static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, ++ struct mhi_ep_buf_info *buf_info) + { + struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl); + struct device *dma_dev = epf_mhi->epf->epc->dev.parent; +@@ -284,13 +284,13 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, + dma_addr_t dst_addr; + int ret; + +- if (size < SZ_4K) +- return pci_epf_mhi_iatu_read(mhi_cntrl, from, to, size); ++ if (buf_info->size < SZ_4K) ++ return pci_epf_mhi_iatu_read(mhi_cntrl, buf_info); + + mutex_lock(&epf_mhi->lock); + + config.direction = DMA_DEV_TO_MEM; +- config.src_addr = from; ++ config.src_addr = buf_info->host_addr; + + ret = dmaengine_slave_config(chan, &config); + if (ret) { +@@ -298,14 +298,16 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, + goto err_unlock; + } + +- dst_addr = dma_map_single(dma_dev, to, size, DMA_FROM_DEVICE); ++ dst_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size, ++ DMA_FROM_DEVICE); + ret = dma_mapping_error(dma_dev, dst_addr); + if (ret) { + dev_err(dev, "Failed to map remote memory\n"); + goto err_unlock; + } + +- desc = dmaengine_prep_slave_single(chan, dst_addr, size, DMA_DEV_TO_MEM, ++ desc = dmaengine_prep_slave_single(chan, dst_addr, buf_info->size, ++ DMA_DEV_TO_MEM, + DMA_CTRL_ACK | DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(dev, "Failed to prepare DMA\n"); +@@ -332,15 +334,15 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from, + } + + err_unmap: +- dma_unmap_single(dma_dev, dst_addr, size, DMA_FROM_DEVICE); ++ dma_unmap_single(dma_dev, dst_addr, buf_info->size, DMA_FROM_DEVICE); + err_unlock: + mutex_unlock(&epf_mhi->lock); + + return ret; + } + +-static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from, +- u64 to, size_t size) ++static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, ++ struct mhi_ep_buf_info *buf_info) + { + struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl); + struct device *dma_dev = epf_mhi->epf->epc->dev.parent; +@@ -353,13 +355,13 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from, + dma_addr_t src_addr; + int ret; + +- if (size < SZ_4K) +- return pci_epf_mhi_iatu_write(mhi_cntrl, from, to, size); ++ if (buf_info->size < SZ_4K) ++ return pci_epf_mhi_iatu_write(mhi_cntrl, buf_info); + + mutex_lock(&epf_mhi->lock); + + config.direction = DMA_MEM_TO_DEV; +- config.dst_addr = to; ++ config.dst_addr = buf_info->host_addr; + + ret = dmaengine_slave_config(chan, &config); + if (ret) { +@@ -367,14 +369,16 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from, + goto err_unlock; + } + +- src_addr = dma_map_single(dma_dev, from, size, DMA_TO_DEVICE); ++ src_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size, ++ DMA_TO_DEVICE); + ret = dma_mapping_error(dma_dev, src_addr); + if (ret) { + dev_err(dev, "Failed to map remote memory\n"); + goto err_unlock; + } + +- desc = dmaengine_prep_slave_single(chan, src_addr, size, DMA_MEM_TO_DEV, ++ desc = dmaengine_prep_slave_single(chan, src_addr, buf_info->size, ++ DMA_MEM_TO_DEV, + DMA_CTRL_ACK | DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(dev, "Failed to prepare DMA\n"); +@@ -401,7 +405,7 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from, + } + + err_unmap: +- dma_unmap_single(dma_dev, src_addr, size, DMA_FROM_DEVICE); ++ dma_unmap_single(dma_dev, src_addr, buf_info->size, DMA_TO_DEVICE); + err_unlock: + mutex_unlock(&epf_mhi->lock); + +diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c +index caae2d3e9d3ea..6404b17d3aeb0 100644 +--- a/drivers/perf/arm-cmn.c ++++ b/drivers/perf/arm-cmn.c +@@ -811,7 +811,7 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, + #define CMN_EVENT_HNF_OCC(_model, _name, _event) \ + CMN_EVENT_HN_OCC(_model, hnf_##_name, CMN_TYPE_HNF, _event) + #define CMN_EVENT_HNF_CLS(_model, _name, _event) \ +- CMN_EVENT_HN_CLS(_model, hnf_##_name, CMN_TYPE_HNS, _event) ++ CMN_EVENT_HN_CLS(_model, hnf_##_name, CMN_TYPE_HNF, _event) + #define CMN_EVENT_HNF_SNT(_model, _name, _event) \ + CMN_EVENT_HN_SNT(_model, hnf_##_name, CMN_TYPE_HNF, _event) + +diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c +index 63da05e5831c1..636fb79647c8c 100644 +--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c ++++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c +@@ -383,8 +383,8 @@ static struct attribute *hisi_uc_pmu_events_attr[] = { + HISI_PMU_EVENT_ATTR(cpu_rd, 0x10), + HISI_PMU_EVENT_ATTR(cpu_rd64, 0x17), + HISI_PMU_EVENT_ATTR(cpu_rs64, 0x19), +- HISI_PMU_EVENT_ATTR(cpu_mru, 0x1a), +- HISI_PMU_EVENT_ATTR(cycles, 0x9c), ++ HISI_PMU_EVENT_ATTR(cpu_mru, 0x1c), ++ HISI_PMU_EVENT_ATTR(cycles, 0x95), + HISI_PMU_EVENT_ATTR(spipe_hit, 0xb3), + HISI_PMU_EVENT_ATTR(hpipe_hit, 0xdb), + HISI_PMU_EVENT_ATTR(cring_rxdat_cnt, 0xfa), +diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c +index c1f9e4471b28f..343ab6a82c017 100644 +--- a/drivers/platform/x86/intel/vsec.c ++++ b/drivers/platform/x86/intel/vsec.c +@@ -120,6 +120,8 @@ static void intel_vsec_dev_release(struct device *dev) + { + struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); + ++ xa_erase(&auxdev_array, intel_vsec_dev->id); ++ + mutex_lock(&vsec_ida_lock); + ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); + mutex_unlock(&vsec_ida_lock); +@@ -135,19 +137,28 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, + struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; + int ret, id; + +- mutex_lock(&vsec_ida_lock); +- ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); +- mutex_unlock(&vsec_ida_lock); ++ ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, ++ PMT_XA_LIMIT, GFP_KERNEL); + if (ret < 0) { + kfree(intel_vsec_dev->resource); + kfree(intel_vsec_dev); + return ret; + } + ++ mutex_lock(&vsec_ida_lock); ++ id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); ++ mutex_unlock(&vsec_ida_lock); ++ if (id < 0) { ++ xa_erase(&auxdev_array, intel_vsec_dev->id); ++ kfree(intel_vsec_dev->resource); ++ kfree(intel_vsec_dev); ++ return id; ++ } ++ + if (!parent) + parent = &pdev->dev; + +- auxdev->id = ret; ++ auxdev->id = id; + auxdev->name = name; + auxdev->dev.parent = parent; + auxdev->dev.release = intel_vsec_dev_release; +@@ -169,12 +180,6 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, + if (ret < 0) + return ret; + +- /* Add auxdev to list */ +- ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT, +- GFP_KERNEL); +- if (ret) +- return ret; +- + return 0; + } + EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); +diff --git a/drivers/platform/x86/intel/vsec.h b/drivers/platform/x86/intel/vsec.h +index 0fd042c171ba0..0a6201b4a0e90 100644 +--- a/drivers/platform/x86/intel/vsec.h ++++ b/drivers/platform/x86/intel/vsec.h +@@ -45,6 +45,7 @@ struct intel_vsec_device { + struct ida *ida; + struct intel_vsec_platform_info *info; + int num_resources; ++ int id; /* xa */ + void *priv_data; + size_t priv_data_size; + }; +diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c +index 82d3cd5ee2f92..c8368dae69c71 100644 +--- a/drivers/power/supply/bq256xx_charger.c ++++ b/drivers/power/supply/bq256xx_charger.c +@@ -1574,13 +1574,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq) + wd_reg_val = i; + break; + } +- if (bq->watchdog_timer > bq256xx_watchdog_time[i] && ++ if (i + 1 < BQ256XX_NUM_WD_VAL && ++ bq->watchdog_timer > bq256xx_watchdog_time[i] && + bq->watchdog_timer < bq256xx_watchdog_time[i + 1]) + wd_reg_val = i; + } + ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1, + BQ256XX_WATCHDOG_MASK, wd_reg_val << + BQ256XX_WDT_BIT_SHIFT); ++ if (ret) ++ return ret; + + ret = power_supply_get_battery_info(bq->charger, &bat_info); + if (ret == -ENOMEM) +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index bb29e9ebd24a8..99f3ccdc30a6a 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -491,7 +491,7 @@ static int cw_battery_get_property(struct power_supply *psy, + + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + if (cw_battery_valid_time_to_empty(cw_bat)) +- val->intval = cw_bat->time_to_empty; ++ val->intval = cw_bat->time_to_empty * 60; + else + val->intval = 0; + break; +diff --git a/drivers/power/supply/qcom_pmi8998_charger.c b/drivers/power/supply/qcom_pmi8998_charger.c +index 10f4dd0caca17..22c7c0e7c5228 100644 +--- a/drivers/power/supply/qcom_pmi8998_charger.c ++++ b/drivers/power/supply/qcom_pmi8998_charger.c +@@ -973,10 +973,14 @@ static int smb2_probe(struct platform_device *pdev) + supply_config.of_node = pdev->dev.of_node; + + desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL); ++ if (!desc) ++ return -ENOMEM; + memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc)); + desc->name = + devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger", + (const char *)device_get_match_data(chip->dev)); ++ if (!desc->name) ++ return -ENOMEM; + + chip->chg_psy = + devm_power_supply_register(chip->dev, desc, &supply_config); +diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c +index dc66e3405bf50..0c8c63239adbf 100644 +--- a/drivers/pwm/core.c ++++ b/drivers/pwm/core.c +@@ -176,7 +176,7 @@ of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args) + pwm->args.period = args->args[0]; + pwm->args.polarity = PWM_POLARITY_NORMAL; + +- if (args->args_count == 2 && args->args[2] & PWM_POLARITY_INVERTED) ++ if (args->args_count == 2 && args->args[1] & PWM_POLARITY_INVERTED) + pwm->args.polarity = PWM_POLARITY_INVERSED; + + return pwm; +diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c +index ef1293f2a897e..7758d274a26cd 100644 +--- a/drivers/pwm/pwm-jz4740.c ++++ b/drivers/pwm/pwm-jz4740.c +@@ -60,9 +60,10 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) + snprintf(name, sizeof(name), "timer%u", pwm->hwpwm); + + clk = clk_get(chip->dev, name); +- if (IS_ERR(clk)) +- return dev_err_probe(chip->dev, PTR_ERR(clk), +- "Failed to get clock\n"); ++ if (IS_ERR(clk)) { ++ dev_err(chip->dev, "error %pe: Failed to get clock\n", clk); ++ return PTR_ERR(clk); ++ } + + err = clk_prepare_enable(clk); + if (err < 0) { +diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c +index 3d6be7749e231..dd2ee5d9ca066 100644 +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -579,32 +579,23 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) + priv->have_complementary_output = (ccer != 0); + } + +-static int stm32_pwm_detect_channels(struct stm32_pwm *priv) ++static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, ++ unsigned int *num_enabled) + { +- u32 ccer; +- int npwm = 0; ++ u32 ccer, ccer_backup; + + /* + * If channels enable bits don't exist writing 1 will have no + * effect so we can detect and count them. + */ ++ regmap_read(priv->regmap, TIM_CCER, &ccer_backup); + regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_read(priv->regmap, TIM_CCER, &ccer); +- regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); +- +- if (ccer & TIM_CCER_CC1E) +- npwm++; +- +- if (ccer & TIM_CCER_CC2E) +- npwm++; ++ regmap_write(priv->regmap, TIM_CCER, ccer_backup); + +- if (ccer & TIM_CCER_CC3E) +- npwm++; ++ *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); + +- if (ccer & TIM_CCER_CC4E) +- npwm++; +- +- return npwm; ++ return hweight32(ccer & TIM_CCER_CCXE); + } + + static int stm32_pwm_probe(struct platform_device *pdev) +@@ -613,6 +604,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) + struct device_node *np = dev->of_node; + struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + struct stm32_pwm *priv; ++ unsigned int num_enabled; ++ unsigned int i; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); +@@ -635,7 +628,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) + + priv->chip.dev = dev; + priv->chip.ops = &stm32pwm_ops; +- priv->chip.npwm = stm32_pwm_detect_channels(priv); ++ priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); ++ ++ /* Initialize clock refcount to number of enabled PWM channels. */ ++ for (i = 0; i < num_enabled; i++) ++ clk_enable(priv->clk); + + ret = devm_pwmchip_add(dev, &priv->chip); + if (ret < 0) +diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c +index 520f9152f3bf2..d4ceca2d435ee 100644 +--- a/drivers/scsi/bfa/bfad_bsg.c ++++ b/drivers/scsi/bfa/bfad_bsg.c +@@ -2550,7 +2550,7 @@ out: + static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, + int lunmask_cfg) + { +- const u32 scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; ++ const blist_flags_t scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; + struct bfad_itnim_s *itnim; + struct scsi_device *sdev; + unsigned long flags; +diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c +index c4d9ed0d7d753..2619a2d4f5f14 100644 +--- a/drivers/scsi/fnic/fnic_debugfs.c ++++ b/drivers/scsi/fnic/fnic_debugfs.c +@@ -52,9 +52,10 @@ int fnic_debugfs_init(void) + fc_trc_flag->fnic_trace = 2; + fc_trc_flag->fc_trace = 3; + fc_trc_flag->fc_clear = 4; ++ return 0; + } + +- return 0; ++ return -ENOMEM; + } + + /* +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 9472b9743aefb..b155ac800979c 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1565,12 +1565,12 @@ EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) + { + if (!hisi_hba->hw->soft_reset) +- return -1; ++ return -ENOENT; + + down(&hisi_hba->sem); + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { + up(&hisi_hba->sem); +- return -1; ++ return -EPERM; + } + + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) +@@ -1641,7 +1641,10 @@ static int hisi_sas_abort_task(struct sas_task *task) + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + spin_unlock_irqrestore(&task->task_state_lock, flags); + +- if (slot && task->task_proto & SAS_PROTOCOL_SSP) { ++ if (!slot) ++ goto out; ++ ++ if (task->task_proto & SAS_PROTOCOL_SSP) { + u16 tag = slot->idx; + int rc2; + +@@ -1688,7 +1691,7 @@ static int hisi_sas_abort_task(struct sas_task *task) + rc = hisi_sas_softreset_ata_disk(device); + } + } +- } else if (slot && task->task_proto & SAS_PROTOCOL_SMP) { ++ } else if (task->task_proto & SAS_PROTOCOL_SMP) { + /* SMP */ + u32 tag = slot->idx; + struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 089186fe17915..520fffc142822 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3478,7 +3478,7 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; + int i; + +- for (i = 0; i < debugfs_axi_reg.count; i++, databuf++) ++ for (i = 0; i < debugfs_global_reg.count; i++, databuf++) + *databuf = hisi_sas_read32(hisi_hba, 4 * i); + } + +@@ -5098,6 +5098,7 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) + { + struct sas_ha_struct *sha = pci_get_drvdata(pdev); + struct hisi_hba *hisi_hba = sha->lldd_ha; ++ struct Scsi_Host *shost = hisi_hba->shost; + struct device *dev = hisi_hba->dev; + int rc; + +@@ -5106,6 +5107,10 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) + rc = hw_init_v3_hw(hisi_hba); + if (rc) { + dev_err(dev, "FLR: hw init failed rc=%d\n", rc); ++ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); ++ scsi_unblock_requests(shost); ++ clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); ++ up(&hisi_hba->sem); + return; + } + +@@ -5148,7 +5153,7 @@ static int _suspend_v3_hw(struct device *device) + } + + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) +- return -1; ++ return -EPERM; + + dev_warn(dev, "entering suspend state\n"); + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c +index 08645a99ad6b3..9dacbb8570c93 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_app.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_app.c +@@ -223,6 +223,22 @@ static long mpi3mr_bsg_pel_enable(struct mpi3mr_ioc *mrioc, + return rval; + } + ++ if (mrioc->unrecoverable) { ++ dprint_bsg_err(mrioc, "%s: unrecoverable controller\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ if (mrioc->reset_in_progress) { ++ dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__); ++ return -EAGAIN; ++ } ++ ++ if (mrioc->stop_bsgs) { ++ dprint_bsg_err(mrioc, "%s: bsgs are blocked\n", __func__); ++ return -EAGAIN; ++ } ++ + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + &pel_enable, sizeof(pel_enable)); +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 89ba015c5d7e8..c7c75257425d4 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -1047,8 +1047,9 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) + list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list, + list) { + if ((tgtdev->dev_handle == MPI3MR_INVALID_DEV_HANDLE) && +- tgtdev->host_exposed && tgtdev->starget && +- tgtdev->starget->hostdata) { ++ tgtdev->is_hidden && ++ tgtdev->host_exposed && tgtdev->starget && ++ tgtdev->starget->hostdata) { + tgt_priv = tgtdev->starget->hostdata; + tgt_priv->dev_removed = 1; + atomic_set(&tgt_priv->block_io, 0); +@@ -1064,14 +1065,24 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) + mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, true); + mpi3mr_tgtdev_put(tgtdev); ++ } else if (tgtdev->is_hidden & tgtdev->host_exposed) { ++ dprint_reset(mrioc, "hiding target device with perst_id(%d)\n", ++ tgtdev->perst_id); ++ mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); + } + } + + tgtdev = NULL; + list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) { + if ((tgtdev->dev_handle != MPI3MR_INVALID_DEV_HANDLE) && +- !tgtdev->is_hidden && !tgtdev->host_exposed) +- mpi3mr_report_tgtdev_to_host(mrioc, tgtdev->perst_id); ++ !tgtdev->is_hidden) { ++ if (!tgtdev->host_exposed) ++ mpi3mr_report_tgtdev_to_host(mrioc, ++ tgtdev->perst_id); ++ else if (tgtdev->starget) ++ starget_for_each_device(tgtdev->starget, ++ (void *)tgtdev, mpi3mr_update_sdev); ++ } + } + } + +diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c +index c61848595da06..e877aace11555 100644 +--- a/drivers/soc/qcom/llcc-qcom.c ++++ b/drivers/soc/qcom/llcc-qcom.c +@@ -46,7 +46,7 @@ + #define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K) + #define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) + #define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) +-#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_8 * n) ++#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_4 * n) + + #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 + #define LLCC_TRP_PCB_ACT 0x21f04 +@@ -785,15 +785,15 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, + u32 disable_cap_alloc, retain_pc; + + disable_cap_alloc = config->dis_cap_alloc << config->slice_id; +- ret = regmap_write(drv_data->bcast_regmap, +- LLCC_TRP_SCID_DIS_CAP_ALLOC, disable_cap_alloc); ++ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC, ++ BIT(config->slice_id), disable_cap_alloc); + if (ret) + return ret; + + if (drv_data->version < LLCC_VERSION_4_1_0_0) { + retain_pc = config->retain_on_pc << config->slice_id; +- ret = regmap_write(drv_data->bcast_regmap, +- LLCC_TRP_PCB_ACT, retain_pc); ++ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT, ++ BIT(config->slice_id), retain_pc); + if (ret) + return ret; + } +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index bcbf840cd41c8..3ce0fd5df8e9c 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -1165,9 +1165,10 @@ config SPI_ZYNQ_QSPI + + config SPI_ZYNQMP_GQSPI + tristate "Xilinx ZynqMP GQSPI controller" +- depends on (SPI_MASTER && HAS_DMA) || COMPILE_TEST ++ depends on (SPI_MEM && HAS_DMA) || COMPILE_TEST + help + Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. ++ This controller only supports SPI memory interface. + + config SPI_AMD + tristate "AMD SPI controller" +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index b50db71ac4ccc..2064dc4ea935f 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -1825,7 +1825,7 @@ static int cqspi_probe(struct platform_device *pdev) + if (ddata->jh7110_clk_init) { + ret = cqspi_jh7110_clk_init(pdev, cqspi); + if (ret) +- goto probe_clk_failed; ++ goto probe_reset_failed; + } + + if (of_device_is_compatible(pdev->dev.of_node, +@@ -1872,6 +1872,8 @@ static int cqspi_probe(struct platform_device *pdev) + probe_setup_failed: + cqspi_controller_enable(cqspi, 0); + probe_reset_failed: ++ if (cqspi->is_jh7110) ++ cqspi_jh7110_disable_clk(pdev, cqspi); + clk_disable_unprepare(cqspi->clk); + probe_clk_failed: + pm_runtime_put_sync(dev); +diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c +index f0b630fe16c3c..b341b6908df06 100644 +--- a/drivers/spi/spi-coldfire-qspi.c ++++ b/drivers/spi/spi-coldfire-qspi.c +@@ -441,7 +441,6 @@ static void mcfqspi_remove(struct platform_device *pdev) + mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); + + mcfqspi_cs_teardown(mcfqspi); +- clk_disable_unprepare(mcfqspi->clk); + } + + #ifdef CONFIG_PM_SLEEP +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index fb452bc783727..cfc3b1ddbd229 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -29,12 +29,15 @@ + + #include + ++#define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) ++ + struct sh_msiof_chipdata { + u32 bits_per_word_mask; + u16 tx_fifo_size; + u16 rx_fifo_size; + u16 ctlr_flags; + u16 min_div_pow; ++ u32 flags; + }; + + struct sh_msiof_spi_priv { +@@ -1072,6 +1075,16 @@ static const struct sh_msiof_chipdata rcar_gen3_data = { + .min_div_pow = 1, + }; + ++static const struct sh_msiof_chipdata rcar_r8a7795_data = { ++ .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) | ++ SPI_BPW_MASK(24) | SPI_BPW_MASK(32), ++ .tx_fifo_size = 64, ++ .rx_fifo_size = 64, ++ .ctlr_flags = SPI_CONTROLLER_MUST_TX, ++ .min_div_pow = 1, ++ .flags = SH_MSIOF_FLAG_FIXED_DTDL_200, ++}; ++ + static const struct of_device_id sh_msiof_match[] __maybe_unused = { + { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, + { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, +@@ -1082,6 +1095,7 @@ static const struct of_device_id sh_msiof_match[] __maybe_unused = { + { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, + { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, ++ { .compatible = "renesas,msiof-r8a7795", .data = &rcar_r8a7795_data }, + { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, + { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, + { .compatible = "renesas,rcar-gen4-msiof", .data = &rcar_gen3_data }, +@@ -1279,6 +1293,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + return -ENXIO; + } + ++ if (chipdata->flags & SH_MSIOF_FLAG_FIXED_DTDL_200) ++ info->dtdl = 200; ++ + if (info->mode == MSIOF_SPI_TARGET) + ctlr = spi_alloc_target(&pdev->dev, + sizeof(struct sh_msiof_spi_priv)); +diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c +index b3c991e1ea40d..54c35f5535cbe 100644 +--- a/drivers/spmi/spmi-mtk-pmif.c ++++ b/drivers/spmi/spmi-mtk-pmif.c +@@ -50,6 +50,7 @@ struct pmif { + struct clk_bulk_data clks[PMIF_MAX_CLKS]; + size_t nclks; + const struct pmif_data *data; ++ raw_spinlock_t lock; + }; + + static const char * const pmif_clock_names[] = { +@@ -314,6 +315,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + struct ch_reg *inf_reg; + int ret; + u32 data, cmd; ++ unsigned long flags; + + /* Check for argument validation. */ + if (sid & ~0xf) { +@@ -334,6 +336,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + else + return -EINVAL; + ++ raw_spin_lock_irqsave(&arb->lock, flags); + /* Wait for Software Interface FSM state to be IDLE. */ + inf_reg = &arb->chan; + ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], +@@ -343,6 +346,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* set channel ready if the data has transferred */ + if (pmif_is_fsm_vldclr(arb)) + pmif_writel(arb, 1, inf_reg->ch_rdy); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); + return ret; + } +@@ -350,6 +354,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* Send the command. */ + cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; + pmif_writel(arb, cmd, inf_reg->ch_send); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + + /* + * Wait for Software Interface FSM state to be WFVLDCLR, +@@ -376,7 +381,8 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct ch_reg *inf_reg; + int ret; +- u32 data, cmd; ++ u32 data, wdata, cmd; ++ unsigned long flags; + + if (len > 4) { + dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); +@@ -394,6 +400,10 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + else + return -EINVAL; + ++ /* Set the write data. */ ++ memcpy(&wdata, buf, len); ++ ++ raw_spin_lock_irqsave(&arb->lock, flags); + /* Wait for Software Interface FSM state to be IDLE. */ + inf_reg = &arb->chan; + ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], +@@ -403,17 +413,17 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, + /* set channel ready if the data has transferred */ + if (pmif_is_fsm_vldclr(arb)) + pmif_writel(arb, 1, inf_reg->ch_rdy); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); + return ret; + } + +- /* Set the write data. */ +- memcpy(&data, buf, len); +- pmif_writel(arb, data, inf_reg->wdata); ++ pmif_writel(arb, wdata, inf_reg->wdata); + + /* Send the command. */ + cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; + pmif_writel(arb, cmd, inf_reg->ch_send); ++ raw_spin_unlock_irqrestore(&arb->lock, flags); + + return 0; + } +@@ -488,6 +498,8 @@ static int mtk_spmi_probe(struct platform_device *pdev) + arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; + arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; + ++ raw_spin_lock_init(&arb->lock); ++ + platform_set_drvdata(pdev, ctrl); + + err = spmi_controller_add(ctrl); +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 84a41792cb4b8..ac398b5a97360 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -461,6 +461,9 @@ static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = { + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, ++ ++ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, ++ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, + }; + + static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, +diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c +index 4d447520bab87..4e4cf6c34a775 100644 +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -332,11 +332,13 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, + } + + iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); +- if (is_write) ++ if (is_write) { ++ file_start_write(fd); + ret = vfs_iter_write(fd, &iter, &pos, 0); +- else ++ file_end_write(fd); ++ } else { + ret = vfs_iter_read(fd, &iter, &pos, 0); +- ++ } + if (is_write) { + if (ret < 0 || ret != data_length) { + pr_err("%s() write returned %d\n", __func__, ret); +@@ -467,7 +469,9 @@ fd_execute_write_same(struct se_cmd *cmd) + } + + iov_iter_bvec(&iter, ITER_SOURCE, bvec, nolb, len); ++ file_start_write(fd_dev->fd_file); + ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0); ++ file_end_write(fd_dev->fd_file); + + kfree(bvec); + if (ret < 0 || ret != len) { +diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c +index 133098dc08547..99ca0c7bc41c7 100644 +--- a/drivers/thermal/loongson2_thermal.c ++++ b/drivers/thermal/loongson2_thermal.c +@@ -127,7 +127,7 @@ static int loongson2_thermal_probe(struct platform_device *pdev) + if (!IS_ERR(tzd)) + break; + +- if (PTR_ERR(tzd) != ENODEV) ++ if (PTR_ERR(tzd) != -ENODEV) + continue; + + return dev_err_probe(dev, PTR_ERR(tzd), "failed to register"); +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index e6f3166a9208f..2de524fb7be55 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1382,7 +1382,6 @@ unregister: + device_del(&tz->device); + release_device: + put_device(&tz->device); +- tz = NULL; + remove_id: + ida_free(&thermal_tz_ida, id); + free_tzp: +diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c +index 15a2387a5b258..4f4502fb5454c 100644 +--- a/drivers/tty/serial/8250/8250_bcm2835aux.c ++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c +@@ -119,6 +119,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) + + /* get the clock - this also enables the HW */ + data->clk = devm_clk_get_optional(&pdev->dev, NULL); ++ if (IS_ERR(data->clk)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n"); + + /* get the interrupt */ + ret = platform_get_irq(pdev, 0); +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index 077c3ba3539e6..8385be846840a 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -446,7 +446,7 @@ static int generic_rs485_config(struct uart_port *port, struct ktermios *termios + } + + static const struct serial_rs485 generic_rs485_supported = { +- .flags = SER_RS485_ENABLED, ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, + }; + + static const struct exar8250_platform exar8250_default_platform = { +@@ -490,7 +490,8 @@ static int iot2040_rs485_config(struct uart_port *port, struct ktermios *termios + } + + static const struct serial_rs485 iot2040_rs485_supported = { +- .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | ++ SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, + }; + + static const struct property_entry iot2040_gpio_properties[] = { +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 1122f37fe744e..346167afe9e11 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1581,7 +1581,7 @@ static int omap8250_remove(struct platform_device *pdev) + + err = pm_runtime_resume_and_get(&pdev->dev); + if (err) +- return err; ++ dev_err(&pdev->dev, "Failed to resume hardware\n"); + + up = serial8250_get_port(priv->line); + omap_8250_shutdown(&up->port); +diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c +index d7658f3808380..d3cb341f2c553 100644 +--- a/drivers/tty/serial/apbuart.c ++++ b/drivers/tty/serial/apbuart.c +@@ -122,7 +122,7 @@ static void apbuart_tx_chars(struct uart_port *port) + { + u8 ch; + +- uart_port_tx_limited(port, ch, port->fifosize >> 1, ++ uart_port_tx_limited(port, ch, port->fifosize, + true, + UART_PUT_CHAR(port, ch), + ({})); +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index 13cb78340709a..cd36251ba1c02 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -421,13 +421,13 @@ static void imx_uart_stop_tx(struct uart_port *port) + ucr1 = imx_uart_readl(sport, UCR1); + imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); + ++ ucr4 = imx_uart_readl(sport, UCR4); + usr2 = imx_uart_readl(sport, USR2); +- if (!(usr2 & USR2_TXDC)) { ++ if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) { + /* The shifter is still busy, so retry once TC triggers */ + return; + } + +- ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + +@@ -2214,7 +2214,6 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) + return HRTIMER_NORESTART; + } + +-static const struct serial_rs485 imx_no_rs485 = {}; /* No RS485 if no RTS */ + static const struct serial_rs485 imx_rs485_supported = { + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | + SER_RS485_RX_DURING_TX, +@@ -2298,8 +2297,6 @@ static int imx_uart_probe(struct platform_device *pdev) + /* RTS is required to control the RS485 transmitter */ + if (sport->have_rtscts || sport->have_rtsgpio) + sport->port.rs485_supported = imx_rs485_supported; +- else +- sport->port.rs485_supported = imx_no_rs485; + sport->port.flags = UPF_BOOT_AUTOCONF; + timer_setup(&sport->timer, imx_uart_timeout, 0); + +@@ -2326,19 +2323,13 @@ static int imx_uart_probe(struct platform_device *pdev) + /* For register access, we only need to enable the ipg clock. */ + ret = clk_prepare_enable(sport->clk_ipg); + if (ret) { +- dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret); ++ dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); + return ret; + } + + ret = uart_get_rs485_mode(&sport->port); +- if (ret) { +- clk_disable_unprepare(sport->clk_ipg); +- return ret; +- } +- +- if (sport->port.rs485.flags & SER_RS485_ENABLED && +- (!sport->have_rtscts && !sport->have_rtsgpio)) +- dev_err(&pdev->dev, "no RTS control, disabling rs485\n"); ++ if (ret) ++ goto err_clk; + + /* + * If using the i.MX UART RTS/CTS control then the RTS (CTS_B) +@@ -2418,8 +2409,6 @@ static int imx_uart_probe(struct platform_device *pdev) + imx_uart_writel(sport, ucr3, UCR3); + } + +- clk_disable_unprepare(sport->clk_ipg); +- + hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + sport->trigger_start_tx.function = imx_trigger_start_tx; +@@ -2435,7 +2424,7 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request rx irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0, +@@ -2443,7 +2432,7 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request tx irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + + ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0, +@@ -2451,14 +2440,14 @@ static int imx_uart_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "failed to request rts irq: %d\n", + ret); +- return ret; ++ goto err_clk; + } + } else { + ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0, + dev_name(&pdev->dev), sport); + if (ret) { + dev_err(&pdev->dev, "failed to request irq: %d\n", ret); +- return ret; ++ goto err_clk; + } + } + +@@ -2466,7 +2455,12 @@ static int imx_uart_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, sport); + +- return uart_add_one_port(&imx_uart_uart_driver, &sport->port); ++ ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port); ++ ++err_clk: ++ clk_disable_unprepare(sport->clk_ipg); ++ ++ return ret; + } + + static int imx_uart_remove(struct platform_device *pdev) +diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c +index 0ead88c5a19ad..135a838f517a2 100644 +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -1483,6 +1483,13 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) + return omap_up_info; + } + ++static const struct serial_rs485 serial_omap_rs485_supported = { ++ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | ++ SER_RS485_RX_DURING_TX, ++ .delay_rts_before_send = 1, ++ .delay_rts_after_send = 1, ++}; ++ + static int serial_omap_probe_rs485(struct uart_omap_port *up, + struct device *dev) + { +@@ -1497,6 +1504,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, + if (!np) + return 0; + ++ up->port.rs485_config = serial_omap_config_rs485; ++ up->port.rs485_supported = serial_omap_rs485_supported; ++ + ret = uart_get_rs485_mode(&up->port); + if (ret) + return ret; +@@ -1531,13 +1541,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, + return 0; + } + +-static const struct serial_rs485 serial_omap_rs485_supported = { +- .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | +- SER_RS485_RX_DURING_TX, +- .delay_rts_before_send = 1, +- .delay_rts_after_send = 1, +-}; +- + static int serial_omap_probe(struct platform_device *pdev) + { + struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); +@@ -1604,17 +1607,11 @@ static int serial_omap_probe(struct platform_device *pdev) + dev_info(up->port.dev, "no wakeirq for uart%d\n", + up->port.line); + +- ret = serial_omap_probe_rs485(up, &pdev->dev); +- if (ret < 0) +- goto err_rs485; +- + sprintf(up->name, "OMAP UART%d", up->port.line); + up->port.mapbase = mem->start; + up->port.membase = base; + up->port.flags = omap_up_info->flags; + up->port.uartclk = omap_up_info->uartclk; +- up->port.rs485_config = serial_omap_config_rs485; +- up->port.rs485_supported = serial_omap_rs485_supported; + if (!up->port.uartclk) { + up->port.uartclk = DEFAULT_CLK_SPEED; + dev_warn(&pdev->dev, +@@ -1622,6 +1619,10 @@ static int serial_omap_probe(struct platform_device *pdev) + DEFAULT_CLK_SPEED); + } + ++ ret = serial_omap_probe_rs485(up, &pdev->dev); ++ if (ret < 0) ++ goto err_rs485; ++ + up->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + up->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + cpu_latency_qos_add_request(&up->pm_qos_request, up->latency); +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index 6a0a3208d0900..6aeb821d9b1da 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + #define SC16IS7XX_NAME "sc16is7xx" +@@ -1714,9 +1715,12 @@ static int sc16is7xx_spi_probe(struct spi_device *spi) + + /* Setup SPI bus */ + spi->bits_per_word = 8; +- /* only supports mode 0 on SC16IS762 */ ++ /* For all variants, only mode 0 is supported */ ++ if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0) ++ return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n"); ++ + spi->mode = spi->mode ? : SPI_MODE_0; +- spi->max_speed_hz = spi->max_speed_hz ? : 15000000; ++ spi->max_speed_hz = spi->max_speed_hz ? : 4 * HZ_PER_MHZ; + ret = spi_setup(spi); + if (ret) + return ret; +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index f912f8bf1e633..18b49b1439a58 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -1370,19 +1370,27 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4 + return; + } + ++ rs485->flags &= supported_flags; ++ + /* Pick sane settings if the user hasn't */ +- if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) && +- !(rs485->flags & SER_RS485_RTS_ON_SEND) == ++ if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == + !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { +- dev_warn_ratelimited(port->dev, +- "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", +- port->name, port->line); +- rs485->flags |= SER_RS485_RTS_ON_SEND; +- rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; +- supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND; +- } ++ if (supported_flags & SER_RS485_RTS_ON_SEND) { ++ rs485->flags |= SER_RS485_RTS_ON_SEND; ++ rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + +- rs485->flags &= supported_flags; ++ dev_warn_ratelimited(port->dev, ++ "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", ++ port->name, port->line); ++ } else { ++ rs485->flags |= SER_RS485_RTS_AFTER_SEND; ++ rs485->flags &= ~SER_RS485_RTS_ON_SEND; ++ ++ dev_warn_ratelimited(port->dev, ++ "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n", ++ port->name, port->line); ++ } ++ } + + uart_sanitize_serial_rs485_delays(port, rs485); + +@@ -1445,7 +1453,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, + int ret; + unsigned long flags; + +- if (!port->rs485_config) ++ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) + return -ENOTTY; + + if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) +@@ -3568,6 +3576,9 @@ int uart_get_rs485_mode(struct uart_port *port) + int ret; + int rx_during_tx_gpio_flag; + ++ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) ++ return 0; ++ + ret = device_property_read_u32_array(dev, "rs485-rts-delay", + rs485_delay, 2); + if (!ret) { +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 8a94e5a43c6d2..493fc4742895f 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -2475,22 +2475,25 @@ static int send_break(struct tty_struct *tty, unsigned int duration) + return 0; + + if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) +- retval = tty->ops->break_ctl(tty, duration); +- else { +- /* Do the work ourselves */ +- if (tty_write_lock(tty, false) < 0) +- return -EINTR; +- retval = tty->ops->break_ctl(tty, -1); +- if (retval) +- goto out; +- if (!signal_pending(current)) +- msleep_interruptible(duration); ++ return tty->ops->break_ctl(tty, duration); ++ ++ /* Do the work ourselves */ ++ if (tty_write_lock(tty, false) < 0) ++ return -EINTR; ++ ++ retval = tty->ops->break_ctl(tty, -1); ++ if (!retval) { ++ msleep_interruptible(duration); + retval = tty->ops->break_ctl(tty, 0); +-out: +- tty_write_unlock(tty); +- if (signal_pending(current)) +- retval = -EINTR; ++ } else if (retval == -EOPNOTSUPP) { ++ /* some drivers can tell only dynamically */ ++ retval = 0; + } ++ tty_write_unlock(tty); ++ ++ if (signal_pending(current)) ++ retval = -EINTR; ++ + return retval; + } + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index a885cc177cff7..0971ae37f2a71 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -8540,7 +8540,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba) + + ufs_bsg_probe(hba); + scsi_scan_host(hba->host); +- pm_runtime_put_sync(hba->dev); + + out: + return ret; +@@ -8808,15 +8807,15 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) + + /* Probe and add UFS logical units */ + ret = ufshcd_add_lus(hba); ++ + out: ++ pm_runtime_put_sync(hba->dev); + /* + * If we failed to initialize the device or the device is not + * present, turn off the power/clocks etc. + */ +- if (ret) { +- pm_runtime_put_sync(hba->dev); ++ if (ret) + ufshcd_hba_exit(hba); +- } + } + + static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd) +diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c +index fc40726e13c26..0cbe14aca8774 100644 +--- a/drivers/ufs/host/ufs-qcom.c ++++ b/drivers/ufs/host/ufs-qcom.c +@@ -159,7 +159,7 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, + cap = hba->crypto_cap_array[cfg->crypto_cap_idx]; + if (cap.algorithm_id != UFS_CRYPTO_ALG_AES_XTS || + cap.key_size != UFS_CRYPTO_KEY_SIZE_256) +- return -EINVAL; ++ return -EOPNOTSUPP; + + if (config_enable) + return qcom_ice_program_key(host->ice, +@@ -1675,7 +1675,7 @@ static int ufs_qcom_mcq_config_resource(struct ufs_hba *hba) + if (!res->resource) { + dev_info(hba->dev, "Resource %s not provided\n", res->name); + if (i == RES_UFS) +- return -ENOMEM; ++ return -ENODEV; + continue; + } else if (i == RES_UFS) { + res_mem = res->resource; +diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c +index 11a5b3437c32d..d140010257004 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -1119,6 +1119,8 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + dma_addr_t trb_dma; + u32 togle_pcs = 1; + int sg_iter = 0; ++ int num_trb_req; ++ int trb_burst; + int num_trb; + int address; + u32 control; +@@ -1127,15 +1129,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + struct scatterlist *s = NULL; + bool sg_supported = !!(request->num_mapped_sgs); + ++ num_trb_req = sg_supported ? request->num_mapped_sgs : 1; ++ ++ /* ISO transfer require each SOF have a TD, each TD include some TRBs */ + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) +- num_trb = priv_ep->interval; ++ num_trb = priv_ep->interval * num_trb_req; + else +- num_trb = sg_supported ? request->num_mapped_sgs : 1; +- +- if (num_trb > priv_ep->free_trbs) { +- priv_ep->flags |= EP_RING_FULL; +- return -ENOBUFS; +- } ++ num_trb = num_trb_req; + + priv_req = to_cdns3_request(request); + address = priv_ep->endpoint.desc->bEndpointAddress; +@@ -1184,14 +1184,31 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + + link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) | + TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit); ++ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { ++ /* ++ * ISO require LINK TRB must be first one of TD. ++ * Fill LINK TRBs for left trb space to simply software process logic. ++ */ ++ while (priv_ep->enqueue) { ++ *trb = *link_trb; ++ trace_cdns3_prepare_trb(priv_ep, trb); ++ ++ cdns3_ep_inc_enq(priv_ep); ++ trb = priv_ep->trb_pool + priv_ep->enqueue; ++ priv_req->trb = trb; ++ } ++ } ++ } ++ ++ if (num_trb > priv_ep->free_trbs) { ++ priv_ep->flags |= EP_RING_FULL; ++ return -ENOBUFS; + } + + if (priv_dev->dev_ver <= DEV_VER_V2) + togle_pcs = cdns3_wa1_update_guard(priv_ep, trb); + +- if (sg_supported) +- s = request->sg; +- + /* set incorrect Cycle Bit for first trb*/ + control = priv_ep->pcs ? 0 : TRB_CYCLE; + trb->length = 0; +@@ -1209,6 +1226,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + do { + u32 length; + ++ if (!(sg_iter % num_trb_req) && sg_supported) ++ s = request->sg; ++ + /* fill TRB */ + control |= TRB_TYPE(TRB_NORMAL); + if (sg_supported) { +@@ -1223,7 +1243,36 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + total_tdl += DIV_ROUND_UP(length, + priv_ep->endpoint.maxpacket); + +- trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) | ++ trb_burst = priv_ep->trb_burst_size; ++ ++ /* ++ * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still ++ * met problem when do ISO transfer if sg enabled. ++ * ++ * Data pattern likes below when sg enabled, package size is 1k and mult is 2 ++ * [UVC Header(8B) ] [data(3k - 8)] ... ++ * ++ * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen ++ * as below pattern: ++ * 0xd000: wrong ++ * 0xe000: wrong ++ * 0xf000: correct ++ * 0x10000: wrong ++ * 0x11000: wrong ++ * 0x12000: correct ++ * ... ++ * ++ * But it is still unclear about why error have not happen below 0xd000, it should ++ * cross 4k bounder. But anyway, the below code can fix this problem. ++ * ++ * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16. ++ */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2) ++ if (ALIGN_DOWN(trb->buffer, SZ_4K) != ++ ALIGN_DOWN(trb->buffer + length, SZ_4K)) ++ trb_burst = 16; ++ ++ trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) | + TRB_LEN(length)); + pcs = priv_ep->pcs ? TRB_CYCLE : 0; + +@@ -1250,7 +1299,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + if (sg_supported) { + trb->control |= cpu_to_le32(TRB_ISP); + /* Don't set chain bit for last TRB */ +- if (sg_iter < num_trb - 1) ++ if ((sg_iter % num_trb_req) < num_trb_req - 1) + trb->control |= cpu_to_le32(TRB_CHAIN); + + s = sg_next(s); +@@ -1508,6 +1557,12 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, + + /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */ + while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { ++ ++ /* ISO ep_traddr may stop at LINK TRB */ ++ if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) && ++ priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ break; ++ + trace_cdns3_complete_trb(priv_ep, trb); + cdns3_ep_inc_deq(priv_ep); + trb = priv_ep->trb_pool + priv_ep->dequeue; +@@ -1540,6 +1595,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, + } + + if (request_handled) { ++ /* TRBs are duplicated by priv_ep->interval time for ISO IN */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir) ++ request->actual /= priv_ep->interval; ++ + cdns3_gadget_giveback(priv_ep, priv_req, 0); + request_handled = false; + transfer_end = false; +@@ -2035,11 +2094,10 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + u32 bEndpointAddress = priv_ep->num | priv_ep->dir; +- u32 max_packet_size = 0; +- u8 maxburst = 0; ++ u32 max_packet_size = priv_ep->wMaxPacketSize; ++ u8 maxburst = priv_ep->bMaxBurst; + u32 ep_cfg = 0; + u8 buffering; +- u8 mult = 0; + int ret; + + buffering = priv_dev->ep_buf_size - 1; +@@ -2061,8 +2119,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + break; + default: + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); +- mult = priv_dev->ep_iso_burst - 1; +- buffering = mult + 1; ++ buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1; + } + + switch (priv_dev->gadget.speed) { +@@ -2073,17 +2130,8 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + max_packet_size = is_iso_ep ? 1024 : 512; + break; + case USB_SPEED_SUPER: +- /* It's limitation that driver assumes in driver. */ +- mult = 0; +- max_packet_size = 1024; +- if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { +- maxburst = priv_dev->ep_iso_burst - 1; +- buffering = (mult + 1) * +- (maxburst + 1); +- +- if (priv_ep->interval > 1) +- buffering++; +- } else { ++ if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { ++ max_packet_size = 1024; + maxburst = priv_dev->ep_buf_size - 1; + } + break; +@@ -2112,7 +2160,6 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + if (priv_dev->dev_ver < DEV_VER_V2) + priv_ep->trb_burst_size = 16; + +- mult = min_t(u8, mult, EP_CFG_MULT_MAX); + buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); + maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); + +@@ -2146,7 +2193,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + } + + ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | +- EP_CFG_MULT(mult) | ++ EP_CFG_MULT(priv_ep->mult) | /* must match EP setting */ + EP_CFG_BUFFERING(buffering) | + EP_CFG_MAXBURST(maxburst); + +@@ -2236,6 +2283,13 @@ usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, + priv_ep->type = usb_endpoint_type(desc); + priv_ep->flags |= EP_CLAIMED; + priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; ++ priv_ep->wMaxPacketSize = usb_endpoint_maxp(desc); ++ priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize); ++ priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK; ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) { ++ priv_ep->mult = USB_SS_MULT(comp_desc->bmAttributes) - 1; ++ priv_ep->bMaxBurst = comp_desc->bMaxBurst; ++ } + + spin_unlock_irqrestore(&priv_dev->lock, flags); + return &priv_ep->endpoint; +@@ -3019,22 +3073,40 @@ static int cdns3_gadget_check_config(struct usb_gadget *gadget) + struct cdns3_endpoint *priv_ep; + struct usb_ep *ep; + int n_in = 0; ++ int iso = 0; ++ int out = 1; + int total; ++ int n; + + list_for_each_entry(ep, &gadget->ep_list, ep_list) { + priv_ep = ep_to_cdns3_ep(ep); +- if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN)) +- n_in++; ++ if (!(priv_ep->flags & EP_CLAIMED)) ++ continue; ++ ++ n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1); ++ if (ep->address & USB_DIR_IN) { ++ /* ++ * ISO transfer: DMA start move data when get ISO, only transfer ++ * data as min(TD size, iso). No benefit for allocate bigger ++ * internal memory than 'iso'. ++ */ ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ iso += n; ++ else ++ n_in++; ++ } else { ++ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) ++ out = max_t(int, out, n); ++ } + } + + /* 2KB are reserved for EP0, 1KB for out*/ +- total = 2 + n_in + 1; ++ total = 2 + n_in + out + iso; + + if (total > priv_dev->onchip_buffers) + return -ENOMEM; + +- priv_dev->ep_buf_size = priv_dev->ep_iso_burst = +- (priv_dev->onchip_buffers - 2) / (n_in + 1); ++ priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out); + + return 0; + } +diff --git a/drivers/usb/cdns3/cdns3-gadget.h b/drivers/usb/cdns3/cdns3-gadget.h +index fbe4a8e3aa897..086a7bb838975 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.h ++++ b/drivers/usb/cdns3/cdns3-gadget.h +@@ -1168,6 +1168,9 @@ struct cdns3_endpoint { + u8 dir; + u8 num; + u8 type; ++ u8 mult; ++ u8 bMaxBurst; ++ u16 wMaxPacketSize; + int interval; + + int free_trbs; +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index 7ac39a281b8cb..85e9c3ab66e94 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int irq, void *data) + u32 otgsc = 0; + + if (ci->in_lpm) { ++ /* ++ * If we already have a wakeup irq pending there, ++ * let's just return to wait resume finished firstly. ++ */ ++ if (ci->wakeup_int) ++ return IRQ_HANDLED; ++ + disable_irq_nosync(irq); + ci->wakeup_int = true; + pm_runtime_get(ci->dev); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index a1f4e1ead97ff..0e7439dba8fe8 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -916,6 +916,9 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) + struct acm *acm = tty->driver_data; + int retval; + ++ if (!(acm->ctrl_caps & USB_CDC_CAP_BRK)) ++ return -EOPNOTSUPP; ++ + retval = acm_send_break(acm, state ? 0xffff : 0); + if (retval < 0) + dev_dbg(&acm->control->dev, +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 8d5af9ccb6027..b73b79fea281d 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -277,48 +277,11 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) + /* + * We're resetting only the device side because, if we're in host mode, + * XHCI driver will reset the host block. If dwc3 was configured for +- * host-only mode or current role is host, then we can return early. ++ * host-only mode, then we can return early. + */ + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) + return 0; + +- /* +- * If the dr_mode is host and the dwc->current_dr_role is not the +- * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode +- * isn't executed yet. Ensure the phy is ready before the controller +- * updates the GCTL.PRTCAPDIR or other settings by soft-resetting +- * the phy. +- * +- * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n +- * is port index. If this is a multiport host, then we need to reset +- * all active ports. +- */ +- if (dwc->dr_mode == USB_DR_MODE_HOST) { +- u32 usb3_port; +- u32 usb2_port; +- +- usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); +- usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); +- +- usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); +- usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); +- +- /* Small delay for phy reset assertion */ +- usleep_range(1000, 2000); +- +- usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); +- +- usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); +- +- /* Wait for clock synchronization */ +- msleep(50); +- return 0; +- } +- + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg |= DWC3_DCTL_CSFTRST; + reg &= ~DWC3_DCTL_RUN_STOP; +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index b942432372937..6ae8a36f21cf6 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -238,7 +238,10 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) + struct dwc3_request *req; + + req = next_request(&dep->pending_list); +- dwc3_gadget_giveback(dep, req, -ECONNRESET); ++ if (!dwc->connected) ++ dwc3_gadget_giveback(dep, req, -ESHUTDOWN); ++ else ++ dwc3_gadget_giveback(dep, req, -ECONNRESET); + } + + dwc->eps[0]->trb_enqueue = 0; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 858fe4c299b7a..89de363ecf8bb 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2103,7 +2103,17 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, + + list_for_each_entry(r, &dep->pending_list, list) { + if (r == req) { +- dwc3_gadget_giveback(dep, req, -ECONNRESET); ++ /* ++ * Explicitly check for EP0/1 as dequeue for those ++ * EPs need to be handled differently. Control EP ++ * only deals with one USB req, and giveback will ++ * occur during dwc3_ep0_stall_and_restart(). EP0 ++ * requests are never added to started_list. ++ */ ++ if (dep->number > 1) ++ dwc3_gadget_giveback(dep, req, -ECONNRESET); ++ else ++ dwc3_ep0_reset_state(dwc); + goto out; + } + } +@@ -3973,6 +3983,13 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) + usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED); + + dwc3_ep0_reset_state(dwc); ++ ++ /* ++ * Request PM idle to address condition where usage count is ++ * already decremented to zero, but waiting for the disconnect ++ * interrupt to set dwc->connected to FALSE. ++ */ ++ pm_request_idle(dwc->dev); + } + + static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) +diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c +index faa398109431f..2e6bafb2a5549 100644 +--- a/drivers/usb/gadget/function/f_uvc.c ++++ b/drivers/usb/gadget/function/f_uvc.c +@@ -719,13 +719,29 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) + } + uvc->enable_interrupt_ep = opts->enable_interrupt_ep; + +- ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); ++ /* ++ * gadget_is_{super|dual}speed() API check UDC controller capitblity. It should pass down ++ * highest speed endpoint descriptor to UDC controller. So UDC controller driver can reserve ++ * enough resource at check_config(), especially mult and maxburst. So UDC driver (such as ++ * cdns3) can know need at least (mult + 1) * (maxburst + 1) * wMaxPacketSize internal ++ * memory for this uvc functions. This is the only straightforward method to resolve the UDC ++ * resource allocation issue in the current gadget framework. ++ */ ++ if (gadget_is_superspeed(c->cdev->gadget)) ++ ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, ++ &uvc_ss_streaming_comp); ++ else if (gadget_is_dualspeed(cdev->gadget)) ++ ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep); ++ else ++ ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); ++ + if (!ep) { + uvcg_info(f, "Unable to allocate streaming EP\n"); + goto error; + } + uvc->video.ep = ep; + ++ uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; + uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; + uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; + +@@ -950,7 +966,8 @@ static void uvc_free(struct usb_function *f) + struct uvc_device *uvc = to_uvc(f); + struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts, + func_inst); +- config_item_put(&uvc->header->item); ++ if (!opts->header) ++ config_item_put(&uvc->header->item); + --opts->refcnt; + kfree(uvc); + } +@@ -1042,25 +1059,29 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) + uvc->desc.hs_streaming = opts->hs_streaming; + uvc->desc.ss_streaming = opts->ss_streaming; + +- streaming = config_group_find_item(&opts->func_inst.group, "streaming"); +- if (!streaming) +- goto err_config; +- +- header = config_group_find_item(to_config_group(streaming), "header"); +- config_item_put(streaming); +- if (!header) +- goto err_config; +- +- h = config_group_find_item(to_config_group(header), "h"); +- config_item_put(header); +- if (!h) +- goto err_config; +- +- uvc->header = to_uvcg_streaming_header(h); +- if (!uvc->header->linked) { +- mutex_unlock(&opts->lock); +- kfree(uvc); +- return ERR_PTR(-EBUSY); ++ if (opts->header) { ++ uvc->header = opts->header; ++ } else { ++ streaming = config_group_find_item(&opts->func_inst.group, "streaming"); ++ if (!streaming) ++ goto err_config; ++ ++ header = config_group_find_item(to_config_group(streaming), "header"); ++ config_item_put(streaming); ++ if (!header) ++ goto err_config; ++ ++ h = config_group_find_item(to_config_group(header), "h"); ++ config_item_put(header); ++ if (!h) ++ goto err_config; ++ ++ uvc->header = to_uvcg_streaming_header(h); ++ if (!uvc->header->linked) { ++ mutex_unlock(&opts->lock); ++ kfree(uvc); ++ return ERR_PTR(-EBUSY); ++ } + } + + uvc->desc.extension_units = &opts->extension_units; +diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h +index 1ce58f61253c9..3ac392cbb7794 100644 +--- a/drivers/usb/gadget/function/u_uvc.h ++++ b/drivers/usb/gadget/function/u_uvc.h +@@ -98,6 +98,12 @@ struct f_uvc_opts { + */ + struct mutex lock; + int refcnt; ++ ++ /* ++ * Only for legacy gadget. Shall be NULL for configfs-composed gadgets, ++ * which is guaranteed by alloc_inst implementation of f_uvc doing kzalloc. ++ */ ++ struct uvcg_streaming_header *header; + }; + + #endif /* U_UVC_H */ +diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c +index c06dd1af7a0c5..c395438d39780 100644 +--- a/drivers/usb/gadget/legacy/webcam.c ++++ b/drivers/usb/gadget/legacy/webcam.c +@@ -12,6 +12,7 @@ + #include + + #include "u_uvc.h" ++#include "uvc_configfs.h" + + USB_GADGET_COMPOSITE_OPTIONS(); + +@@ -84,8 +85,6 @@ static struct usb_device_descriptor webcam_device_descriptor = { + .bNumConfigurations = 0, /* dynamic */ + }; + +-DECLARE_UVC_HEADER_DESCRIPTOR(1); +- + static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { + .bLength = UVC_DT_HEADER_SIZE(1), + .bDescriptorType = USB_DT_CS_INTERFACE, +@@ -158,43 +157,112 @@ static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = { + .bmaControls[1][0] = 4, + }; + +-static const struct uvc_format_uncompressed uvc_format_yuv = { +- .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, +- .bDescriptorType = USB_DT_CS_INTERFACE, +- .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, +- .bFormatIndex = 1, +- .bNumFrameDescriptors = 2, +- .guidFormat = +- { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, +- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, +- .bBitsPerPixel = 16, +- .bDefaultFrameIndex = 1, +- .bAspectRatioX = 0, +- .bAspectRatioY = 0, +- .bmInterlaceFlags = 0, +- .bCopyProtect = 0, ++static const struct uvcg_color_matching uvcg_color_matching = { ++ .desc = { ++ .bLength = UVC_DT_COLOR_MATCHING_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_COLORFORMAT, ++ .bColorPrimaries = 1, ++ .bTransferCharacteristics = 1, ++ .bMatrixCoefficients = 4, ++ }, ++}; ++ ++static struct uvcg_uncompressed uvcg_format_yuv = { ++ .fmt = { ++ .type = UVCG_UNCOMPRESSED, ++ /* add to .frames and fill .num_frames at runtime */ ++ .color_matching = (struct uvcg_color_matching *)&uvcg_color_matching, ++ }, ++ .desc = { ++ .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, ++ .bFormatIndex = 1, ++ .bNumFrameDescriptors = 2, ++ .guidFormat = { ++ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ++ }, ++ .bBitsPerPixel = 16, ++ .bDefaultFrameIndex = 1, ++ .bAspectRatioX = 0, ++ .bAspectRatioY = 0, ++ .bmInterlaceFlags = 0, ++ .bCopyProtect = 0, ++ }, ++}; ++ ++static struct uvcg_format_ptr uvcg_format_ptr_yuv = { ++ .fmt = &uvcg_format_yuv.fmt, + }; + + DECLARE_UVC_FRAME_UNCOMPRESSED(1); + DECLARE_UVC_FRAME_UNCOMPRESSED(3); + ++#define UVCG_WIDTH_360P 640 ++#define UVCG_HEIGHT_360P 360 ++#define UVCG_MIN_BITRATE_360P 18432000 ++#define UVCG_MAX_BITRATE_360P 55296000 ++#define UVCG_MAX_VIDEO_FB_SZ_360P 460800 ++#define UVCG_FRM_INTERV_0_360P 666666 ++#define UVCG_FRM_INTERV_1_360P 1000000 ++#define UVCG_FRM_INTERV_2_360P 5000000 ++#define UVCG_DEFAULT_FRM_INTERV_360P UVCG_FRM_INTERV_0_360P ++ + static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { + .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, + .bFrameIndex = 1, + .bmCapabilities = 0, +- .wWidth = cpu_to_le16(640), +- .wHeight = cpu_to_le16(360), +- .dwMinBitRate = cpu_to_le32(18432000), +- .dwMaxBitRate = cpu_to_le32(55296000), +- .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), +- .dwDefaultFrameInterval = cpu_to_le32(666666), ++ .wWidth = cpu_to_le16(UVCG_WIDTH_360P), ++ .wHeight = cpu_to_le16(UVCG_HEIGHT_360P), ++ .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_360P), ++ .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_360P), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P), ++ .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P), + .bFrameIntervalType = 3, +- .dwFrameInterval[0] = cpu_to_le32(666666), +- .dwFrameInterval[1] = cpu_to_le32(1000000), +- .dwFrameInterval[2] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_360P), ++ .dwFrameInterval[1] = cpu_to_le32(UVCG_FRM_INTERV_1_360P), ++ .dwFrameInterval[2] = cpu_to_le32(UVCG_FRM_INTERV_2_360P), ++}; ++ ++static u32 uvcg_frame_yuv_360p_dw_frame_interval[] = { ++ [0] = UVCG_FRM_INTERV_0_360P, ++ [1] = UVCG_FRM_INTERV_1_360P, ++ [2] = UVCG_FRM_INTERV_2_360P, ++}; ++ ++static const struct uvcg_frame uvcg_frame_yuv_360p = { ++ .fmt_type = UVCG_UNCOMPRESSED, ++ .frame = { ++ .b_length = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), ++ .b_descriptor_type = USB_DT_CS_INTERFACE, ++ .b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED, ++ .b_frame_index = 1, ++ .bm_capabilities = 0, ++ .w_width = UVCG_WIDTH_360P, ++ .w_height = UVCG_HEIGHT_360P, ++ .dw_min_bit_rate = UVCG_MIN_BITRATE_360P, ++ .dw_max_bit_rate = UVCG_MAX_BITRATE_360P, ++ .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P, ++ .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_360P, ++ .b_frame_interval_type = 3, ++ }, ++ .dw_frame_interval = uvcg_frame_yuv_360p_dw_frame_interval, ++}; ++ ++static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_360p = { ++ .frm = (struct uvcg_frame *)&uvcg_frame_yuv_360p, + }; ++#define UVCG_WIDTH_720P 1280 ++#define UVCG_HEIGHT_720P 720 ++#define UVCG_MIN_BITRATE_720P 29491200 ++#define UVCG_MAX_BITRATE_720P 29491200 ++#define UVCG_MAX_VIDEO_FB_SZ_720P 1843200 ++#define UVCG_FRM_INTERV_0_720P 5000000 ++#define UVCG_DEFAULT_FRM_INTERV_720P UVCG_FRM_INTERV_0_720P + + static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { + .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), +@@ -202,28 +270,66 @@ static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { + .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, + .bFrameIndex = 2, + .bmCapabilities = 0, +- .wWidth = cpu_to_le16(1280), +- .wHeight = cpu_to_le16(720), +- .dwMinBitRate = cpu_to_le32(29491200), +- .dwMaxBitRate = cpu_to_le32(29491200), +- .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), +- .dwDefaultFrameInterval = cpu_to_le32(5000000), ++ .wWidth = cpu_to_le16(UVCG_WIDTH_720P), ++ .wHeight = cpu_to_le16(UVCG_HEIGHT_720P), ++ .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_720P), ++ .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_720P), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P), ++ .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P), + .bFrameIntervalType = 1, +- .dwFrameInterval[0] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_720P), + }; + +-static const struct uvc_format_mjpeg uvc_format_mjpg = { +- .bLength = UVC_DT_FORMAT_MJPEG_SIZE, +- .bDescriptorType = USB_DT_CS_INTERFACE, +- .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, +- .bFormatIndex = 2, +- .bNumFrameDescriptors = 2, +- .bmFlags = 0, +- .bDefaultFrameIndex = 1, +- .bAspectRatioX = 0, +- .bAspectRatioY = 0, +- .bmInterlaceFlags = 0, +- .bCopyProtect = 0, ++static u32 uvcg_frame_yuv_720p_dw_frame_interval[] = { ++ [0] = UVCG_FRM_INTERV_0_720P, ++}; ++ ++static const struct uvcg_frame uvcg_frame_yuv_720p = { ++ .fmt_type = UVCG_UNCOMPRESSED, ++ .frame = { ++ .b_length = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), ++ .b_descriptor_type = USB_DT_CS_INTERFACE, ++ .b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED, ++ .b_frame_index = 2, ++ .bm_capabilities = 0, ++ .w_width = UVCG_WIDTH_720P, ++ .w_height = UVCG_HEIGHT_720P, ++ .dw_min_bit_rate = UVCG_MIN_BITRATE_720P, ++ .dw_max_bit_rate = UVCG_MAX_BITRATE_720P, ++ .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P, ++ .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_720P, ++ .b_frame_interval_type = 1, ++ }, ++ .dw_frame_interval = uvcg_frame_yuv_720p_dw_frame_interval, ++}; ++ ++static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_720p = { ++ .frm = (struct uvcg_frame *)&uvcg_frame_yuv_720p, ++}; ++ ++static struct uvcg_mjpeg uvcg_format_mjpeg = { ++ .fmt = { ++ .type = UVCG_MJPEG, ++ /* add to .frames and fill .num_frames at runtime */ ++ .color_matching = (struct uvcg_color_matching *)&uvcg_color_matching, ++ }, ++ .desc = { ++ .bLength = UVC_DT_FORMAT_MJPEG_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, ++ .bFormatIndex = 2, ++ .bNumFrameDescriptors = 2, ++ .bmFlags = 0, ++ .bDefaultFrameIndex = 1, ++ .bAspectRatioX = 0, ++ .bAspectRatioY = 0, ++ .bmInterlaceFlags = 0, ++ .bCopyProtect = 0, ++ }, ++}; ++ ++static struct uvcg_format_ptr uvcg_format_ptr_mjpeg = { ++ .fmt = &uvcg_format_mjpeg.fmt, + }; + + DECLARE_UVC_FRAME_MJPEG(1); +@@ -235,16 +341,45 @@ static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { + .bDescriptorSubType = UVC_VS_FRAME_MJPEG, + .bFrameIndex = 1, + .bmCapabilities = 0, +- .wWidth = cpu_to_le16(640), +- .wHeight = cpu_to_le16(360), +- .dwMinBitRate = cpu_to_le32(18432000), +- .dwMaxBitRate = cpu_to_le32(55296000), +- .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), +- .dwDefaultFrameInterval = cpu_to_le32(666666), ++ .wWidth = cpu_to_le16(UVCG_WIDTH_360P), ++ .wHeight = cpu_to_le16(UVCG_HEIGHT_360P), ++ .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_360P), ++ .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_360P), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P), ++ .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P), + .bFrameIntervalType = 3, +- .dwFrameInterval[0] = cpu_to_le32(666666), +- .dwFrameInterval[1] = cpu_to_le32(1000000), +- .dwFrameInterval[2] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_360P), ++ .dwFrameInterval[1] = cpu_to_le32(UVCG_FRM_INTERV_1_360P), ++ .dwFrameInterval[2] = cpu_to_le32(UVCG_FRM_INTERV_2_360P), ++}; ++ ++static u32 uvcg_frame_mjpeg_360p_dw_frame_interval[] = { ++ [0] = UVCG_FRM_INTERV_0_360P, ++ [1] = UVCG_FRM_INTERV_1_360P, ++ [2] = UVCG_FRM_INTERV_2_360P, ++}; ++ ++static const struct uvcg_frame uvcg_frame_mjpeg_360p = { ++ .fmt_type = UVCG_MJPEG, ++ .frame = { ++ .b_length = UVC_DT_FRAME_MJPEG_SIZE(3), ++ .b_descriptor_type = USB_DT_CS_INTERFACE, ++ .b_descriptor_subtype = UVC_VS_FRAME_MJPEG, ++ .b_frame_index = 1, ++ .bm_capabilities = 0, ++ .w_width = UVCG_WIDTH_360P, ++ .w_height = UVCG_HEIGHT_360P, ++ .dw_min_bit_rate = UVCG_MIN_BITRATE_360P, ++ .dw_max_bit_rate = UVCG_MAX_BITRATE_360P, ++ .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P, ++ .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_360P, ++ .b_frame_interval_type = 3, ++ }, ++ .dw_frame_interval = uvcg_frame_mjpeg_360p_dw_frame_interval, ++}; ++ ++static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_360p = { ++ .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_360p, + }; + + static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { +@@ -253,23 +388,44 @@ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { + .bDescriptorSubType = UVC_VS_FRAME_MJPEG, + .bFrameIndex = 2, + .bmCapabilities = 0, +- .wWidth = cpu_to_le16(1280), +- .wHeight = cpu_to_le16(720), +- .dwMinBitRate = cpu_to_le32(29491200), +- .dwMaxBitRate = cpu_to_le32(29491200), +- .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), +- .dwDefaultFrameInterval = cpu_to_le32(5000000), ++ .wWidth = cpu_to_le16(UVCG_WIDTH_720P), ++ .wHeight = cpu_to_le16(UVCG_HEIGHT_720P), ++ .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_720P), ++ .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_720P), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P), ++ .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P), + .bFrameIntervalType = 1, +- .dwFrameInterval[0] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_720P), + }; + +-static const struct uvc_color_matching_descriptor uvc_color_matching = { +- .bLength = UVC_DT_COLOR_MATCHING_SIZE, +- .bDescriptorType = USB_DT_CS_INTERFACE, +- .bDescriptorSubType = UVC_VS_COLORFORMAT, +- .bColorPrimaries = 1, +- .bTransferCharacteristics = 1, +- .bMatrixCoefficients = 4, ++static u32 uvcg_frame_mjpeg_720p_dw_frame_interval[] = { ++ [0] = UVCG_FRM_INTERV_0_720P, ++}; ++ ++static const struct uvcg_frame uvcg_frame_mjpeg_720p = { ++ .fmt_type = UVCG_MJPEG, ++ .frame = { ++ .b_length = UVC_DT_FRAME_MJPEG_SIZE(1), ++ .b_descriptor_type = USB_DT_CS_INTERFACE, ++ .b_descriptor_subtype = UVC_VS_FRAME_MJPEG, ++ .b_frame_index = 2, ++ .bm_capabilities = 0, ++ .w_width = UVCG_WIDTH_720P, ++ .w_height = UVCG_HEIGHT_720P, ++ .dw_min_bit_rate = UVCG_MIN_BITRATE_720P, ++ .dw_max_bit_rate = UVCG_MAX_BITRATE_720P, ++ .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P, ++ .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_720P, ++ .b_frame_interval_type = 1, ++ }, ++ .dw_frame_interval = uvcg_frame_mjpeg_720p_dw_frame_interval, ++}; ++ ++static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_720p = { ++ .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_720p, ++}; ++ ++static struct uvcg_streaming_header uvcg_streaming_header = { + }; + + static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { +@@ -290,40 +446,40 @@ static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { + + static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = { + (const struct uvc_descriptor_header *) &uvc_input_header, +- (const struct uvc_descriptor_header *) &uvc_format_yuv, ++ (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, +- (const struct uvc_descriptor_header *) &uvc_format_mjpg, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, ++ (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + NULL, + }; + + static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { + (const struct uvc_descriptor_header *) &uvc_input_header, +- (const struct uvc_descriptor_header *) &uvc_format_yuv, ++ (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, +- (const struct uvc_descriptor_header *) &uvc_format_mjpg, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, ++ (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + NULL, + }; + + static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { + (const struct uvc_descriptor_header *) &uvc_input_header, +- (const struct uvc_descriptor_header *) &uvc_format_yuv, ++ (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, +- (const struct uvc_descriptor_header *) &uvc_format_mjpg, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, ++ (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, +- (const struct uvc_descriptor_header *) &uvc_color_matching, ++ (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + NULL, + }; + +@@ -387,6 +543,23 @@ webcam_bind(struct usb_composite_dev *cdev) + uvc_opts->hs_streaming = uvc_hs_streaming_cls; + uvc_opts->ss_streaming = uvc_ss_streaming_cls; + ++ INIT_LIST_HEAD(&uvcg_format_yuv.fmt.frames); ++ list_add_tail(&uvcg_frame_ptr_yuv_360p.entry, &uvcg_format_yuv.fmt.frames); ++ list_add_tail(&uvcg_frame_ptr_yuv_720p.entry, &uvcg_format_yuv.fmt.frames); ++ uvcg_format_yuv.fmt.num_frames = 2; ++ ++ INIT_LIST_HEAD(&uvcg_format_mjpeg.fmt.frames); ++ list_add_tail(&uvcg_frame_ptr_mjpeg_360p.entry, &uvcg_format_mjpeg.fmt.frames); ++ list_add_tail(&uvcg_frame_ptr_mjpeg_720p.entry, &uvcg_format_mjpeg.fmt.frames); ++ uvcg_format_mjpeg.fmt.num_frames = 2; ++ ++ INIT_LIST_HEAD(&uvcg_streaming_header.formats); ++ list_add_tail(&uvcg_format_ptr_yuv.entry, &uvcg_streaming_header.formats); ++ list_add_tail(&uvcg_format_ptr_mjpeg.entry, &uvcg_streaming_header.formats); ++ uvcg_streaming_header.num_fmt = 2; ++ ++ uvc_opts->header = &uvcg_streaming_header; ++ + /* Allocate string descriptor numbers ... note that string contents + * can be overridden by the composite_dev glue. + */ +diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c +index bbdf1b0b7be11..3252e3d2d79cd 100644 +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -7,6 +7,7 @@ + * Chunfeng Yun + */ + ++#include + #include + #include + #include +@@ -73,6 +74,9 @@ + #define FRMCNT_LEV1_RANG (0x12b << 8) + #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8) + ++#define HSCH_CFG1 0x960 ++#define SCH3_RXFIFO_DEPTH_MASK GENMASK(21, 20) ++ + #define SS_GEN2_EOF_CFG 0x990 + #define SSG2EOF_OFFSET 0x3c + +@@ -114,6 +118,8 @@ + #define SSC_IP_SLEEP_EN BIT(4) + #define SSC_SPM_INT_EN BIT(1) + ++#define SCH_FIFO_TO_KB(x) ((x) >> 10) ++ + enum ssusb_uwk_vers { + SSUSB_UWK_V1 = 1, + SSUSB_UWK_V2, +@@ -165,6 +171,35 @@ static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk) + writel(value, hcd->regs + SS_GEN2_EOF_CFG); + } + ++/* ++ * workaround: usb3.2 gen1 isoc rx hw issue ++ * host send out unexpected ACK afer device fininsh a burst transfer with ++ * a short packet. ++ */ ++static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) ++{ ++ struct usb_hcd *hcd = mtk->hcd; ++ u32 value; ++ ++ if (!mtk->rxfifo_depth) ++ return; ++ ++ value = readl(hcd->regs + HSCH_CFG1); ++ value &= ~SCH3_RXFIFO_DEPTH_MASK; ++ value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK, ++ SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); ++ writel(value, hcd->regs + HSCH_CFG1); ++} ++ ++static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) ++{ ++ /* workaround only for mt8195 */ ++ xhci_mtk_set_frame_interval(mtk); ++ ++ /* workaround for SoCs using SSUSB about before IPM v1.6.0 */ ++ xhci_mtk_rxfifo_depth_set(mtk); ++} ++ + static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) + { + struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; +@@ -448,8 +483,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd) + if (ret) + return ret; + +- /* workaround only for mt8195 */ +- xhci_mtk_set_frame_interval(mtk); ++ xhci_mtk_init_quirk(mtk); + } + + ret = xhci_gen_setup(hcd, xhci_mtk_quirks); +@@ -527,6 +561,8 @@ static int xhci_mtk_probe(struct platform_device *pdev) + of_property_read_u32(node, "mediatek,u2p-dis-msk", + &mtk->u2p_dis_msk); + ++ of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth); ++ + ret = usb_wakeup_of_property_parse(mtk, node); + if (ret) { + dev_err(dev, "failed to parse uwk property\n"); +diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h +index faaaf05e36ce0..ac042077db8c1 100644 +--- a/drivers/usb/host/xhci-mtk.h ++++ b/drivers/usb/host/xhci-mtk.h +@@ -160,6 +160,8 @@ struct xhci_hcd_mtk { + struct regmap *uwk; + u32 uwk_reg_base; + u32 uwk_vers; ++ /* quirk */ ++ u32 rxfifo_depth; + }; + + static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) +diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c +index 9ca9305243fe5..4e30de4db1c0a 100644 +--- a/drivers/usb/mon/mon_bin.c ++++ b/drivers/usb/mon/mon_bin.c +@@ -1250,14 +1250,19 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf) + struct mon_reader_bin *rp = vmf->vma->vm_private_data; + unsigned long offset, chunk_idx; + struct page *pageptr; ++ unsigned long flags; + ++ spin_lock_irqsave(&rp->b_lock, flags); + offset = vmf->pgoff << PAGE_SHIFT; +- if (offset >= rp->b_size) ++ if (offset >= rp->b_size) { ++ spin_unlock_irqrestore(&rp->b_lock, flags); + return VM_FAULT_SIGBUS; ++ } + chunk_idx = offset / CHUNK_SIZE; + pageptr = rp->b_vec[chunk_idx].pg; + get_page(pageptr); + vmf->page = pageptr; ++ spin_unlock_irqrestore(&rp->b_lock, flags); + return 0; + } + +diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c +index acd46b72899e9..920a32cd094d6 100644 +--- a/drivers/usb/phy/phy-mxs-usb.c ++++ b/drivers/usb/phy/phy-mxs-usb.c +@@ -388,8 +388,7 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) + + static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) + { +- return IS_ENABLED(CONFIG_USB_OTG) && +- mxs_phy->phy.last_event == USB_EVENT_ID; ++ return mxs_phy->phy.last_event == USB_EVENT_ID; + } + + static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) +diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c +index 6e80fab11788c..41382b1e29075 100644 +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -262,11 +262,13 @@ static void typec_altmode_put_partner(struct altmode *altmode) + { + struct altmode *partner = altmode->partner; + struct typec_altmode *adev; ++ struct typec_altmode *partner_adev; + + if (!partner) + return; + + adev = &altmode->adev; ++ partner_adev = &partner->adev; + + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); +@@ -275,7 +277,7 @@ static void typec_altmode_put_partner(struct altmode *altmode) + } else { + partner->partner = NULL; + } +- put_device(&adev->dev); ++ put_device(&partner_adev->dev); + } + + /** +diff --git a/drivers/vdpa/alibaba/eni_vdpa.c b/drivers/vdpa/alibaba/eni_vdpa.c +index 5a09a09cca709..cce3d1837104c 100644 +--- a/drivers/vdpa/alibaba/eni_vdpa.c ++++ b/drivers/vdpa/alibaba/eni_vdpa.c +@@ -497,7 +497,7 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (!eni_vdpa->vring) { + ret = -ENOMEM; + ENI_ERR(pdev, "failed to allocate virtqueues\n"); +- goto err; ++ goto err_remove_vp_legacy; + } + + for (i = 0; i < eni_vdpa->queues; i++) { +@@ -509,11 +509,13 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ret = vdpa_register_device(&eni_vdpa->vdpa, eni_vdpa->queues); + if (ret) { + ENI_ERR(pdev, "failed to register to vdpa bus\n"); +- goto err; ++ goto err_remove_vp_legacy; + } + + return 0; + ++err_remove_vp_legacy: ++ vp_legacy_remove(&eni_vdpa->ldev); + err: + put_device(&eni_vdpa->vdpa.dev); + return ret; +diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +index b2f9778c8366e..4d27465c8f1a8 100644 +--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c ++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +@@ -694,6 +694,7 @@ static ssize_t hisi_acc_vf_resume_write(struct file *filp, const char __user *bu + size_t len, loff_t *pos) + { + struct hisi_acc_vf_migration_file *migf = filp->private_data; ++ u8 *vf_data = (u8 *)&migf->vf_data; + loff_t requested_length; + ssize_t done = 0; + int ret; +@@ -715,7 +716,7 @@ static ssize_t hisi_acc_vf_resume_write(struct file *filp, const char __user *bu + goto out_unlock; + } + +- ret = copy_from_user(&migf->vf_data, buf, len); ++ ret = copy_from_user(vf_data + *pos, buf, len); + if (ret) { + done = -EFAULT; + goto out_unlock; +@@ -835,7 +836,9 @@ static ssize_t hisi_acc_vf_save_read(struct file *filp, char __user *buf, size_t + + len = min_t(size_t, migf->total_length - *pos, len); + if (len) { +- ret = copy_to_user(buf, &migf->vf_data, len); ++ u8 *vf_data = (u8 *)&migf->vf_data; ++ ++ ret = copy_to_user(buf, vf_data + *pos, len); + if (ret) { + done = -EFAULT; + goto out_unlock; +diff --git a/drivers/vfio/pci/pds/dirty.c b/drivers/vfio/pci/pds/dirty.c +index c937aa6f39546..27607d7b9030a 100644 +--- a/drivers/vfio/pci/pds/dirty.c ++++ b/drivers/vfio/pci/pds/dirty.c +@@ -478,8 +478,7 @@ static int pds_vfio_dirty_sync(struct pds_vfio_pci_device *pds_vfio, + pds_vfio->vf_id, iova, length, pds_vfio->dirty.region_page_size, + pages, bitmap_size); + +- if (!length || ((dirty->region_start + iova + length) > +- (dirty->region_start + dirty->region_size))) { ++ if (!length || ((iova - dirty->region_start + length) > dirty->region_size)) { + dev_err(dev, "Invalid iova 0x%lx and/or length 0x%lx to sync\n", + iova, length); + return -EINVAL; +@@ -496,7 +495,8 @@ static int pds_vfio_dirty_sync(struct pds_vfio_pci_device *pds_vfio, + return -EINVAL; + } + +- bmp_offset = DIV_ROUND_UP(iova / dirty->region_page_size, sizeof(u64)); ++ bmp_offset = DIV_ROUND_UP((iova - dirty->region_start) / ++ dirty->region_page_size, sizeof(u64)); + + dev_dbg(dev, + "Syncing dirty bitmap, iova 0x%lx length 0x%lx, bmp_offset %llu bmp_bytes %llu\n", +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index 817d377a3f360..61255855d4906 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -438,6 +438,7 @@ static struct virtio_transport vhost_transport = { + .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue, + .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue, + .notify_buffer_size = virtio_transport_notify_buffer_size, ++ .notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat, + + .read_skb = virtio_transport_read_skb, + }, +diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c +index 163d2c9f951c3..f0600f6ca2548 100644 +--- a/drivers/video/fbdev/acornfb.c ++++ b/drivers/video/fbdev/acornfb.c +@@ -605,7 +605,7 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) + + static const struct fb_ops acornfb_ops = { + .owner = THIS_MODULE, +- FB_IOMEM_DEFAULT_OPS, ++ FB_DEFAULT_IOMEM_OPS, + .fb_check_var = acornfb_check_var, + .fb_set_par = acornfb_set_par, + .fb_setcolreg = acornfb_setcolreg, +diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c +index 274f5d0fa2471..1ae1d35a59423 100644 +--- a/drivers/video/fbdev/core/fb_defio.c ++++ b/drivers/video/fbdev/core/fb_defio.c +@@ -132,11 +132,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy + return 0; + + inode_lock(inode); +- /* Kill off the delayed work */ +- cancel_delayed_work_sync(&info->deferred_work); +- +- /* Run it immediately */ +- schedule_delayed_work(&info->deferred_work, 0); ++ flush_delayed_work(&info->deferred_work); + inode_unlock(inode); + + return 0; +@@ -317,7 +313,7 @@ static void fb_deferred_io_lastclose(struct fb_info *info) + struct page *page; + int i; + +- cancel_delayed_work_sync(&info->deferred_work); ++ flush_delayed_work(&info->deferred_work); + + /* clear out the mapping that we setup */ + for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { +diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c +index 84201c9608d36..7042a43b81d85 100644 +--- a/drivers/video/fbdev/imxfb.c ++++ b/drivers/video/fbdev/imxfb.c +@@ -42,6 +42,7 @@ + #include