diff --git a/patch/kernel/odroidxu4-current/patch-5.4.88-89.patch b/patch/kernel/odroidxu4-current/patch-5.4.88-89.patch new file mode 100644 index 0000000000..bcf2d61f38 --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-5.4.88-89.patch @@ -0,0 +1,2852 @@ +diff --git a/Makefile b/Makefile +index 450ebe1528062..95848875110ef 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 88 ++SUBLEVEL = 89 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +@@ -436,7 +436,7 @@ LEX = flex + YACC = bison + AWK = awk + INSTALLKERNEL := installkernel +-DEPMOD = /sbin/depmod ++DEPMOD = depmod + PERL = perl + PYTHON = python + PYTHON3 = python3 +diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S +index 5229eeac8946d..4def51c12e1bf 100644 +--- a/arch/powerpc/kernel/vmlinux.lds.S ++++ b/arch/powerpc/kernel/vmlinux.lds.S +@@ -98,7 +98,7 @@ SECTIONS + ALIGN_FUNCTION(); + #endif + /* careful! __ftr_alt_* sections need to be close to .text */ +- *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); ++ *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); + #ifdef CONFIG_PPC64 + *(.tramp.ftrace.text); + #endif +diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c +index aa5c064a6a227..4ea906fe1c351 100644 +--- a/arch/x86/kernel/cpu/mtrr/generic.c ++++ b/arch/x86/kernel/cpu/mtrr/generic.c +@@ -167,9 +167,6 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, + *repeat = 0; + *uniform = 1; + +- /* Make end inclusive instead of exclusive */ +- end--; +- + prev_match = MTRR_TYPE_INVALID; + for (i = 0; i < num_var_ranges; ++i) { + unsigned short start_state, end_state, inclusive; +@@ -261,6 +258,9 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform) + int repeat; + u64 partial_end; + ++ /* Make end inclusive instead of exclusive */ ++ end--; ++ + if (!mtrr_state_set) + return MTRR_TYPE_INVALID; + +diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h +index 6f2208cf30df3..ea9945a05b831 100644 +--- a/arch/x86/kvm/mmu.h ++++ b/arch/x86/kvm/mmu.h +@@ -48,7 +48,7 @@ static inline u64 rsvd_bits(int s, int e) + if (e < s) + return 0; + +- return ((1ULL << (e - s + 1)) - 1) << s; ++ return ((2ULL << (e - s)) - 1) << s; + } + + void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask, u64 mmio_value, u64 access_mask); +diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c +index 7bd2c3a52297f..7982f13807aa0 100644 +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -826,6 +826,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) + } + + free_page((unsigned long)pmd_sv); ++ ++ pgtable_pmd_page_dtor(virt_to_page(pmd)); + free_page((unsigned long)pmd); + + return 1; +diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c +index 5154e280ada22..08baa10a254bf 100644 +--- a/crypto/asymmetric_keys/asym_tpm.c ++++ b/crypto/asymmetric_keys/asym_tpm.c +@@ -370,7 +370,7 @@ static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf) + memcpy(cur, e, sizeof(e)); + cur += sizeof(e); + /* Zero parameters to satisfy set_pub_key ABI. */ +- memset(cur, 0, SETKEY_PARAMS_SIZE); ++ memzero_explicit(cur, SETKEY_PARAMS_SIZE); + + return cur - buf; + } +diff --git a/crypto/ecdh.c b/crypto/ecdh.c +index efa4ee72301f8..46570b517175a 100644 +--- a/crypto/ecdh.c ++++ b/crypto/ecdh.c +@@ -39,7 +39,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, + struct ecdh params; + unsigned int ndigits; + +- if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0) ++ if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0 || ++ params.key_size > sizeof(ctx->private_key)) + return -EINVAL; + + ndigits = ecdh_supported_curve(params.curve_id); +diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c +index df51680e89319..363073e7b6538 100644 +--- a/drivers/atm/idt77252.c ++++ b/drivers/atm/idt77252.c +@@ -3606,7 +3606,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, + + if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { + printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); +- return err; ++ goto err_out_disable_pdev; + } + + card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); +diff --git a/drivers/base/core.c b/drivers/base/core.c +index ddfbd62d8bfc2..c5edb00938f69 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -3414,7 +3414,7 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) + if (fwnode_is_primary(fn)) { + dev->fwnode = fn->secondary; + if (!(parent && fn == parent->fwnode)) +- fn->secondary = ERR_PTR(-ENODEV); ++ fn->secondary = NULL; + } else { + dev->fwnode = NULL; + } +diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c +index 17b0f1b793ec8..e11af747395dd 100644 +--- a/drivers/bluetooth/hci_h5.c ++++ b/drivers/bluetooth/hci_h5.c +@@ -250,12 +250,8 @@ static int h5_close(struct hci_uart *hu) + if (h5->vnd && h5->vnd->close) + h5->vnd->close(h5); + +- if (hu->serdev) +- serdev_device_close(hu->serdev); +- +- kfree_skb(h5->rx_skb); +- kfree(h5); +- h5 = NULL; ++ if (!hu->serdev) ++ kfree(h5); + + return 0; + } +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index f6df6ef1b0fbe..758de0e9b2ddc 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry) + + dmabuf->ops->release(dmabuf); + +- mutex_lock(&db_list.lock); +- list_del(&dmabuf->list_node); +- mutex_unlock(&db_list.lock); +- + if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) + dma_resv_fini(dmabuf->resv); + +@@ -88,6 +84,22 @@ static void dma_buf_release(struct dentry *dentry) + kfree(dmabuf); + } + ++static int dma_buf_file_release(struct inode *inode, struct file *file) ++{ ++ struct dma_buf *dmabuf; ++ ++ if (!is_dma_buf_file(file)) ++ return -EINVAL; ++ ++ dmabuf = file->private_data; ++ ++ mutex_lock(&db_list.lock); ++ list_del(&dmabuf->list_node); ++ mutex_unlock(&db_list.lock); ++ ++ return 0; ++} ++ + static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +@@ -413,6 +425,7 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) + } + + static const struct file_operations dma_buf_fops = { ++ .release = dma_buf_file_release, + .mmap = dma_buf_mmap_internal, + .llseek = dma_buf_llseek, + .poll = dma_buf_poll, +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +index 7f7d59445faed..198a91c765314 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +@@ -936,7 +936,7 @@ static void reloc_gpu_flush(struct reloc_cache *cache) + GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); + cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; + +- __i915_gem_object_flush_map(obj, 0, sizeof(u32) * (cache->rq_size + 1)); ++ i915_gem_object_flush_map(obj); + i915_gem_object_unpin_map(obj); + + intel_gt_chipset_flush(cache->rq->engine->gt); +@@ -1163,6 +1163,8 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, + goto out_pool; + } + ++ memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); ++ + batch = i915_vma_instance(pool->obj, vma->vm, NULL); + if (IS_ERR(batch)) { + err = PTR_ERR(batch); +diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c +index 80bc3bf82f4d7..775fd34132abb 100644 +--- a/drivers/ide/ide-atapi.c ++++ b/drivers/ide/ide-atapi.c +@@ -223,7 +223,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) + sense_rq->rq_disk = rq->rq_disk; + sense_rq->cmd_flags = REQ_OP_DRV_IN; + ide_req(sense_rq)->type = ATA_PRIV_SENSE; +- sense_rq->rq_flags |= RQF_PREEMPT; + + req->cmd[0] = GPCMD_REQUEST_SENSE; + req->cmd[4] = cmd_len; +diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c +index b137f27a34d58..b32a013d827a0 100644 +--- a/drivers/ide/ide-io.c ++++ b/drivers/ide/ide-io.c +@@ -512,11 +512,6 @@ repeat: + * above to return us whatever is in the queue. Since we call + * ide_do_request() ourselves, we end up taking requests while + * the queue is blocked... +- * +- * We let requests forced at head of queue with ide-preempt +- * though. I hope that doesn't happen too much, hopefully not +- * unless the subdriver triggers such a thing in its own PM +- * state machine. + */ + if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && + ata_pm_request(rq) == 0 && +diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c +index ef5d5cc529693..0d9b3fa7bd94e 100644 +--- a/drivers/net/dsa/lantiq_gswip.c ++++ b/drivers/net/dsa/lantiq_gswip.c +@@ -92,9 +92,7 @@ + GSWIP_MDIO_PHY_FDUP_MASK) + + /* GSWIP MII Registers */ +-#define GSWIP_MII_CFG0 0x00 +-#define GSWIP_MII_CFG1 0x02 +-#define GSWIP_MII_CFG5 0x04 ++#define GSWIP_MII_CFGp(p) (0x2 * (p)) + #define GSWIP_MII_CFG_EN BIT(14) + #define GSWIP_MII_CFG_LDCLKDIS BIT(12) + #define GSWIP_MII_CFG_MODE_MIIP 0x0 +@@ -392,17 +390,9 @@ static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set, + static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, + int port) + { +- switch (port) { +- case 0: +- gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG0); +- break; +- case 1: +- gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG1); +- break; +- case 5: +- gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG5); +- break; +- } ++ /* There's no MII_CFG register for the CPU port */ ++ if (!dsa_is_cpu_port(priv->ds, port)) ++ gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port)); + } + + static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set, +@@ -806,9 +796,8 @@ static int gswip_setup(struct dsa_switch *ds) + gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); + + /* Disable the xMII link */ +- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 0); +- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 1); +- gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 5); ++ for (i = 0; i < priv->hw_info->max_ports; i++) ++ gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i); + + /* enable special tag insertion on cpu port */ + gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, +@@ -1522,9 +1511,7 @@ static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, + { + struct gswip_priv *priv = ds->priv; + +- /* Enable the xMII interface only for the external PHY */ +- if (interface != PHY_INTERFACE_MODE_INTERNAL) +- gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); ++ gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); + } + + static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset, +diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c +index 71eb8914e620b..470d12e308814 100644 +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -2520,6 +2520,7 @@ static int bcm_sysport_probe(struct platform_device *pdev) + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + dev->hw_features |= dev->features; + dev->vlan_features |= dev->features; ++ dev->max_mtu = UMAC_MAX_MTU_SIZE; + + /* Request the WOL interrupt and advertise suspend if available */ + priv->wol_irq_disabled = 1; +diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c +index ea4f17f5cce77..590d20ca891cb 100644 +--- a/drivers/net/ethernet/ethoc.c ++++ b/drivers/net/ethernet/ethoc.c +@@ -1207,7 +1207,7 @@ static int ethoc_probe(struct platform_device *pdev) + ret = mdiobus_register(priv->mdio); + if (ret) { + dev_err(&netdev->dev, "failed to register MDIO bus\n"); +- goto free2; ++ goto free3; + } + + ret = ethoc_mdio_probe(netdev); +@@ -1239,6 +1239,7 @@ error2: + netif_napi_del(&priv->napi); + error: + mdiobus_unregister(priv->mdio); ++free3: + mdiobus_free(priv->mdio); + free2: + clk_disable_unprepare(priv->clk); +diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c +index d3b8ce734c1b9..beaf35c585d28 100644 +--- a/drivers/net/ethernet/freescale/ucc_geth.c ++++ b/drivers/net/ethernet/freescale/ucc_geth.c +@@ -3890,6 +3890,7 @@ static int ucc_geth_probe(struct platform_device* ofdev) + INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); + netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); + dev->mtu = 1500; ++ dev->max_mtu = 1518; + + ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); + ugeth->phy_interface = phy_interface; +@@ -3935,12 +3936,12 @@ static int ucc_geth_remove(struct platform_device* ofdev) + struct device_node *np = ofdev->dev.of_node; + + unregister_netdev(dev); +- free_netdev(dev); + ucc_geth_memclean(ugeth); + if (of_phy_is_fixed_link(np)) + of_phy_deregister_fixed_link(np); + of_node_put(ugeth->ug_info->tbi_node); + of_node_put(ugeth->ug_info->phy_node); ++ free_netdev(dev); + + return 0; + } +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +index 717fccc2efba9..78b2f4e01bd8e 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +@@ -415,6 +415,10 @@ static void __lb_other_process(struct hns_nic_ring_data *ring_data, + /* for mutl buffer*/ + new_skb = skb_copy(skb, GFP_ATOMIC); + dev_kfree_skb_any(skb); ++ if (!new_skb) { ++ netdev_err(ndev, "skb alloc failed\n"); ++ return; ++ } + skb = new_skb; + + check_ok = 0; +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 47b8ce7822c09..9040340fad198 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -2152,8 +2152,7 @@ static void __ibmvnic_reset(struct work_struct *work) + rc = do_hard_reset(adapter, rwi, reset_state); + rtnl_unlock(); + } +- } else if (!(rwi->reset_reason == VNIC_RESET_FATAL && +- adapter->from_passive_init)) { ++ } else { + rc = do_reset(adapter, rwi, reset_state); + } + kfree(rwi); +diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h +index cfe99bae8e362..678e4190b8a8c 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e.h ++++ b/drivers/net/ethernet/intel/i40e/i40e.h +@@ -129,6 +129,7 @@ enum i40e_state_t { + __I40E_RESET_INTR_RECEIVED, + __I40E_REINIT_REQUESTED, + __I40E_PF_RESET_REQUESTED, ++ __I40E_PF_RESET_AND_REBUILD_REQUESTED, + __I40E_CORE_RESET_REQUESTED, + __I40E_GLOBAL_RESET_REQUESTED, + __I40E_EMP_RESET_INTR_RECEIVED, +@@ -156,6 +157,8 @@ enum i40e_state_t { + }; + + #define I40E_PF_RESET_FLAG BIT_ULL(__I40E_PF_RESET_REQUESTED) ++#define I40E_PF_RESET_AND_REBUILD_FLAG \ ++ BIT_ULL(__I40E_PF_RESET_AND_REBUILD_REQUESTED) + + /* VSI state flags */ + enum i40e_vsi_state_t { +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 2b4327416457d..c19b45a90fcd2 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -44,6 +44,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf); + static void i40e_determine_queue_usage(struct i40e_pf *pf); + static int i40e_setup_pf_filter_control(struct i40e_pf *pf); + static void i40e_prep_for_reset(struct i40e_pf *pf, bool lock_acquired); ++static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit, ++ bool lock_acquired); + static int i40e_reset(struct i40e_pf *pf); + static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); + static int i40e_setup_misc_vector_for_recovery_mode(struct i40e_pf *pf); +@@ -8484,6 +8486,14 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired) + "FW LLDP is disabled\n" : + "FW LLDP is enabled\n"); + ++ } else if (reset_flags & I40E_PF_RESET_AND_REBUILD_FLAG) { ++ /* Request a PF Reset ++ * ++ * Resets PF and reinitializes PFs VSI. ++ */ ++ i40e_prep_for_reset(pf, lock_acquired); ++ i40e_reset_and_rebuild(pf, true, lock_acquired); ++ + } else if (reset_flags & BIT_ULL(__I40E_REINIT_REQUESTED)) { + int v; + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 09ff3f335ffa6..c952212900fcf 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -1704,7 +1704,7 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) + if (num_vfs) { + if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { + pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; +- i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); ++ i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); + } + ret = i40e_pci_sriov_enable(pdev, num_vfs); + goto sriov_configure_out; +@@ -1713,7 +1713,7 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs) + if (!pci_vfs_assigned(pf->pdev)) { + i40e_free_vfs(pf); + pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; +- i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); ++ i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); + } else { + dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); + ret = -EINVAL; +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index cd95d6af8fc1b..56e6bec9af797 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1844,11 +1844,9 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter) + netif_tx_stop_all_queues(netdev); + if (CLIENT_ALLOWED(adapter)) { + err = iavf_lan_add_device(adapter); +- if (err) { +- rtnl_unlock(); ++ if (err) + dev_info(&pdev->dev, "Failed to add VF to client API service list: %d\n", + err); +- } + } + dev_info(&pdev->dev, "MAC address: %pM\n", adapter->hw.mac.addr); + if (netdev->features & NETIF_F_GRO) +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index ccb2abd18d6c7..94e3f8b869be4 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -4694,7 +4694,7 @@ static int mvneta_probe(struct platform_device *pdev) + err = mvneta_port_power_up(pp, pp->phy_interface); + if (err < 0) { + dev_err(&pdev->dev, "can't power up port\n"); +- return err; ++ goto err_netdev; + } + + /* Armada3700 network controller does not support per-cpu +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index 931d1a56b79ca..8827ab4b4932e 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -1129,7 +1129,7 @@ static void mvpp22_gop_init_rgmii(struct mvpp2_port *port) + + regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val); + if (port->gop_id == 2) +- val |= GENCONF_CTRL0_PORT0_RGMII | GENCONF_CTRL0_PORT1_RGMII; ++ val |= GENCONF_CTRL0_PORT0_RGMII; + else if (port->gop_id == 3) + val |= GENCONF_CTRL0_PORT1_RGMII_MII; + regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val); +@@ -2161,17 +2161,18 @@ static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port, + static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, + struct mvpp2_tx_queue *txq) + { +- unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu()); ++ unsigned int thread; + u32 val; + + if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK) + txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK; + + val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET); +- mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); +- mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); +- +- put_cpu(); ++ /* PKT-coalescing registers are per-queue + per-thread */ ++ for (thread = 0; thread < MVPP2_MAX_THREADS; thread++) { ++ mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); ++ mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); ++ } + } + + static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c +index 5692c6087bbb0..a30eb90ba3d28 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c +@@ -405,6 +405,38 @@ static int mvpp2_prs_tcam_first_free(struct mvpp2 *priv, unsigned char start, + return -EINVAL; + } + ++/* Drop flow control pause frames */ ++static void mvpp2_prs_drop_fc(struct mvpp2 *priv) ++{ ++ unsigned char da[ETH_ALEN] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 }; ++ struct mvpp2_prs_entry pe; ++ unsigned int len; ++ ++ memset(&pe, 0, sizeof(pe)); ++ ++ /* For all ports - drop flow control frames */ ++ pe.index = MVPP2_PE_FC_DROP; ++ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); ++ ++ /* Set match on DA */ ++ len = ETH_ALEN; ++ while (len--) ++ mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff); ++ ++ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK, ++ MVPP2_PRS_RI_DROP_MASK); ++ ++ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); ++ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); ++ ++ /* Mask all ports */ ++ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); ++ ++ /* Update shadow table and hw entry */ ++ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC); ++ mvpp2_prs_hw_write(priv, &pe); ++} ++ + /* Enable/disable dropping all mac da's */ + static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add) + { +@@ -1162,6 +1194,7 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv) + mvpp2_prs_hw_write(priv, &pe); + + /* Create dummy entries for drop all and promiscuous modes */ ++ mvpp2_prs_drop_fc(priv); + mvpp2_prs_mac_drop_all_set(priv, 0, false); + mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false); + mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false); +@@ -1647,8 +1680,9 @@ static int mvpp2_prs_pppoe_init(struct mvpp2 *priv) + mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); + mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, + MVPP2_PRS_RI_L3_PROTO_MASK); +- /* Skip eth_type + 4 bytes of IPv6 header */ +- mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, ++ /* Jump to DIP of IPV6 header */ ++ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 + ++ MVPP2_MAX_L3_ADDR_SIZE, + MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); + /* Set L3 offset */ + mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h +index e22f6c85d3803..4b68dd3747338 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h +@@ -129,7 +129,7 @@ + #define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7) + #define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) + #define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5) +-/* reserved */ ++#define MVPP2_PE_FC_DROP (MVPP2_PRS_TCAM_SRAM_SIZE - 4) + #define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) + #define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) + #define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +index ab6663d94f424..c818d24a8b24f 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +@@ -257,7 +257,7 @@ void ionic_rx_fill(struct ionic_queue *q) + unsigned int len; + unsigned int i; + +- len = netdev->mtu + ETH_HLEN; ++ len = netdev->mtu + ETH_HLEN + VLAN_HLEN; + + for (i = ionic_q_space_avail(q); i; i--) { + skb = ionic_rx_skb_alloc(q, len, &dma_addr); +diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c +index 004c0bfec41d7..f310a94e04898 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c +@@ -1737,6 +1737,11 @@ netdev_features_t qede_features_check(struct sk_buff *skb, + ntohs(udp_hdr(skb)->dest) != gnv_port)) + return features & ~(NETIF_F_CSUM_MASK | + NETIF_F_GSO_MASK); ++ } else if (l4_proto == IPPROTO_IPIP) { ++ /* IPIP tunnels are unknown to the device or at least unsupported natively, ++ * offloads for them can't be done trivially, so disable them for such skb. ++ */ ++ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + } + } + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index fd5adb0c54d29..366ca1b5da5cc 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -3958,7 +3958,8 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) + } + + switch (tp->mac_version) { +- case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: ++ case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_43: +@@ -3987,7 +3988,8 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) + static void rtl_pll_power_up(struct rtl8169_private *tp) + { + switch (tp->mac_version) { +- case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: ++ case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: ++ case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_43: +diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c +index 61136428e2c0e..26cfe3f7ed8df 100644 +--- a/drivers/net/ethernet/ti/cpts.c ++++ b/drivers/net/ethernet/ti/cpts.c +@@ -485,6 +485,7 @@ void cpts_unregister(struct cpts *cpts) + + ptp_clock_unregister(cpts->clock); + cpts->clock = NULL; ++ cpts->phc_index = -1; + + cpts_write32(cpts, 0, int_enable); + cpts_write32(cpts, 0, control); +@@ -667,6 +668,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, + cpts->cc.read = cpts_systim_read; + cpts->cc.mask = CLOCKSOURCE_MASK(32); + cpts->info = cpts_info; ++ cpts->phc_index = -1; + + cpts_calc_mult_shift(cpts); + /* save cc.mult original value as it can be modified +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index e72d273999834..84e779f93f0a4 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1469,7 +1469,7 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, + int i; + + if (it->nr_segs > MAX_SKB_FRAGS + 1) +- return ERR_PTR(-ENOMEM); ++ return ERR_PTR(-EMSGSIZE); + + local_bh_disable(); + skb = napi_get_frags(&tfile->napi); +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index c2c82e6391b4f..d407489cec904 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1625,9 +1625,6 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) + * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be + * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. + */ +- netif_info(dev, link, dev->net, +- "network connection: %sconnected\n", +- !!event->wValue ? "" : "dis"); + usbnet_link_change(dev, !!event->wValue, 0); + break; + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 74de621fa3504..b0d748a614a9e 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1058,6 +1058,7 @@ static const struct usb_device_id products[] = { + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ + + /* 3. Combined interface devices matching on interface number */ +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 7cc8f405be1ad..0ef85819665c8 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2072,14 +2072,16 @@ static int virtnet_set_channels(struct net_device *dev, + + get_online_cpus(); + err = _virtnet_set_queues(vi, queue_pairs); +- if (!err) { +- netif_set_real_num_tx_queues(dev, queue_pairs); +- netif_set_real_num_rx_queues(dev, queue_pairs); +- +- virtnet_set_affinity(vi); ++ if (err) { ++ put_online_cpus(); ++ goto err; + } ++ virtnet_set_affinity(vi); + put_online_cpus(); + ++ netif_set_real_num_tx_queues(dev, queue_pairs); ++ netif_set_real_num_rx_queues(dev, queue_pairs); ++ err: + return err; + } + +diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c +index 64f8556513369..261b53fc8e04c 100644 +--- a/drivers/net/wan/hdlc_ppp.c ++++ b/drivers/net/wan/hdlc_ppp.c +@@ -569,6 +569,13 @@ static void ppp_timer(struct timer_list *t) + unsigned long flags; + + spin_lock_irqsave(&ppp->lock, flags); ++ /* mod_timer could be called after we entered this function but ++ * before we got the lock. ++ */ ++ if (timer_pending(&proto->timer)) { ++ spin_unlock_irqrestore(&ppp->lock, flags); ++ return; ++ } + switch (proto->state) { + case STOPPING: + case REQ_SENT: +diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c +index f3d5b1bbd5aa7..c37dd15d16d24 100644 +--- a/drivers/scsi/scsi_transport_spi.c ++++ b/drivers/scsi/scsi_transport_spi.c +@@ -117,12 +117,16 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, + sshdr = &sshdr_tmp; + + for(i = 0; i < DV_RETRIES; i++) { ++ /* ++ * The purpose of the RQF_PM flag below is to bypass the ++ * SDEV_QUIESCE state. ++ */ + result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, + sshdr, DV_TIMEOUT, /* retries */ 1, + REQ_FAILFAST_DEV | + REQ_FAILFAST_TRANSPORT | + REQ_FAILFAST_DRIVER, +- 0, NULL); ++ RQF_PM, NULL); + if (driver_byte(result) != DRIVER_SENSE || + sshdr->sense_key != UNIT_ATTENTION) + break; +@@ -1005,23 +1009,26 @@ spi_dv_device(struct scsi_device *sdev) + */ + lock_system_sleep(); + ++ if (scsi_autopm_get_device(sdev)) ++ goto unlock_system_sleep; ++ + if (unlikely(spi_dv_in_progress(starget))) +- goto unlock; ++ goto put_autopm; + + if (unlikely(scsi_device_get(sdev))) +- goto unlock; ++ goto put_autopm; + + spi_dv_in_progress(starget) = 1; + + buffer = kzalloc(len, GFP_KERNEL); + + if (unlikely(!buffer)) +- goto out_put; ++ goto put_sdev; + + /* We need to verify that the actual device will quiesce; the + * later target quiesce is just a nice to have */ + if (unlikely(scsi_device_quiesce(sdev))) +- goto out_free; ++ goto free_buffer; + + scsi_target_quiesce(starget); + +@@ -1041,12 +1048,16 @@ spi_dv_device(struct scsi_device *sdev) + + spi_initial_dv(starget) = 1; + +- out_free: ++free_buffer: + kfree(buffer); +- out_put: ++ ++put_sdev: + spi_dv_in_progress(starget) = 0; + scsi_device_put(sdev); +-unlock: ++put_autopm: ++ scsi_autopm_put_device(sdev); ++ ++unlock_system_sleep: + unlock_system_sleep(); + } + EXPORT_SYMBOL(spi_dv_device); +diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c +index 3b19de3ae9a30..e4ba2445ff56f 100644 +--- a/drivers/scsi/ufs/ufshcd-pci.c ++++ b/drivers/scsi/ufs/ufshcd-pci.c +@@ -96,6 +96,30 @@ static int ufshcd_pci_resume(struct device *dev) + { + return ufshcd_system_resume(dev_get_drvdata(dev)); + } ++ ++/** ++ * ufshcd_pci_poweroff - suspend-to-disk poweroff function ++ * @dev: pointer to PCI device handle ++ * ++ * Returns 0 if successful ++ * Returns non-zero otherwise ++ */ ++static int ufshcd_pci_poweroff(struct device *dev) ++{ ++ struct ufs_hba *hba = dev_get_drvdata(dev); ++ int spm_lvl = hba->spm_lvl; ++ int ret; ++ ++ /* ++ * For poweroff we need to set the UFS device to PowerDown mode. ++ * Force spm_lvl to ensure that. ++ */ ++ hba->spm_lvl = 5; ++ ret = ufshcd_system_suspend(hba); ++ hba->spm_lvl = spm_lvl; ++ return ret; ++} ++ + #endif /* !CONFIG_PM_SLEEP */ + + #ifdef CONFIG_PM +@@ -190,8 +214,14 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + static const struct dev_pm_ops ufshcd_pci_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, +- ufshcd_pci_resume) ++#ifdef CONFIG_PM_SLEEP ++ .suspend = ufshcd_pci_suspend, ++ .resume = ufshcd_pci_resume, ++ .freeze = ufshcd_pci_suspend, ++ .thaw = ufshcd_pci_resume, ++ .poweroff = ufshcd_pci_poweroff, ++ .restore = ufshcd_pci_resume, ++#endif + SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, + ufshcd_pci_runtime_resume, + ufshcd_pci_runtime_idle) +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 675e16e61ebdd..b888117f4ecd3 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -3593,7 +3593,7 @@ static int ufshcd_dme_enable(struct ufs_hba *hba) + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, +- "dme-reset: error code %d\n", ret); ++ "dme-enable: error code %d\n", ret); + + return ret; + } +diff --git a/drivers/staging/mt7621-dma/mtk-hsdma.c b/drivers/staging/mt7621-dma/mtk-hsdma.c +index d964642d95a3c..bf2772af1045f 100644 +--- a/drivers/staging/mt7621-dma/mtk-hsdma.c ++++ b/drivers/staging/mt7621-dma/mtk-hsdma.c +@@ -714,7 +714,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) + ret = dma_async_device_register(dd); + if (ret) { + dev_err(&pdev->dev, "failed to register dma device\n"); +- return ret; ++ goto err_uninit_hsdma; + } + + ret = of_dma_controller_register(pdev->dev.of_node, +@@ -730,6 +730,8 @@ static int mtk_hsdma_probe(struct platform_device *pdev) + + err_unregister: + dma_async_device_unregister(dd); ++err_uninit_hsdma: ++ mtk_hsdma_uninit(hsdma); + return ret; + } + +diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c +index 9d24e85b08631..596ad3edec9c0 100644 +--- a/drivers/target/target_core_xcopy.c ++++ b/drivers/target/target_core_xcopy.c +@@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf) + return 0; + } + +-struct xcopy_dev_search_info { +- const unsigned char *dev_wwn; +- struct se_device *found_dev; +-}; +- ++/** ++ * target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers ++ * ++ * @se_dev: device being considered for match ++ * @dev_wwn: XCOPY requested NAA dev_wwn ++ * @return: 1 on match, 0 on no-match ++ */ + static int target_xcopy_locate_se_dev_e4_iter(struct se_device *se_dev, +- void *data) ++ const unsigned char *dev_wwn) + { +- struct xcopy_dev_search_info *info = data; + unsigned char tmp_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; + int rc; + +- if (!se_dev->dev_attrib.emulate_3pc) ++ if (!se_dev->dev_attrib.emulate_3pc) { ++ pr_debug("XCOPY: emulate_3pc disabled on se_dev %p\n", se_dev); + return 0; ++ } + + memset(&tmp_dev_wwn[0], 0, XCOPY_NAA_IEEE_REGEX_LEN); + target_xcopy_gen_naa_ieee(se_dev, &tmp_dev_wwn[0]); + +- rc = memcmp(&tmp_dev_wwn[0], info->dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN); +- if (rc != 0) +- return 0; +- +- info->found_dev = se_dev; +- pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev); +- +- rc = target_depend_item(&se_dev->dev_group.cg_item); ++ rc = memcmp(&tmp_dev_wwn[0], dev_wwn, XCOPY_NAA_IEEE_REGEX_LEN); + if (rc != 0) { +- pr_err("configfs_depend_item attempt failed: %d for se_dev: %p\n", +- rc, se_dev); +- return rc; ++ pr_debug("XCOPY: skip non-matching: %*ph\n", ++ XCOPY_NAA_IEEE_REGEX_LEN, tmp_dev_wwn); ++ return 0; + } ++ pr_debug("XCOPY 0xe4: located se_dev: %p\n", se_dev); + +- pr_debug("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n", +- se_dev, &se_dev->dev_group); + return 1; + } + +-static int target_xcopy_locate_se_dev_e4(const unsigned char *dev_wwn, +- struct se_device **found_dev) ++static int target_xcopy_locate_se_dev_e4(struct se_session *sess, ++ const unsigned char *dev_wwn, ++ struct se_device **_found_dev, ++ struct percpu_ref **_found_lun_ref) + { +- struct xcopy_dev_search_info info; +- int ret; +- +- memset(&info, 0, sizeof(info)); +- info.dev_wwn = dev_wwn; +- +- ret = target_for_each_device(target_xcopy_locate_se_dev_e4_iter, &info); +- if (ret == 1) { +- *found_dev = info.found_dev; +- return 0; +- } else { +- pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); +- return -EINVAL; ++ struct se_dev_entry *deve; ++ struct se_node_acl *nacl; ++ struct se_lun *this_lun = NULL; ++ struct se_device *found_dev = NULL; ++ ++ /* cmd with NULL sess indicates no associated $FABRIC_MOD */ ++ if (!sess) ++ goto err_out; ++ ++ pr_debug("XCOPY 0xe4: searching for: %*ph\n", ++ XCOPY_NAA_IEEE_REGEX_LEN, dev_wwn); ++ ++ nacl = sess->se_node_acl; ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { ++ struct se_device *this_dev; ++ int rc; ++ ++ this_lun = rcu_dereference(deve->se_lun); ++ this_dev = rcu_dereference_raw(this_lun->lun_se_dev); ++ ++ rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn); ++ if (rc) { ++ if (percpu_ref_tryget_live(&this_lun->lun_ref)) ++ found_dev = this_dev; ++ break; ++ } + } ++ rcu_read_unlock(); ++ if (found_dev == NULL) ++ goto err_out; ++ ++ pr_debug("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n", ++ found_dev, &found_dev->dev_group); ++ *_found_dev = found_dev; ++ *_found_lun_ref = &this_lun->lun_ref; ++ return 0; ++err_out: ++ pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); ++ return -EINVAL; + } + + static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op *xop, +@@ -246,12 +269,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd, + + switch (xop->op_origin) { + case XCOL_SOURCE_RECV_OP: +- rc = target_xcopy_locate_se_dev_e4(xop->dst_tid_wwn, +- &xop->dst_dev); ++ rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, ++ xop->dst_tid_wwn, ++ &xop->dst_dev, ++ &xop->remote_lun_ref); + break; + case XCOL_DEST_RECV_OP: +- rc = target_xcopy_locate_se_dev_e4(xop->src_tid_wwn, +- &xop->src_dev); ++ rc = target_xcopy_locate_se_dev_e4(se_cmd->se_sess, ++ xop->src_tid_wwn, ++ &xop->src_dev, ++ &xop->remote_lun_ref); + break; + default: + pr_err("XCOPY CSCD descriptor IDs not found in CSCD list - " +@@ -396,18 +423,12 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd) + + static void xcopy_pt_undepend_remotedev(struct xcopy_op *xop) + { +- struct se_device *remote_dev; +- + if (xop->op_origin == XCOL_SOURCE_RECV_OP) +- remote_dev = xop->dst_dev; ++ pr_debug("putting dst lun_ref for %p\n", xop->dst_dev); + else +- remote_dev = xop->src_dev; +- +- pr_debug("Calling configfs_undepend_item for" +- " remote_dev: %p remote_dev->dev_group: %p\n", +- remote_dev, &remote_dev->dev_group.cg_item); ++ pr_debug("putting src lun_ref for %p\n", xop->src_dev); + +- target_undepend_item(&remote_dev->dev_group.cg_item); ++ percpu_ref_put(xop->remote_lun_ref); + } + + static void xcopy_pt_release_cmd(struct se_cmd *se_cmd) +diff --git a/drivers/target/target_core_xcopy.h b/drivers/target/target_core_xcopy.h +index 26ba4c3c9cffd..974bc1e19ff2b 100644 +--- a/drivers/target/target_core_xcopy.h ++++ b/drivers/target/target_core_xcopy.h +@@ -29,6 +29,7 @@ struct xcopy_op { + struct se_device *dst_dev; + unsigned char dst_tid_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; + unsigned char local_dev_wwn[XCOPY_NAA_IEEE_REGEX_LEN]; ++ struct percpu_ref *remote_lun_ref; + + sector_t src_lba; + sector_t dst_lba; +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index c08bcce04276e..85561b3194a16 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) + misc_pdev = of_find_device_by_node(args.np); + of_node_put(args.np); + +- if (!misc_pdev || !platform_get_drvdata(misc_pdev)) ++ if (!misc_pdev) + return ERR_PTR(-EPROBE_DEFER); + ++ if (!platform_get_drvdata(misc_pdev)) { ++ put_device(&misc_pdev->dev); ++ return ERR_PTR(-EPROBE_DEFER); ++ } + data->dev = &misc_pdev->dev; + + /* +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 16c98e718001b..681374a3b3684 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1907,6 +1907,10 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */ + .driver_info = IGNORE_DEVICE, + }, ++ ++ { USB_DEVICE(0x04d8, 0xf58b), ++ .driver_info = IGNORE_DEVICE, ++ }, + #endif + + /*Samsung phone in firmware update mode */ +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 9875e2fe33db2..fc1a219ad0a76 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc) + if (!desc->resp_count || !--desc->resp_count) + goto out; + ++ if (test_bit(WDM_DISCONNECTING, &desc->flags)) { ++ rv = -ENODEV; ++ goto out; ++ } ++ if (test_bit(WDM_RESETTING, &desc->flags)) { ++ rv = -EIO; ++ goto out; ++ } ++ + set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); + rv = usb_submit_urb(desc->response, GFP_KERNEL); + spin_lock_irq(&desc->iuspin); + if (rv) { +- dev_err(&desc->intf->dev, +- "usb_submit_urb failed with result %d\n", rv); ++ if (!test_bit(WDM_DISCONNECTING, &desc->flags)) ++ dev_err(&desc->intf->dev, ++ "usb_submit_urb failed with result %d\n", rv); + + /* make sure the next notification trigger a submit */ + clear_bit(WDM_RESPONDING, &desc->flags); +@@ -1026,9 +1036,9 @@ static void wdm_disconnect(struct usb_interface *intf) + wake_up_all(&desc->wait); + mutex_lock(&desc->rlock); + mutex_lock(&desc->wlock); +- kill_urbs(desc); + cancel_work_sync(&desc->rxwork); + cancel_work_sync(&desc->service_outs_intr); ++ kill_urbs(desc); + mutex_unlock(&desc->wlock); + mutex_unlock(&desc->rlock); + +diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c +index 67cbd42421bee..134dc2005ce97 100644 +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i + #define usblp_reset(usblp)\ + usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) + +-#define usblp_hp_channel_change_request(usblp, channel, buffer) \ +- usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) ++static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) ++{ ++ u8 *buf; ++ int ret; ++ ++ buf = kzalloc(1, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, ++ USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, ++ channel, buf, 1); ++ if (ret == 0) ++ *new_channel = buf[0]; ++ ++ kfree(buf); ++ ++ return ret; ++} + + /* + * See the description for usblp_select_alts() below for the usage +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index c848f9164f929..da296f888f45d 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -283,6 +283,7 @@ + + /* Global USB2 PHY Vendor Control Register */ + #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) ++#define DWC3_GUSB2PHYACC_DONE BIT(24) + #define DWC3_GUSB2PHYACC_BUSY BIT(23) + #define DWC3_GUSB2PHYACC_WRITE BIT(22) + #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) +diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c +index f62b5f3c2d67d..bb8271531da70 100644 +--- a/drivers/usb/dwc3/ulpi.c ++++ b/drivers/usb/dwc3/ulpi.c +@@ -24,7 +24,7 @@ static int dwc3_ulpi_busyloop(struct dwc3 *dwc) + + while (count--) { + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); +- if (!(reg & DWC3_GUSB2PHYACC_BUSY)) ++ if (reg & DWC3_GUSB2PHYACC_DONE) + return 0; + cpu_relax(); + } +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 02ff850278b17..09ba3af1234ee 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM + depends on NET + select USB_U_ETHER + select USB_F_NCM ++ select CRC32 + help + NCM is an advanced protocol for Ethernet encapsulation, allows + grouping of several ethernet frames into one USB transfer and +@@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM + depends on NET + select USB_U_ETHER + select USB_F_EEM ++ select CRC32 + help + CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM + and therefore can be supported by more hardware. Technically ECM and +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index f75ff1a75dc45..ed46fd74a292a 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function) + + spin_lock_irqsave(&cdev->lock, flags); + +- if (cdev->deactivations == 0) ++ if (cdev->deactivations == 0) { ++ spin_unlock_irqrestore(&cdev->lock, flags); + status = usb_gadget_deactivate(cdev->gadget); ++ spin_lock_irqsave(&cdev->lock, flags); ++ } + if (status == 0) + cdev->deactivations++; + +@@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function) + status = -EINVAL; + else { + cdev->deactivations--; +- if (cdev->deactivations == 0) ++ if (cdev->deactivations == 0) { ++ spin_unlock_irqrestore(&cdev->lock, flags); + status = usb_gadget_activate(cdev->gadget); ++ spin_lock_irqsave(&cdev->lock, flags); ++ } + } + + spin_unlock_irqrestore(&cdev->lock, flags); +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index a7709d126b29b..5b8b2ca4376cb 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -233,9 +233,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item, + + static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) + { +- char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name; ++ struct gadget_info *gi = to_gadget_info(item); ++ char *udc_name; ++ int ret; ++ ++ mutex_lock(&gi->lock); ++ udc_name = gi->composite.gadget_driver.udc_name; ++ ret = sprintf(page, "%s\n", udc_name ?: ""); ++ mutex_unlock(&gi->lock); + +- return sprintf(page, "%s\n", udc_name ?: ""); ++ return ret; + } + + static int unregister_gadget(struct gadget_info *gi) +@@ -1217,9 +1224,9 @@ static void purge_configs_funcs(struct gadget_info *gi) + + cfg = container_of(c, struct config_usb_cfg, c); + +- list_for_each_entry_safe(f, tmp, &c->functions, list) { ++ list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) { + +- list_move_tail(&f->list, &cfg->func_list); ++ list_move(&f->list, &cfg->func_list); + if (f->unbind) { + dev_dbg(&gi->cdev.gadget->dev, + "unbind function '%s'/%p\n", +@@ -1505,7 +1512,7 @@ static const struct usb_gadget_driver configfs_driver_template = { + .suspend = configfs_composite_suspend, + .resume = configfs_composite_resume, + +- .max_speed = USB_SPEED_SUPER, ++ .max_speed = USB_SPEED_SUPER_PLUS, + .driver = { + .owner = THIS_MODULE, + .name = "configfs-gadget", +@@ -1545,7 +1552,7 @@ static struct config_group *gadgets_make( + gi->composite.unbind = configfs_do_nothing; + gi->composite.suspend = NULL; + gi->composite.resume = NULL; +- gi->composite.max_speed = USB_SPEED_SUPER; ++ gi->composite.max_speed = USB_SPEED_SUPER_PLUS; + + spin_lock_init(&gi->spinlock); + mutex_init(&gi->lock); +diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c +index 8ed1295d7e350..0f47cd398d60a 100644 +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -1126,6 +1126,7 @@ fail_tx_reqs: + printer_req_free(dev->in_ep, req); + } + ++ usb_free_all_descriptors(f); + return ret; + + } +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index 3633df6d7610f..5d960b6603b6f 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1023), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 1, + }; + +@@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1024), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 4, + }; + +@@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = { + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1023), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 1, + }; + +@@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1024), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 4, + }; + +@@ -444,12 +444,28 @@ struct cntrl_range_lay3 { + __le32 dRES; + } __packed; + +-static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, ++static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + struct usb_endpoint_descriptor *ep_desc, +- unsigned int factor, bool is_playback) ++ enum usb_device_speed speed, bool is_playback) + { + int chmask, srate, ssize; +- u16 max_packet_size; ++ u16 max_size_bw, max_size_ep; ++ unsigned int factor; ++ ++ switch (speed) { ++ case USB_SPEED_FULL: ++ max_size_ep = 1023; ++ factor = 1000; ++ break; ++ ++ case USB_SPEED_HIGH: ++ max_size_ep = 1024; ++ factor = 8000; ++ break; ++ ++ default: ++ return -EINVAL; ++ } + + if (is_playback) { + chmask = uac2_opts->p_chmask; +@@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + ssize = uac2_opts->c_ssize; + } + +- max_packet_size = num_channels(chmask) * ssize * ++ max_size_bw = num_channels(chmask) * ssize * + DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); +- ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, +- le16_to_cpu(ep_desc->wMaxPacketSize))); ++ ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, ++ max_size_ep)); ++ ++ return 0; + } + + /* Use macro to overcome line length limitation */ +@@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) + } + + /* Calculate wMaxPacketSize according to audio bandwidth */ +- set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); +- set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); +- set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); +- set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); ++ ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, ++ true); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL, ++ false); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH, ++ true); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH, ++ false); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } + + if (EPOUT_EN(uac2_opts)) { + agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); +diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c +index 891e9f7f40d59..99b840daf3d94 100644 +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -45,9 +45,10 @@ + #define UETH__VERSION "29-May-2008" + + /* Experiments show that both Linux and Windows hosts allow up to 16k +- * frame sizes. Set the max size to 15k+52 to prevent allocating 32k ++ * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k + * blocks and still have efficient handling. */ +-#define GETHER_MAX_ETH_FRAME_LEN 15412 ++#define GETHER_MAX_MTU_SIZE 15412 ++#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) + + struct eth_dev { + /* lock is held while accessing port_usb +@@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, + + /* MTU range: 14 - 15412 */ + net->min_mtu = ETH_HLEN; +- net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; ++ net->max_mtu = GETHER_MAX_MTU_SIZE; + + dev->gadget = g; + SET_NETDEV_DEV(net, &g->dev); +@@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname) + + /* MTU range: 14 - 15412 */ + net->min_mtu = ETH_HLEN; +- net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; ++ net->max_mtu = GETHER_MAX_MTU_SIZE; + + return net; + } +diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c +index af16672d51187..6680dcfe660ea 100644 +--- a/drivers/usb/gadget/legacy/acm_ms.c ++++ b/drivers/usb/gadget/legacy/acm_ms.c +@@ -203,8 +203,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) + struct usb_descriptor_header *usb_desc; + + usb_desc = usb_otg_descriptor_alloc(gadget); +- if (!usb_desc) ++ if (!usb_desc) { ++ status = -ENOMEM; + goto fail_string_ids; ++ } + usb_otg_descriptor_init(gadget, usb_desc); + otg_desc[0] = usb_desc; + otg_desc[1] = NULL; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 7123ab44671b2..70aa3055c41e7 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4642,19 +4642,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, + { + unsigned long long timeout_ns; + ++ if (xhci->quirks & XHCI_INTEL_HOST) ++ timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); ++ else ++ timeout_ns = udev->u1_params.sel; ++ + /* Prevent U1 if service interval is shorter than U1 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { +- if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { ++ if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + +- if (xhci->quirks & XHCI_INTEL_HOST) +- timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); +- else +- timeout_ns = udev->u1_params.sel; +- + /* The U1 timeout is encoded in 1us intervals. + * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. + */ +@@ -4706,19 +4706,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, + { + unsigned long long timeout_ns; + ++ if (xhci->quirks & XHCI_INTEL_HOST) ++ timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); ++ else ++ timeout_ns = udev->u2_params.sel; ++ + /* Prevent U2 if service interval is shorter than U2 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { +- if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { ++ if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + +- if (xhci->quirks & XHCI_INTEL_HOST) +- timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); +- else +- timeout_ns = udev->u2_params.sel; +- + /* The U2 timeout is encoded in 256us intervals */ + timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); + /* If the necessary timeout value is bigger than what we can set in the +diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c +index 785080f790738..08b72bb22b7ef 100644 +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -497,6 +497,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, + timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); + finish_wait(&dev->waitq, &wait); + ++ /* make sure URB is idle after timeout or (spurious) CMD_ACK */ ++ usb_kill_urb(dev->cntl_urb); ++ + mutex_unlock(&dev->io_mutex); + + if (retval < 0) { +diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c +index ffbb2a8901b2b..7e4ec0b8d01f8 100644 +--- a/drivers/usb/serial/iuu_phoenix.c ++++ b/drivers/usb/serial/iuu_phoenix.c +@@ -536,23 +536,29 @@ static int iuu_uart_flush(struct usb_serial_port *port) + struct device *dev = &port->dev; + int i; + int status; +- u8 rxcmd = IUU_UART_RX; ++ u8 *rxcmd; + struct iuu_private *priv = usb_get_serial_port_data(port); + + if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) + return -EIO; + ++ rxcmd = kmalloc(1, GFP_KERNEL); ++ if (!rxcmd) ++ return -ENOMEM; ++ ++ rxcmd[0] = IUU_UART_RX; ++ + for (i = 0; i < 2; i++) { +- status = bulk_immediate(port, &rxcmd, 1); ++ status = bulk_immediate(port, rxcmd, 1); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_write error\n", __func__); +- return status; ++ goto out_free; + } + + status = read_immediate(port, &priv->len, 1); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_read error\n", __func__); +- return status; ++ goto out_free; + } + + if (priv->len > 0) { +@@ -560,12 +566,16 @@ static int iuu_uart_flush(struct usb_serial_port *port) + status = read_immediate(port, priv->buf, priv->len); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_read error\n", __func__); +- return status; ++ goto out_free; + } + } + } + dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); + iuu_led(port, 0, 0xF000, 0, 0xFF); ++ ++out_free: ++ kfree(rxcmd); ++ + return status; + } + +diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c +index fab6aa8a676aa..5dd228da5bdd5 100644 +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -555,10 +555,8 @@ exit: + static void keyspan_pda_write_bulk_callback(struct urb *urb) + { + struct usb_serial_port *port = urb->context; +- struct keyspan_pda_private *priv; + + set_bit(0, &port->write_urbs_free); +- priv = usb_get_serial_port_data(port); + + /* queue up a wakeup at scheduler time */ + usb_serial_port_softint(port); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 531744049e7f0..fd41b07b5aaf1 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), +@@ -2057,6 +2059,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ +diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h +index 749c69be091cc..cb7b15ecb7aba 100644 +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -90,6 +90,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA), + ++/* Reported-by: Thinh Nguyen */ ++UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, ++ "PNY", ++ "Pro Elite SSD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_ATA_1X), ++ + /* Reported-by: Thinh Nguyen */ + UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, + "PNY", +diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c +index 65850e9c71905..fee511437abe3 100644 +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + default: + usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", + wValue); ++ if (wValue >= 32) ++ goto error; + vhci_hcd->port_status[rhport] &= ~(1 << wValue); + break; + } +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index b53b6528d6ce2..48e574ae60330 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -860,6 +860,7 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) + size_t len, total_len = 0; + int err; + struct vhost_net_ubuf_ref *uninitialized_var(ubufs); ++ struct ubuf_info *ubuf; + bool zcopy_used; + int sent_pkts = 0; + +@@ -892,9 +893,7 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) + + /* use msg_control to pass vhost zerocopy ubuf info to skb */ + if (zcopy_used) { +- struct ubuf_info *ubuf; + ubuf = nvq->ubuf_info + nvq->upend_idx; +- + vq->heads[nvq->upend_idx].id = cpu_to_vhost32(vq, head); + vq->heads[nvq->upend_idx].len = VHOST_DMA_IN_PROGRESS; + ubuf->callback = vhost_zerocopy_callback; +@@ -924,7 +923,8 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) + err = sock->ops->sendmsg(sock, &msg, len); + if (unlikely(err < 0)) { + if (zcopy_used) { +- vhost_net_ubuf_put(ubufs); ++ if (vq->heads[ubuf->desc].len == VHOST_DMA_IN_PROGRESS) ++ vhost_net_ubuf_put(ubufs); + nvq->upend_idx = ((unsigned)nvq->upend_idx - 1) + % UIO_MAXIOV; + } +diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c +index 81671272aa58f..1c6ae98710a01 100644 +--- a/drivers/video/fbdev/hyperv_fb.c ++++ b/drivers/video/fbdev/hyperv_fb.c +@@ -704,11 +704,9 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) + } + + /* +- * Map the VRAM cacheable for performance. This is also required for +- * VM Connect to display properly for ARM64 Linux VM, as the host also +- * maps the VRAM cacheable. ++ * Map the VRAM cacheable for performance. + */ +- fb_virt = ioremap_cache(par->mem->start, screen_fb_size); ++ fb_virt = ioremap_wc(par->mem->start, screen_fb_size); + if (!fb_virt) + goto err2; + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index 88940f494428a..903136ceac34a 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -238,6 +238,7 @@ struct waiting_dir_move { + * after this directory is moved, we can try to rmdir the ino rmdir_ino. + */ + u64 rmdir_ino; ++ u64 rmdir_gen; + bool orphanized; + }; + +@@ -323,7 +324,7 @@ static int is_waiting_for_move(struct send_ctx *sctx, u64 ino); + static struct waiting_dir_move * + get_waiting_dir_move(struct send_ctx *sctx, u64 ino); + +-static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino); ++static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen); + + static int need_send_hole(struct send_ctx *sctx) + { +@@ -2306,7 +2307,7 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, + + fs_path_reset(name); + +- if (is_waiting_for_rm(sctx, ino)) { ++ if (is_waiting_for_rm(sctx, ino, gen)) { + ret = gen_unique_name(sctx, ino, gen, name); + if (ret < 0) + goto out; +@@ -2865,8 +2866,8 @@ out: + return ret; + } + +-static struct orphan_dir_info * +-add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) ++static struct orphan_dir_info *add_orphan_dir_info(struct send_ctx *sctx, ++ u64 dir_ino, u64 dir_gen) + { + struct rb_node **p = &sctx->orphan_dirs.rb_node; + struct rb_node *parent = NULL; +@@ -2875,20 +2876,23 @@ add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) + while (*p) { + parent = *p; + entry = rb_entry(parent, struct orphan_dir_info, node); +- if (dir_ino < entry->ino) { ++ if (dir_ino < entry->ino) + p = &(*p)->rb_left; +- } else if (dir_ino > entry->ino) { ++ else if (dir_ino > entry->ino) + p = &(*p)->rb_right; +- } else { ++ else if (dir_gen < entry->gen) ++ p = &(*p)->rb_left; ++ else if (dir_gen > entry->gen) ++ p = &(*p)->rb_right; ++ else + return entry; +- } + } + + odi = kmalloc(sizeof(*odi), GFP_KERNEL); + if (!odi) + return ERR_PTR(-ENOMEM); + odi->ino = dir_ino; +- odi->gen = 0; ++ odi->gen = dir_gen; + odi->last_dir_index_offset = 0; + + rb_link_node(&odi->node, parent, p); +@@ -2896,8 +2900,8 @@ add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) + return odi; + } + +-static struct orphan_dir_info * +-get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) ++static struct orphan_dir_info *get_orphan_dir_info(struct send_ctx *sctx, ++ u64 dir_ino, u64 gen) + { + struct rb_node *n = sctx->orphan_dirs.rb_node; + struct orphan_dir_info *entry; +@@ -2908,15 +2912,19 @@ get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) + n = n->rb_left; + else if (dir_ino > entry->ino) + n = n->rb_right; ++ else if (gen < entry->gen) ++ n = n->rb_left; ++ else if (gen > entry->gen) ++ n = n->rb_right; + else + return entry; + } + return NULL; + } + +-static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino) ++static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen) + { +- struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino); ++ struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino, gen); + + return odi != NULL; + } +@@ -2961,7 +2969,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, + key.type = BTRFS_DIR_INDEX_KEY; + key.offset = 0; + +- odi = get_orphan_dir_info(sctx, dir); ++ odi = get_orphan_dir_info(sctx, dir, dir_gen); + if (odi) + key.offset = odi->last_dir_index_offset; + +@@ -2992,7 +3000,7 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, + + dm = get_waiting_dir_move(sctx, loc.objectid); + if (dm) { +- odi = add_orphan_dir_info(sctx, dir); ++ odi = add_orphan_dir_info(sctx, dir, dir_gen); + if (IS_ERR(odi)) { + ret = PTR_ERR(odi); + goto out; +@@ -3000,12 +3008,13 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, + odi->gen = dir_gen; + odi->last_dir_index_offset = found_key.offset; + dm->rmdir_ino = dir; ++ dm->rmdir_gen = dir_gen; + ret = 0; + goto out; + } + + if (loc.objectid > send_progress) { +- odi = add_orphan_dir_info(sctx, dir); ++ odi = add_orphan_dir_info(sctx, dir, dir_gen); + if (IS_ERR(odi)) { + ret = PTR_ERR(odi); + goto out; +@@ -3045,6 +3054,7 @@ static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized) + return -ENOMEM; + dm->ino = ino; + dm->rmdir_ino = 0; ++ dm->rmdir_gen = 0; + dm->orphanized = orphanized; + + while (*p) { +@@ -3190,7 +3200,7 @@ static int path_loop(struct send_ctx *sctx, struct fs_path *name, + while (ino != BTRFS_FIRST_FREE_OBJECTID) { + fs_path_reset(name); + +- if (is_waiting_for_rm(sctx, ino)) ++ if (is_waiting_for_rm(sctx, ino, gen)) + break; + if (is_waiting_for_move(sctx, ino)) { + if (*ancestor_ino == 0) +@@ -3230,6 +3240,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) + u64 parent_ino, parent_gen; + struct waiting_dir_move *dm = NULL; + u64 rmdir_ino = 0; ++ u64 rmdir_gen; + u64 ancestor; + bool is_orphan; + int ret; +@@ -3244,6 +3255,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) + dm = get_waiting_dir_move(sctx, pm->ino); + ASSERT(dm); + rmdir_ino = dm->rmdir_ino; ++ rmdir_gen = dm->rmdir_gen; + is_orphan = dm->orphanized; + free_waiting_dir_move(sctx, dm); + +@@ -3280,6 +3292,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) + dm = get_waiting_dir_move(sctx, pm->ino); + ASSERT(dm); + dm->rmdir_ino = rmdir_ino; ++ dm->rmdir_gen = rmdir_gen; + } + goto out; + } +@@ -3298,7 +3311,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) + struct orphan_dir_info *odi; + u64 gen; + +- odi = get_orphan_dir_info(sctx, rmdir_ino); ++ odi = get_orphan_dir_info(sctx, rmdir_ino, rmdir_gen); + if (!odi) { + /* already deleted */ + goto finish; +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index 64e9ee1b129e2..8c3dbe13e647c 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -138,8 +138,12 @@ static int proc_getattr(const struct path *path, struct kstat *stat, + { + struct inode *inode = d_inode(path->dentry); + struct proc_dir_entry *de = PDE(inode); +- if (de && de->nlink) +- set_nlink(inode, de->nlink); ++ if (de) { ++ nlink_t nlink = READ_ONCE(de->nlink); ++ if (nlink > 0) { ++ set_nlink(inode, nlink); ++ } ++ } + + generic_fillattr(inode, stat); + return 0; +@@ -338,6 +342,16 @@ static const struct file_operations proc_dir_operations = { + .iterate_shared = proc_readdir, + }; + ++static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ return 0; ++} ++ ++const struct dentry_operations proc_net_dentry_ops = { ++ .d_revalidate = proc_net_d_revalidate, ++ .d_delete = always_delete_dentry, ++}; ++ + /* + * proc directories can do almost nothing.. + */ +@@ -362,6 +376,7 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, + write_unlock(&proc_subdir_lock); + goto out_free_inum; + } ++ dir->nlink++; + write_unlock(&proc_subdir_lock); + + return dp; +@@ -459,8 +474,8 @@ struct proc_dir_entry *proc_symlink(const char *name, + } + EXPORT_SYMBOL(proc_symlink); + +-struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, +- struct proc_dir_entry *parent, void *data) ++struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode, ++ struct proc_dir_entry *parent, void *data, bool force_lookup) + { + struct proc_dir_entry *ent; + +@@ -472,13 +487,20 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, + ent->data = data; + ent->proc_fops = &proc_dir_operations; + ent->proc_iops = &proc_dir_inode_operations; +- parent->nlink++; ++ if (force_lookup) { ++ pde_force_lookup(ent); ++ } + ent = proc_register(parent, ent); +- if (!ent) +- parent->nlink--; + } + return ent; + } ++EXPORT_SYMBOL_GPL(_proc_mkdir); ++ ++struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, ++ struct proc_dir_entry *parent, void *data) ++{ ++ return _proc_mkdir(name, mode, parent, data, false); ++} + EXPORT_SYMBOL_GPL(proc_mkdir_data); + + struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, +@@ -505,10 +527,7 @@ struct proc_dir_entry *proc_create_mount_point(const char *name) + ent->data = NULL; + ent->proc_fops = NULL; + ent->proc_iops = NULL; +- parent->nlink++; + ent = proc_register(parent, ent); +- if (!ent) +- parent->nlink--; + } + return ent; + } +@@ -666,8 +685,12 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) + len = strlen(fn); + + de = pde_subdir_find(parent, fn, len); +- if (de) ++ if (de) { + rb_erase(&de->subdir_node, &parent->subdir); ++ if (S_ISDIR(de->mode)) { ++ parent->nlink--; ++ } ++ } + write_unlock(&proc_subdir_lock); + if (!de) { + WARN(1, "name '%s'\n", name); +@@ -676,9 +699,6 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) + + proc_entry_rundown(de); + +- if (S_ISDIR(de->mode)) +- parent->nlink--; +- de->nlink = 0; + WARN(pde_subdir_first(de), + "%s: removing non-empty directory '%s/%s', leaking at least '%s'\n", + __func__, de->parent->name, de->name, pde_subdir_first(de)->name); +@@ -714,13 +734,12 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) + de = next; + continue; + } +- write_unlock(&proc_subdir_lock); +- +- proc_entry_rundown(de); + next = de->parent; + if (S_ISDIR(de->mode)) + next->nlink--; +- de->nlink = 0; ++ write_unlock(&proc_subdir_lock); ++ ++ proc_entry_rundown(de); + if (de == root) + break; + pde_put(de); +diff --git a/fs/proc/internal.h b/fs/proc/internal.h +index cd0c8d5ce9a13..269acc165055d 100644 +--- a/fs/proc/internal.h ++++ b/fs/proc/internal.h +@@ -299,3 +299,10 @@ extern unsigned long task_statm(struct mm_struct *, + unsigned long *, unsigned long *, + unsigned long *, unsigned long *); + extern void task_mem(struct seq_file *, struct mm_struct *); ++ ++extern const struct dentry_operations proc_net_dentry_ops; ++static inline void pde_force_lookup(struct proc_dir_entry *pde) ++{ ++ /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ ++ pde->proc_dops = &proc_net_dentry_ops; ++} +diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c +index 76ae278df1c47..313b7c751867f 100644 +--- a/fs/proc/proc_net.c ++++ b/fs/proc/proc_net.c +@@ -39,22 +39,6 @@ static struct net *get_proc_net(const struct inode *inode) + return maybe_get_net(PDE_NET(PDE(inode))); + } + +-static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags) +-{ +- return 0; +-} +- +-static const struct dentry_operations proc_net_dentry_ops = { +- .d_revalidate = proc_net_d_revalidate, +- .d_delete = always_delete_dentry, +-}; +- +-static void pde_force_lookup(struct proc_dir_entry *pde) +-{ +- /* /proc/net/ entries can be changed under us by setns(CLONE_NEWNET) */ +- pde->proc_dops = &proc_net_dentry_ops; +-} +- + static int seq_open_net(struct inode *inode, struct file *file) + { + unsigned int state_size = PDE(inode)->state_size; +diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h +index a705aa2d03f91..865d02c224ada 100644 +--- a/include/linux/proc_fs.h ++++ b/include/linux/proc_fs.h +@@ -21,6 +21,7 @@ extern void proc_flush_task(struct task_struct *); + + extern struct proc_dir_entry *proc_symlink(const char *, + struct proc_dir_entry *, const char *); ++struct proc_dir_entry *_proc_mkdir(const char *, umode_t, struct proc_dir_entry *, void *, bool); + extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *); + extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, + struct proc_dir_entry *, void *); +@@ -99,6 +100,11 @@ static inline struct proc_dir_entry *proc_symlink(const char *name, + static inline struct proc_dir_entry *proc_mkdir(const char *name, + struct proc_dir_entry *parent) {return NULL;} + static inline struct proc_dir_entry *proc_create_mount_point(const char *name) { return NULL; } ++static inline struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode, ++ struct proc_dir_entry *parent, void *data, bool force_lookup) ++{ ++ return NULL; ++} + static inline struct proc_dir_entry *proc_mkdir_data(const char *name, + umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; } + static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, +@@ -136,7 +142,7 @@ struct net; + static inline struct proc_dir_entry *proc_net_mkdir( + struct net *net, const char *name, struct proc_dir_entry *parent) + { +- return proc_mkdir_data(name, 0, parent, net); ++ return _proc_mkdir(name, 0, parent, net, true); + } + + struct ns_common; +diff --git a/include/net/red.h b/include/net/red.h +index 9665582c4687e..e21e7fd4fe077 100644 +--- a/include/net/red.h ++++ b/include/net/red.h +@@ -168,12 +168,14 @@ static inline void red_set_vars(struct red_vars *v) + v->qcount = -1; + } + +-static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog) ++static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_log) + { + if (fls(qth_min) + Wlog > 32) + return false; + if (fls(qth_max) + Wlog > 32) + return false; ++ if (Scell_log >= 32) ++ return false; + if (qth_max < qth_min) + return false; + return true; +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 4aa268582a225..28e52657e0930 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3718,17 +3718,24 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq) + * is updated and visible. + */ + if (!freezable || !workqueue_freezing) { ++ bool kick = false; ++ + pwq->max_active = wq->saved_max_active; + + while (!list_empty(&pwq->delayed_works) && +- pwq->nr_active < pwq->max_active) ++ pwq->nr_active < pwq->max_active) { + pwq_activate_first_delayed(pwq); ++ kick = true; ++ } + + /* + * Need to kick a worker after thawed or an unbound wq's +- * max_active is bumped. It's a slow path. Do it always. ++ * max_active is bumped. In realtime scenarios, always kicking a ++ * worker will cause interference on the isolated cpu cores, so ++ * let's kick iff work items were activated. + */ +- wake_up_worker(pwq->pool); ++ if (kick) ++ wake_up_worker(pwq->pool); + } else { + pwq->max_active = 0; + } +diff --git a/lib/genalloc.c b/lib/genalloc.c +index 9fc31292cfa1d..80d10d02cf388 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -81,14 +81,14 @@ static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear) + * users set the same bit, one user will return remain bits, otherwise + * return 0. + */ +-static int bitmap_set_ll(unsigned long *map, int start, int nr) ++static int bitmap_set_ll(unsigned long *map, unsigned long start, unsigned long nr) + { + unsigned long *p = map + BIT_WORD(start); +- const int size = start + nr; ++ const unsigned long size = start + nr; + int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); + +- while (nr - bits_to_set >= 0) { ++ while (nr >= bits_to_set) { + if (set_bits_ll(p, mask_to_set)) + return nr; + nr -= bits_to_set; +@@ -116,14 +116,15 @@ static int bitmap_set_ll(unsigned long *map, int start, int nr) + * users clear the same bit, one user will return remain bits, + * otherwise return 0. + */ +-static int bitmap_clear_ll(unsigned long *map, int start, int nr) ++static unsigned long ++bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr) + { + unsigned long *p = map + BIT_WORD(start); +- const int size = start + nr; ++ const unsigned long size = start + nr; + int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); + +- while (nr - bits_to_clear >= 0) { ++ while (nr >= bits_to_clear) { + if (clear_bits_ll(p, mask_to_clear)) + return nr; + nr -= bits_to_clear; +@@ -183,8 +184,8 @@ int gen_pool_add_owner(struct gen_pool *pool, unsigned long virt, phys_addr_t ph + size_t size, int nid, void *owner) + { + struct gen_pool_chunk *chunk; +- int nbits = size >> pool->min_alloc_order; +- int nbytes = sizeof(struct gen_pool_chunk) + ++ unsigned long nbits = size >> pool->min_alloc_order; ++ unsigned long nbytes = sizeof(struct gen_pool_chunk) + + BITS_TO_LONGS(nbits) * sizeof(long); + + chunk = vzalloc_node(nbytes, nid); +@@ -242,7 +243,7 @@ void gen_pool_destroy(struct gen_pool *pool) + struct list_head *_chunk, *_next_chunk; + struct gen_pool_chunk *chunk; + int order = pool->min_alloc_order; +- int bit, end_bit; ++ unsigned long bit, end_bit; + + list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); +@@ -278,7 +279,7 @@ unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size, + struct gen_pool_chunk *chunk; + unsigned long addr = 0; + int order = pool->min_alloc_order; +- int nbits, start_bit, end_bit, remain; ++ unsigned long nbits, start_bit, end_bit, remain; + + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG + BUG_ON(in_nmi()); +@@ -487,7 +488,7 @@ void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, size_t size, + { + struct gen_pool_chunk *chunk; + int order = pool->min_alloc_order; +- int start_bit, nbits, remain; ++ unsigned long start_bit, nbits, remain; + + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG + BUG_ON(in_nmi()); +@@ -754,7 +755,7 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, + index = bitmap_find_next_zero_area(map, size, start, nr, 0); + + while (index < size) { +- int next_bit = find_next_bit(map, size, index + nr); ++ unsigned long next_bit = find_next_bit(map, size, index + nr); + if ((next_bit - index) < len) { + len = next_bit - index; + start_bit = index; +diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c +index 2ebf9b252779d..98474d85fb51f 100644 +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -1235,8 +1235,8 @@ static const struct attribute_group dql_group = { + static ssize_t xps_cpus_show(struct netdev_queue *queue, + char *buf) + { ++ int cpu, len, ret, num_tc = 1, tc = 0; + struct net_device *dev = queue->dev; +- int cpu, len, num_tc = 1, tc = 0; + struct xps_dev_maps *dev_maps; + cpumask_var_t mask; + unsigned long index; +@@ -1246,22 +1246,31 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue, + + index = get_netdev_queue_index(queue); + ++ if (!rtnl_trylock()) ++ return restart_syscall(); ++ + if (dev->num_tc) { + /* Do not allow XPS on subordinate device directly */ + num_tc = dev->num_tc; +- if (num_tc < 0) +- return -EINVAL; ++ if (num_tc < 0) { ++ ret = -EINVAL; ++ goto err_rtnl_unlock; ++ } + + /* If queue belongs to subordinate dev use its map */ + dev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev; + + tc = netdev_txq_to_tc(dev, index); +- if (tc < 0) +- return -EINVAL; ++ if (tc < 0) { ++ ret = -EINVAL; ++ goto err_rtnl_unlock; ++ } + } + +- if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) +- return -ENOMEM; ++ if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) { ++ ret = -ENOMEM; ++ goto err_rtnl_unlock; ++ } + + rcu_read_lock(); + dev_maps = rcu_dereference(dev->xps_cpus_map); +@@ -1284,9 +1293,15 @@ static ssize_t xps_cpus_show(struct netdev_queue *queue, + } + rcu_read_unlock(); + ++ rtnl_unlock(); ++ + len = snprintf(buf, PAGE_SIZE, "%*pb\n", cpumask_pr_args(mask)); + free_cpumask_var(mask); + return len < PAGE_SIZE ? len : -EINVAL; ++ ++err_rtnl_unlock: ++ rtnl_unlock(); ++ return ret; + } + + static ssize_t xps_cpus_store(struct netdev_queue *queue, +@@ -1314,7 +1329,13 @@ static ssize_t xps_cpus_store(struct netdev_queue *queue, + return err; + } + ++ if (!rtnl_trylock()) { ++ free_cpumask_var(mask); ++ return restart_syscall(); ++ } ++ + err = netif_set_xps_queue(dev, mask, index); ++ rtnl_unlock(); + + free_cpumask_var(mask); + +@@ -1326,22 +1347,29 @@ static struct netdev_queue_attribute xps_cpus_attribute __ro_after_init + + static ssize_t xps_rxqs_show(struct netdev_queue *queue, char *buf) + { ++ int j, len, ret, num_tc = 1, tc = 0; + struct net_device *dev = queue->dev; + struct xps_dev_maps *dev_maps; + unsigned long *mask, index; +- int j, len, num_tc = 1, tc = 0; + + index = get_netdev_queue_index(queue); + ++ if (!rtnl_trylock()) ++ return restart_syscall(); ++ + if (dev->num_tc) { + num_tc = dev->num_tc; + tc = netdev_txq_to_tc(dev, index); +- if (tc < 0) +- return -EINVAL; ++ if (tc < 0) { ++ ret = -EINVAL; ++ goto err_rtnl_unlock; ++ } + } + mask = bitmap_zalloc(dev->num_rx_queues, GFP_KERNEL); +- if (!mask) +- return -ENOMEM; ++ if (!mask) { ++ ret = -ENOMEM; ++ goto err_rtnl_unlock; ++ } + + rcu_read_lock(); + dev_maps = rcu_dereference(dev->xps_rxqs_map); +@@ -1367,10 +1395,16 @@ static ssize_t xps_rxqs_show(struct netdev_queue *queue, char *buf) + out_no_maps: + rcu_read_unlock(); + ++ rtnl_unlock(); ++ + len = bitmap_print_to_pagebuf(false, buf, mask, dev->num_rx_queues); + bitmap_free(mask); + + return len < PAGE_SIZE ? len : -EINVAL; ++ ++err_rtnl_unlock: ++ rtnl_unlock(); ++ return ret; + } + + static ssize_t xps_rxqs_store(struct netdev_queue *queue, const char *buf, +@@ -1396,10 +1430,17 @@ static ssize_t xps_rxqs_store(struct netdev_queue *queue, const char *buf, + return err; + } + ++ if (!rtnl_trylock()) { ++ bitmap_free(mask); ++ return restart_syscall(); ++ } ++ + cpus_read_lock(); + err = __netif_set_xps_queue(dev, mask, index, true); + cpus_read_unlock(); + ++ rtnl_unlock(); ++ + bitmap_free(mask); + return err ? : len; + } +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index da994f7e3def9..2ce191019526e 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -302,7 +302,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) + .flowi4_iif = LOOPBACK_IFINDEX, + .flowi4_oif = l3mdev_master_ifindex_rcu(dev), + .daddr = ip_hdr(skb)->saddr, +- .flowi4_tos = RT_TOS(ip_hdr(skb)->tos), ++ .flowi4_tos = ip_hdr(skb)->tos & IPTOS_RT_MASK, + .flowi4_scope = scope, + .flowi4_mark = vmark ? skb->mark : 0, + }; +diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c +index 66fdbfe5447cd..5d1e6fe9d8387 100644 +--- a/net/ipv4/gre_demux.c ++++ b/net/ipv4/gre_demux.c +@@ -128,7 +128,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + * to 0 and sets the configured key in the + * inner erspan header field + */ +- if (greh->protocol == htons(ETH_P_ERSPAN) || ++ if ((greh->protocol == htons(ETH_P_ERSPAN) && hdr_len != 4) || + greh->protocol == htons(ETH_P_ERSPAN2)) { + struct erspan_base_hdr *ershdr; + +diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c +index 8a6a4384e7916..12d242fedffdc 100644 +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -1406,7 +1406,7 @@ static int compat_get_entries(struct net *net, + xt_compat_lock(NFPROTO_ARP); + t = xt_find_table_lock(net, NFPROTO_ARP, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = t->private; ++ const struct xt_table_info *private = xt_table_get_private_protected(t); + struct xt_table_info info; + + ret = compat_table_info(private, &info); +diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c +index 4852769995440..cbbc8a7b82788 100644 +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -1616,7 +1616,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, + xt_compat_lock(AF_INET); + t = xt_find_table_lock(net, AF_INET, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = t->private; ++ const struct xt_table_info *private = xt_table_get_private_protected(t); + struct xt_table_info info; + ret = compat_table_info(private, &info); + if (!ret && get.size == info.size) +diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c +index 12735ee7713a7..01cdde25eb16d 100644 +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -1625,7 +1625,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, + xt_compat_lock(AF_INET6); + t = xt_find_table_lock(net, AF_INET6, get.name); + if (!IS_ERR(t)) { +- const struct xt_table_info *private = t->private; ++ const struct xt_table_info *private = xt_table_get_private_protected(t); + struct xt_table_info info; + ret = compat_table_info(private, &info); + if (!ret && get.size == info.size) +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index d5611f04926de..7c893c3799202 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -1114,7 +1114,7 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, + int payload, i, ret; + + /* Find the NCSI device */ +- nd = ncsi_find_dev(dev); ++ nd = ncsi_find_dev(orig_dev); + ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL; + if (!ndp) + return -ENODEV; +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index a7a982a3e6761..1a58cfdb862d6 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -143,20 +143,6 @@ htable_size(u8 hbits) + return hsize * sizeof(struct hbucket *) + sizeof(struct htable); + } + +-/* Compute htable_bits from the user input parameter hashsize */ +-static u8 +-htable_bits(u32 hashsize) +-{ +- /* Assume that hashsize == 2^htable_bits */ +- u8 bits = fls(hashsize - 1); +- +- if (jhash_size(bits) != hashsize) +- /* Round up to the first 2^n value */ +- bits = fls(hashsize); +- +- return bits; +-} +- + #ifdef IP_SET_HASH_WITH_NETS + #if IPSET_NET_COUNT > 1 + #define __CIDR(cidr, i) (cidr[i]) +@@ -1520,7 +1506,11 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + if (!h) + return -ENOMEM; + +- hbits = htable_bits(hashsize); ++ /* Compute htable_bits from the user input parameter hashsize. ++ * Assume that hashsize == 2^htable_bits, ++ * otherwise round up to the first 2^n value. ++ */ ++ hbits = fls(hashsize - 1); + hsize = htable_size(hbits); + if (hsize == 0) { + kfree(h); +diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c +index 217fd1bdc55e7..60236cc316d03 100644 +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -146,7 +146,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + u32 flags = ntohl(nla_get_be32(tb[NFTA_DYNSET_FLAGS])); + + if (flags & ~NFT_DYNSET_F_INV) +- return -EINVAL; ++ return -EOPNOTSUPP; + if (flags & NFT_DYNSET_F_INV) + priv->invert = true; + } +@@ -179,7 +179,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + timeout = 0; + if (tb[NFTA_DYNSET_TIMEOUT] != NULL) { + if (!(set->flags & NFT_SET_TIMEOUT)) +- return -EINVAL; ++ return -EOPNOTSUPP; + + err = nf_msecs_to_jiffies64(tb[NFTA_DYNSET_TIMEOUT], &timeout); + if (err) +@@ -193,7 +193,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + + if (tb[NFTA_DYNSET_SREG_DATA] != NULL) { + if (!(set->flags & NFT_SET_MAP)) +- return -EINVAL; ++ return -EOPNOTSUPP; + if (set->dtype == NFT_DATA_VERDICT) + return -EOPNOTSUPP; + +diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c +index 2236455b10a36..182c1285b4ada 100644 +--- a/net/netfilter/xt_RATEEST.c ++++ b/net/netfilter/xt_RATEEST.c +@@ -115,6 +115,9 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) + } cfg; + int ret; + ++ if (strnlen(info->name, sizeof(est->name)) >= sizeof(est->name)) ++ return -ENAMETOOLONG; ++ + net_get_random_once(&jhash_rnd, sizeof(jhash_rnd)); + + mutex_lock(&xn->hash_lock); +diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c +index 4021f726b58fd..d856b395ee8eb 100644 +--- a/net/sched/sch_choke.c ++++ b/net/sched/sch_choke.c +@@ -368,7 +368,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, + + ctl = nla_data(tb[TCA_CHOKE_PARMS]); + +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) + return -EINVAL; + + if (ctl->limit > CHOKE_MAX_QUEUE) +diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c +index 8599c6f31b057..e0bc77533acc3 100644 +--- a/net/sched/sch_gred.c ++++ b/net/sched/sch_gred.c +@@ -480,7 +480,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, + struct gred_sched *table = qdisc_priv(sch); + struct gred_sched_data *q = table->tab[dp]; + +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) { ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) { + NL_SET_ERR_MSG_MOD(extack, "invalid RED parameters"); + return -EINVAL; + } +diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c +index 1695421333e38..71e167e91a48d 100644 +--- a/net/sched/sch_red.c ++++ b/net/sched/sch_red.c +@@ -213,7 +213,7 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt, + max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; + + ctl = nla_data(tb[TCA_RED_PARMS]); +- if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog)) ++ if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log)) + return -EINVAL; + + if (ctl->limit > 0) { +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index 5a6def5e4e6df..6e13e137883c3 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -647,7 +647,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) + } + + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, +- ctl_v1->Wlog)) ++ ctl_v1->Wlog, ctl_v1->Scell_log)) + return -EINVAL; + if (ctl_v1 && ctl_v1->qth_min) { + p = kmalloc(sizeof(*p), GFP_KERNEL); +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index f2b1305e79d2f..09116be995113 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -1626,7 +1626,7 @@ static void taprio_destroy(struct Qdisc *sch) + taprio_disable_offload(dev, q, NULL); + + if (q->qdiscs) { +- for (i = 0; i < dev->num_tx_queues && q->qdiscs[i]; i++) ++ for (i = 0; i < dev->num_tx_queues; i++) + qdisc_put(q->qdiscs[i]); + + kfree(q->qdiscs); +diff --git a/scripts/depmod.sh b/scripts/depmod.sh +index e083bcae343f3..3643b4f896ede 100755 +--- a/scripts/depmod.sh ++++ b/scripts/depmod.sh +@@ -15,6 +15,8 @@ if ! test -r System.map ; then + exit 0 + fi + ++# legacy behavior: "depmod" in /sbin, no /sbin in PATH ++PATH="$PATH:/sbin" + if [ -z $(command -v $DEPMOD) ]; then + echo "Warning: 'make modules_install' requires $DEPMOD. Please install it." >&2 + echo "This is probably in the kmod package." >&2 +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 192e580561efd..5f515a29668c8 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2186,8 +2186,6 @@ static struct snd_pci_quirk power_save_blacklist[] = { + SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ + SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), +- /* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */ +- SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ + SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 396b5503038ad..c3a1ce129b3d9 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -1075,6 +1075,7 @@ static int patch_conexant_auto(struct hda_codec *codec) + static const struct hda_device_id snd_hda_id_conexant[] = { + HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), ++ HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto), +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index ec0938923f5de..8adbe45a54c11 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6236,6 +6236,7 @@ enum { + ALC221_FIXUP_HP_FRONT_MIC, + ALC292_FIXUP_TPT460, + ALC298_FIXUP_SPK_VOLUME, ++ ALC298_FIXUP_LENOVO_SPK_VOLUME, + ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, + ALC269_FIXUP_ATIV_BOOK_8, + ALC221_FIXUP_HP_MIC_NO_PRESENCE, +@@ -7062,6 +7063,10 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, + }, ++ [ALC298_FIXUP_LENOVO_SPK_VOLUME] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc298_fixup_speaker_volume, ++ }, + [ALC295_FIXUP_DISABLE_DAC3] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc295_fixup_disable_dac3, +@@ -7875,6 +7880,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), ++ SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), +@@ -7935,6 +7941,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), + SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), + SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), ++ SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), ++ SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), + SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), +@@ -8040,6 +8048,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), ++ SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), +diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c +index 7ef8f3105cdb7..0ab40a8a68fb5 100644 +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1002,6 +1002,7 @@ static const struct hda_verb vt1802_init_verbs[] = { + enum { + VIA_FIXUP_INTMIC_BOOST, + VIA_FIXUP_ASUS_G75, ++ VIA_FIXUP_POWER_SAVE, + }; + + static void via_fixup_intmic_boost(struct hda_codec *codec, +@@ -1011,6 +1012,13 @@ static void via_fixup_intmic_boost(struct hda_codec *codec, + override_mic_boost(codec, 0x30, 0, 2, 40); + } + ++static void via_fixup_power_save(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ codec->power_save_node = 0; ++} ++ + static const struct hda_fixup via_fixups[] = { + [VIA_FIXUP_INTMIC_BOOST] = { + .type = HDA_FIXUP_FUNC, +@@ -1025,11 +1033,16 @@ static const struct hda_fixup via_fixups[] = { + { } + } + }, ++ [VIA_FIXUP_POWER_SAVE] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = via_fixup_power_save, ++ }, + }; + + static const struct snd_pci_quirk vt2002p_fixups[] = { + SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), + SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), ++ SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", VIA_FIXUP_POWER_SAVE), + {} + }; + +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index bc9068b616bb9..1cc17c449407c 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1889,6 +1889,8 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi *umidi, + ms_ep = find_usb_ms_endpoint_descriptor(hostep); + if (!ms_ep) + continue; ++ if (ms_ep->bNumEmbMIDIJack > 0x10) ++ continue; + if (usb_endpoint_dir_out(ep)) { + if (endpoints[epidx].out_ep) { + if (++epidx >= MIDI_MAX_ENDPOINTS) { +@@ -2141,6 +2143,8 @@ static int snd_usbmidi_detect_roland(struct snd_usb_midi *umidi, + cs_desc[1] == USB_DT_CS_INTERFACE && + cs_desc[2] == 0xf1 && + cs_desc[3] == 0x02) { ++ if (cs_desc[4] > 0x10 || cs_desc[5] > 0x10) ++ continue; + endpoint->in_cables = (1 << cs_desc[4]) - 1; + endpoint->out_cables = (1 << cs_desc[5]) - 1; + return snd_usbmidi_detect_endpoints(umidi, endpoint, 1); +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 1dfa49d26de91..8f3b40ec02b77 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -428,9 +428,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, + kvm->mmu_notifier_count++; + need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end, + range->flags); +- need_tlb_flush |= kvm->tlbs_dirty; + /* we've to flush the tlb before the pages can be freed */ +- if (need_tlb_flush) ++ if (need_tlb_flush || kvm->tlbs_dirty) + kvm_flush_remote_tlbs(kvm); + + spin_unlock(&kvm->mmu_lock); diff --git a/patch/kernel/odroidxu4-current/patch-5.4.89-90.patch b/patch/kernel/odroidxu4-current/patch-5.4.89-90.patch new file mode 100644 index 0000000000..bc5ebac353 --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-5.4.89-90.patch @@ -0,0 +1,1787 @@ +diff --git a/Makefile b/Makefile +index 95848875110ef..5c9d680b7ce51 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 89 ++SUBLEVEL = 90 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c +index 3acb4192918df..f85a0fd6aca5c 100644 +--- a/arch/arm/mach-omap2/omap_device.c ++++ b/arch/arm/mach-omap2/omap_device.c +@@ -234,10 +234,12 @@ static int _omap_device_notifier_call(struct notifier_block *nb, + break; + case BUS_NOTIFY_BIND_DRIVER: + od = to_omap_device(pdev); +- if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && +- pm_runtime_status_suspended(dev)) { ++ if (od) { + od->_driver_status = BUS_NOTIFY_BIND_DRIVER; +- pm_runtime_set_active(dev); ++ if (od->_state == OMAP_DEVICE_STATE_ENABLED && ++ pm_runtime_status_suspended(dev)) { ++ pm_runtime_set_active(dev); ++ } + } + break; + case BUS_NOTIFY_ADD_DEVICE: +diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c +index 6478635ff2142..98a177dd1f89f 100644 +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -625,6 +625,10 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) + { + u64 pmcr, val; + ++ /* No PMU available, PMCR_EL0 may UNDEF... */ ++ if (!kvm_arm_support_pmu_v3()) ++ return; ++ + pmcr = read_sysreg(pmcr_el0); + /* + * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN +diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S +index 390edb7638265..bde3e0f85425f 100644 +--- a/arch/x86/entry/entry_32.S ++++ b/arch/x86/entry/entry_32.S +@@ -869,9 +869,10 @@ GLOBAL(__begin_SYSENTER_singlestep_region) + * Xen doesn't set %esp to be precisely what the normal SYSENTER + * entry point expects, so fix it up before using the normal path. + */ +-ENTRY(xen_sysenter_target) ++SYM_CODE_START(xen_sysenter_target) + addl $5*4, %esp /* remove xen-provided frame */ + jmp .Lsysenter_past_esp ++SYM_CODE_END(xen_sysenter_target) + #endif + + /* +diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S +index e95e95960156b..5b076cb79f5fb 100644 +--- a/arch/x86/kernel/acpi/wakeup_32.S ++++ b/arch/x86/kernel/acpi/wakeup_32.S +@@ -9,8 +9,7 @@ + .code32 + ALIGN + +-ENTRY(wakeup_pmode_return) +-wakeup_pmode_return: ++SYM_CODE_START(wakeup_pmode_return) + movw $__KERNEL_DS, %ax + movw %ax, %ss + movw %ax, %fs +@@ -39,6 +38,7 @@ wakeup_pmode_return: + # jump to place where we left off + movl saved_eip, %eax + jmp *%eax ++SYM_CODE_END(wakeup_pmode_return) + + bogus_magic: + jmp bogus_magic +@@ -72,7 +72,7 @@ restore_registers: + popfl + ret + +-ENTRY(do_suspend_lowlevel) ++SYM_CODE_START(do_suspend_lowlevel) + call save_processor_state + call save_registers + pushl $3 +@@ -87,6 +87,7 @@ ret_point: + call restore_registers + call restore_processor_state + ret ++SYM_CODE_END(do_suspend_lowlevel) + + .data + ALIGN +diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c +index 830ccc396e26d..28f786289fce4 100644 +--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c ++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c +@@ -525,85 +525,70 @@ static void rdtgroup_remove(struct rdtgroup *rdtgrp) + kfree(rdtgrp); + } + +-struct task_move_callback { +- struct callback_head work; +- struct rdtgroup *rdtgrp; +-}; +- +-static void move_myself(struct callback_head *head) ++static void _update_task_closid_rmid(void *task) + { +- struct task_move_callback *callback; +- struct rdtgroup *rdtgrp; +- +- callback = container_of(head, struct task_move_callback, work); +- rdtgrp = callback->rdtgrp; +- + /* +- * If resource group was deleted before this task work callback +- * was invoked, then assign the task to root group and free the +- * resource group. ++ * If the task is still current on this CPU, update PQR_ASSOC MSR. ++ * Otherwise, the MSR is updated when the task is scheduled in. + */ +- if (atomic_dec_and_test(&rdtgrp->waitcount) && +- (rdtgrp->flags & RDT_DELETED)) { +- current->closid = 0; +- current->rmid = 0; +- rdtgroup_remove(rdtgrp); +- } +- +- preempt_disable(); +- /* update PQR_ASSOC MSR to make resource group go into effect */ +- resctrl_sched_in(); +- preempt_enable(); ++ if (task == current) ++ resctrl_sched_in(); ++} + +- kfree(callback); ++static void update_task_closid_rmid(struct task_struct *t) ++{ ++ if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) ++ smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); ++ else ++ _update_task_closid_rmid(t); + } + + static int __rdtgroup_move_task(struct task_struct *tsk, + struct rdtgroup *rdtgrp) + { +- struct task_move_callback *callback; +- int ret; +- +- callback = kzalloc(sizeof(*callback), GFP_KERNEL); +- if (!callback) +- return -ENOMEM; +- callback->work.func = move_myself; +- callback->rdtgrp = rdtgrp; ++ /* If the task is already in rdtgrp, no need to move the task. */ ++ if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && ++ tsk->rmid == rdtgrp->mon.rmid) || ++ (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && ++ tsk->closid == rdtgrp->mon.parent->closid)) ++ return 0; + + /* +- * Take a refcount, so rdtgrp cannot be freed before the +- * callback has been invoked. ++ * Set the task's closid/rmid before the PQR_ASSOC MSR can be ++ * updated by them. ++ * ++ * For ctrl_mon groups, move both closid and rmid. ++ * For monitor groups, can move the tasks only from ++ * their parent CTRL group. + */ +- atomic_inc(&rdtgrp->waitcount); +- ret = task_work_add(tsk, &callback->work, true); +- if (ret) { +- /* +- * Task is exiting. Drop the refcount and free the callback. +- * No need to check the refcount as the group cannot be +- * deleted before the write function unlocks rdtgroup_mutex. +- */ +- atomic_dec(&rdtgrp->waitcount); +- kfree(callback); +- rdt_last_cmd_puts("Task exited\n"); +- } else { +- /* +- * For ctrl_mon groups move both closid and rmid. +- * For monitor groups, can move the tasks only from +- * their parent CTRL group. +- */ +- if (rdtgrp->type == RDTCTRL_GROUP) { +- tsk->closid = rdtgrp->closid; ++ ++ if (rdtgrp->type == RDTCTRL_GROUP) { ++ tsk->closid = rdtgrp->closid; ++ tsk->rmid = rdtgrp->mon.rmid; ++ } else if (rdtgrp->type == RDTMON_GROUP) { ++ if (rdtgrp->mon.parent->closid == tsk->closid) { + tsk->rmid = rdtgrp->mon.rmid; +- } else if (rdtgrp->type == RDTMON_GROUP) { +- if (rdtgrp->mon.parent->closid == tsk->closid) { +- tsk->rmid = rdtgrp->mon.rmid; +- } else { +- rdt_last_cmd_puts("Can't move task to different control group\n"); +- ret = -EINVAL; +- } ++ } else { ++ rdt_last_cmd_puts("Can't move task to different control group\n"); ++ return -EINVAL; + } + } +- return ret; ++ ++ /* ++ * Ensure the task's closid and rmid are written before determining if ++ * the task is current that will decide if it will be interrupted. ++ */ ++ barrier(); ++ ++ /* ++ * By now, the task's closid and rmid are set. If the task is current ++ * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource ++ * group go into effect. If the task is not current, the MSR will be ++ * updated when the task is scheduled in. ++ */ ++ update_task_closid_rmid(tsk); ++ ++ return 0; + } + + /** +diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S +index 073aab525d800..2cc0303522c99 100644 +--- a/arch/x86/kernel/ftrace_32.S ++++ b/arch/x86/kernel/ftrace_32.S +@@ -89,7 +89,7 @@ WEAK(ftrace_stub) + ret + END(ftrace_caller) + +-ENTRY(ftrace_regs_caller) ++SYM_CODE_START(ftrace_regs_caller) + /* + * We're here from an mcount/fentry CALL, and the stack frame looks like: + * +@@ -163,6 +163,7 @@ GLOBAL(ftrace_regs_call) + popl %eax + + jmp .Lftrace_ret ++SYM_CODE_END(ftrace_regs_caller) + + #ifdef CONFIG_FUNCTION_GRAPH_TRACER + ENTRY(ftrace_graph_caller) +diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S +index 2e6a0676c1f43..11a5d5ade52ce 100644 +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -64,7 +64,7 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE) + * can. + */ + __HEAD +-ENTRY(startup_32) ++SYM_CODE_START(startup_32) + movl pa(initial_stack),%ecx + + /* test KEEP_SEGMENTS flag to see if the bootloader is asking +@@ -172,6 +172,7 @@ num_subarch_entries = (. - subarch_entries) / 4 + #else + jmp .Ldefault_entry + #endif /* CONFIG_PARAVIRT */ ++SYM_CODE_END(startup_32) + + #ifdef CONFIG_HOTPLUG_CPU + /* +diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S +index 6fe383002125f..a19ed3d231853 100644 +--- a/arch/x86/power/hibernate_asm_32.S ++++ b/arch/x86/power/hibernate_asm_32.S +@@ -35,7 +35,7 @@ ENTRY(swsusp_arch_suspend) + ret + ENDPROC(swsusp_arch_suspend) + +-ENTRY(restore_image) ++SYM_CODE_START(restore_image) + /* prepare to jump to the image kernel */ + movl restore_jump_address, %ebx + movl restore_cr3, %ebp +@@ -45,9 +45,10 @@ ENTRY(restore_image) + /* jump to relocated restore code */ + movl relocated_restore_code, %eax + jmpl *%eax ++SYM_CODE_END(restore_image) + + /* code below has been relocated to a safe page */ +-ENTRY(core_restore_code) ++SYM_CODE_START(core_restore_code) + movl temp_pgt, %eax + movl %eax, %cr3 + +@@ -77,6 +78,7 @@ copy_loop: + + done: + jmpl *%ebx ++SYM_CODE_END(core_restore_code) + + /* code below belongs to the image kernel */ + .align PAGE_SIZE +diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S +index 1868b158480d4..3a0ef0d577344 100644 +--- a/arch/x86/realmode/rm/trampoline_32.S ++++ b/arch/x86/realmode/rm/trampoline_32.S +@@ -29,7 +29,7 @@ + .code16 + + .balign PAGE_SIZE +-ENTRY(trampoline_start) ++SYM_CODE_START(trampoline_start) + wbinvd # Needed for NUMA-Q should be harmless for others + + LJMPW_RM(1f) +@@ -54,11 +54,13 @@ ENTRY(trampoline_start) + lmsw %dx # into protected mode + + ljmpl $__BOOT_CS, $pa_startup_32 ++SYM_CODE_END(trampoline_start) + + .section ".text32","ax" + .code32 +-ENTRY(startup_32) # note: also used from wakeup_asm.S ++SYM_CODE_START(startup_32) # note: also used from wakeup_asm.S + jmp *%eax ++SYM_CODE_END(startup_32) + + .bss + .balign 8 +diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S +index cd177772fe4d5..2712e91553063 100644 +--- a/arch/x86/xen/xen-asm_32.S ++++ b/arch/x86/xen/xen-asm_32.S +@@ -56,7 +56,7 @@ + _ASM_EXTABLE(1b,2b) + .endm + +-ENTRY(xen_iret) ++SYM_CODE_START(xen_iret) + /* test eflags for special cases */ + testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp) + jnz hyper_iret +@@ -122,6 +122,7 @@ xen_iret_end_crit: + hyper_iret: + /* put this out of line since its very rarely used */ + jmp hypercall_page + __HYPERVISOR_iret * 32 ++SYM_CODE_END(xen_iret) + + .globl xen_iret_start_crit, xen_iret_end_crit + +@@ -152,7 +153,7 @@ hyper_iret: + * The only caveat is that if the outer eax hasn't been restored yet (i.e. + * it's still on stack), we need to restore its value here. + */ +-ENTRY(xen_iret_crit_fixup) ++SYM_CODE_START(xen_iret_crit_fixup) + /* + * Paranoia: Make sure we're really coming from kernel space. + * One could imagine a case where userspace jumps into the +@@ -179,4 +180,4 @@ ENTRY(xen_iret_crit_fixup) + + 2: + ret +-END(xen_iret_crit_fixup) ++SYM_CODE_END(xen_iret_crit_fixup) +diff --git a/block/genhd.c b/block/genhd.c +index 26b31fcae217f..604f0a2cbc9a0 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -222,14 +222,17 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter) + part = rcu_dereference(ptbl->part[piter->idx]); + if (!part) + continue; ++ get_device(part_to_dev(part)); ++ piter->part = part; + if (!part_nr_sects_read(part) && + !(piter->flags & DISK_PITER_INCL_EMPTY) && + !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && +- piter->idx == 0)) ++ piter->idx == 0)) { ++ put_device(part_to_dev(part)); ++ piter->part = NULL; + continue; ++ } + +- get_device(part_to_dev(part)); +- piter->part = part; + piter->idx += inc; + break; + } +diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c +index f58baff2be0af..398991381e9af 100644 +--- a/drivers/base/regmap/regmap-debugfs.c ++++ b/drivers/base/regmap/regmap-debugfs.c +@@ -583,8 +583,12 @@ void regmap_debugfs_init(struct regmap *map, const char *name) + devname = dev_name(map->dev); + + if (name) { +- map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", ++ if (!map->debugfs_name) { ++ map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", + devname, name); ++ if (!map->debugfs_name) ++ return; ++ } + name = map->debugfs_name; + } else { + name = devname; +@@ -592,9 +596,10 @@ void regmap_debugfs_init(struct regmap *map, const char *name) + + if (!strcmp(name, "dummy")) { + kfree(map->debugfs_name); +- + map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", + dummy_index); ++ if (!map->debugfs_name) ++ return; + name = map->debugfs_name; + dummy_index++; + } +diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig +index 1bb8ec5753527..0fc27ac14f29c 100644 +--- a/drivers/block/Kconfig ++++ b/drivers/block/Kconfig +@@ -461,6 +461,7 @@ config BLK_DEV_RBD + config BLK_DEV_RSXX + tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" + depends on PCI ++ select CRC32 + help + Device driver for IBM's high speed PCIe SSD + storage device: Flash Adapter 900GB Full Height. +diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c +index 2db2f1739e092..1b2ec3be59eb7 100644 +--- a/drivers/cpufreq/powernow-k8.c ++++ b/drivers/cpufreq/powernow-k8.c +@@ -878,9 +878,9 @@ static int get_transition_latency(struct powernow_k8_data *data) + + /* Take a frequency, and issue the fid/vid transition command */ + static int transition_frequency_fidvid(struct powernow_k8_data *data, +- unsigned int index) ++ unsigned int index, ++ struct cpufreq_policy *policy) + { +- struct cpufreq_policy *policy; + u32 fid = 0; + u32 vid = 0; + int res; +@@ -912,9 +912,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, + freqs.old = find_khz_freq_from_fid(data->currfid); + freqs.new = find_khz_freq_from_fid(fid); + +- policy = cpufreq_cpu_get(smp_processor_id()); +- cpufreq_cpu_put(policy); +- + cpufreq_freq_transition_begin(policy, &freqs); + res = transition_fid_vid(data, fid, vid); + cpufreq_freq_transition_end(policy, &freqs, res); +@@ -969,7 +966,7 @@ static long powernowk8_target_fn(void *arg) + + powernow_k8_acpi_pst_values(data, newstate); + +- ret = transition_frequency_fidvid(data, newstate); ++ ret = transition_frequency_fidvid(data, newstate, pol); + + if (ret) { + pr_err("transition frequency failed\n"); +diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c +index f81a5e35d8fd1..eddc6d1bdb2d1 100644 +--- a/drivers/crypto/chelsio/chtls/chtls_cm.c ++++ b/drivers/crypto/chelsio/chtls/chtls_cm.c +@@ -577,7 +577,7 @@ static void chtls_reset_synq(struct listen_ctx *listen_ctx) + + while (!skb_queue_empty(&listen_ctx->synq)) { + struct chtls_sock *csk = +- container_of((struct synq *)__skb_dequeue ++ container_of((struct synq *)skb_peek + (&listen_ctx->synq), struct chtls_sock, synq); + struct sock *child = csk->sk; + +@@ -1021,6 +1021,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + const struct cpl_pass_accept_req *req, + struct chtls_dev *cdev) + { ++ struct adapter *adap = pci_get_drvdata(cdev->pdev); + struct inet_sock *newinet; + const struct iphdr *iph; + struct tls_context *ctx; +@@ -1030,9 +1031,10 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + struct neighbour *n; + struct tcp_sock *tp; + struct sock *newsk; ++ bool found = false; + u16 port_id; + int rxq_idx; +- int step; ++ int step, i; + + iph = (const struct iphdr *)network_hdr; + newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb); +@@ -1044,7 +1046,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + goto free_sk; + + n = dst_neigh_lookup(dst, &iph->saddr); +- if (!n) ++ if (!n || !n->dev) + goto free_sk; + + ndev = n->dev; +@@ -1053,6 +1055,13 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + if (is_vlan_dev(ndev)) + ndev = vlan_dev_real_dev(ndev); + ++ for_each_port(adap, i) ++ if (cdev->ports[i] == ndev) ++ found = true; ++ ++ if (!found) ++ goto free_dst; ++ + port_id = cxgb4_port_idx(ndev); + + csk = chtls_sock_create(cdev); +@@ -1108,6 +1117,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + free_csk: + chtls_sock_release(&csk->kref); + free_dst: ++ neigh_release(n); + dst_release(dst); + free_sk: + inet_csk_prepare_forced_close(newsk); +@@ -1443,6 +1453,11 @@ static int chtls_pass_establish(struct chtls_dev *cdev, struct sk_buff *skb) + sk_wake_async(sk, 0, POLL_OUT); + + data = lookup_stid(cdev->tids, stid); ++ if (!data) { ++ /* listening server close */ ++ kfree_skb(skb); ++ goto unlock; ++ } + lsk = ((struct listen_ctx *)data)->lsk; + + bh_lock_sock(lsk); +@@ -1828,39 +1843,6 @@ static void send_defer_abort_rpl(struct chtls_dev *cdev, struct sk_buff *skb) + kfree_skb(skb); + } + +-static void send_abort_rpl(struct sock *sk, struct sk_buff *skb, +- struct chtls_dev *cdev, int status, int queue) +-{ +- struct cpl_abort_req_rss *req = cplhdr(skb); +- struct sk_buff *reply_skb; +- struct chtls_sock *csk; +- +- csk = rcu_dereference_sk_user_data(sk); +- +- reply_skb = alloc_skb(sizeof(struct cpl_abort_rpl), +- GFP_KERNEL); +- +- if (!reply_skb) { +- req->status = (queue << 1); +- send_defer_abort_rpl(cdev, skb); +- return; +- } +- +- set_abort_rpl_wr(reply_skb, GET_TID(req), status); +- kfree_skb(skb); +- +- set_wr_txq(reply_skb, CPL_PRIORITY_DATA, queue); +- if (csk_conn_inline(csk)) { +- struct l2t_entry *e = csk->l2t_entry; +- +- if (e && sk->sk_state != TCP_SYN_RECV) { +- cxgb4_l2t_send(csk->egress_dev, reply_skb, e); +- return; +- } +- } +- cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); +-} +- + /* + * Add an skb to the deferred skb queue for processing from process context. + */ +@@ -1923,9 +1905,9 @@ static void bl_abort_syn_rcv(struct sock *lsk, struct sk_buff *skb) + queue = csk->txq_idx; + + skb->sk = NULL; ++ chtls_send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, ++ CPL_ABORT_NO_RST, queue); + do_abort_syn_rcv(child, lsk); +- send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, +- CPL_ABORT_NO_RST, queue); + } + + static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) +@@ -1955,8 +1937,8 @@ static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) + if (!sock_owned_by_user(psk)) { + int queue = csk->txq_idx; + ++ chtls_send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); + do_abort_syn_rcv(sk, psk); +- send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); + } else { + skb->sk = sk; + BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv; +@@ -1974,9 +1956,6 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb) + int queue = csk->txq_idx; + + if (is_neg_adv(req->status)) { +- if (sk->sk_state == TCP_SYN_RECV) +- chtls_set_tcb_tflag(sk, 0, 0); +- + kfree_skb(skb); + return; + } +@@ -2002,12 +1981,11 @@ static void chtls_abort_req_rss(struct sock *sk, struct sk_buff *skb) + + if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb)) + return; +- +- chtls_release_resources(sk); +- chtls_conn_done(sk); + } + + chtls_send_abort_rpl(sk, skb, csk->cdev, rst_status, queue); ++ chtls_release_resources(sk); ++ chtls_conn_done(sk); + } + + static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb) +diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c +index 7f9a86c3c58ff..31577316f80bc 100644 +--- a/drivers/dma/dw-edma/dw-edma-core.c ++++ b/drivers/dma/dw-edma/dw-edma-core.c +@@ -85,12 +85,12 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc) + + if (desc->chunk) { + /* Create and add new element into the linked list */ +- desc->chunks_alloc++; +- list_add_tail(&chunk->list, &desc->chunk->list); + if (!dw_edma_alloc_burst(chunk)) { + kfree(chunk); + return NULL; + } ++ desc->chunks_alloc++; ++ list_add_tail(&chunk->list, &desc->chunk->list); + } else { + /* List head */ + chunk->burst = NULL; +diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c +index 4c58da7421432..04d89eec11e74 100644 +--- a/drivers/dma/mediatek/mtk-hsdma.c ++++ b/drivers/dma/mediatek/mtk-hsdma.c +@@ -1007,6 +1007,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) + return 0; + + err_free: ++ mtk_hsdma_hw_deinit(hsdma); + of_dma_controller_free(pdev->dev.of_node); + err_unregister: + dma_async_device_unregister(dd); +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index a6abfe702c5a3..1b5f3e9f43d70 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -2431,7 +2431,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, + has_dre = false; + + if (!has_dre) +- xdev->common.copy_align = fls(width - 1); ++ xdev->common.copy_align = (enum dmaengine_alignment)fls(width - 1); + + if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || + of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || +@@ -2543,7 +2543,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, + static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, + struct device_node *node) + { +- int ret, i, nr_channels = 1; ++ int ret, i; ++ u32 nr_channels = 1; + + ret = of_property_read_u32(node, "dma-channels", &nr_channels); + if ((ret < 0) && xdev->mcdma) +@@ -2742,7 +2743,11 @@ static int xilinx_dma_probe(struct platform_device *pdev) + } + + /* Register the DMA engine with the core */ +- dma_async_device_register(&xdev->common); ++ err = dma_async_device_register(&xdev->common); ++ if (err) { ++ dev_err(xdev->dev, "failed to register the dma device\n"); ++ goto error; ++ } + + err = of_dma_controller_register(node, of_dma_xilinx_xlate, + xdev); +diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c +index cd71e71339446..9e852b4bbf92b 100644 +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -1270,6 +1270,37 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, + group); + } + ++static void wacom_devm_kfifo_release(struct device *dev, void *res) ++{ ++ struct kfifo_rec_ptr_2 *devres = res; ++ ++ kfifo_free(devres); ++} ++ ++static int wacom_devm_kfifo_alloc(struct wacom *wacom) ++{ ++ struct wacom_wac *wacom_wac = &wacom->wacom_wac; ++ struct kfifo_rec_ptr_2 *pen_fifo = &wacom_wac->pen_fifo; ++ int error; ++ ++ pen_fifo = devres_alloc(wacom_devm_kfifo_release, ++ sizeof(struct kfifo_rec_ptr_2), ++ GFP_KERNEL); ++ ++ if (!pen_fifo) ++ return -ENOMEM; ++ ++ error = kfifo_alloc(pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); ++ if (error) { ++ devres_free(pen_fifo); ++ return error; ++ } ++ ++ devres_add(&wacom->hdev->dev, pen_fifo); ++ ++ return 0; ++} ++ + enum led_brightness wacom_leds_brightness_get(struct wacom_led *led) + { + struct wacom *wacom = led->wacom; +@@ -2724,7 +2755,7 @@ static int wacom_probe(struct hid_device *hdev, + if (features->check_for_hid_type && features->hid_type != hdev->type) + return -ENODEV; + +- error = kfifo_alloc(&wacom_wac->pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); ++ error = wacom_devm_kfifo_alloc(wacom); + if (error) + return error; + +@@ -2786,8 +2817,6 @@ static void wacom_remove(struct hid_device *hdev) + + if (wacom->wacom_wac.features.type != REMOTE) + wacom_release_resources(wacom); +- +- kfifo_free(&wacom_wac->pen_fifo); + } + + #ifdef CONFIG_PM +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index c40eef4e7a985..2b6a4c1f188f4 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -1424,7 +1424,7 @@ static int i801_add_mux(struct i801_priv *priv) + + /* Register GPIO descriptor lookup table */ + lookup = devm_kzalloc(dev, +- struct_size(lookup, table, mux_config->n_gpios), ++ struct_size(lookup, table, mux_config->n_gpios + 1), + GFP_KERNEL); + if (!lookup) + return -ENOMEM; +diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c +index b432e7580458d..b2dc802864641 100644 +--- a/drivers/i2c/busses/i2c-sprd.c ++++ b/drivers/i2c/busses/i2c-sprd.c +@@ -72,6 +72,8 @@ + + /* timeout (ms) for pm runtime autosuspend */ + #define SPRD_I2C_PM_TIMEOUT 1000 ++/* timeout (ms) for transfer message */ ++#define I2C_XFER_TIMEOUT 1000 + + /* SPRD i2c data structure */ + struct sprd_i2c { +@@ -244,6 +246,7 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, + struct i2c_msg *msg, bool is_last_msg) + { + struct sprd_i2c *i2c_dev = i2c_adap->algo_data; ++ unsigned long time_left; + + i2c_dev->msg = msg; + i2c_dev->buf = msg->buf; +@@ -273,7 +276,10 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, + + sprd_i2c_opt_start(i2c_dev); + +- wait_for_completion(&i2c_dev->complete); ++ time_left = wait_for_completion_timeout(&i2c_dev->complete, ++ msecs_to_jiffies(I2C_XFER_TIMEOUT)); ++ if (!time_left) ++ return -ETIMEDOUT; + + return i2c_dev->err; + } +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +index b0f3da1976e4f..d1f2109012ed5 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +@@ -664,13 +664,29 @@ static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private) + static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) + { + struct st_lsm6dsx_hw *hw = private; +- int count; ++ int fifo_len = 0, len; + +- mutex_lock(&hw->fifo_lock); +- count = hw->settings->fifo_ops.read_fifo(hw); +- mutex_unlock(&hw->fifo_lock); ++ /* ++ * If we are using edge IRQs, new samples can arrive while ++ * processing current interrupt since there are no hw ++ * guarantees the irq line stays "low" long enough to properly ++ * detect the new interrupt. In this case the new sample will ++ * be missed. ++ * Polling FIFO status register allow us to read new ++ * samples even if the interrupt arrives while processing ++ * previous data and the timeslot where the line is "low" is ++ * too short to be properly detected. ++ */ ++ do { ++ mutex_lock(&hw->fifo_lock); ++ len = hw->settings->fifo_ops.read_fifo(hw); ++ mutex_unlock(&hw->fifo_lock); ++ ++ if (len > 0) ++ fifo_len += len; ++ } while (len > 0); + +- return count ? IRQ_HANDLED : IRQ_NONE; ++ return fifo_len ? IRQ_HANDLED : IRQ_NONE; + } + + static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev) +diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c +index f697f3a1d46bc..5dcc81b1df623 100644 +--- a/drivers/iommu/intel_irq_remapping.c ++++ b/drivers/iommu/intel_irq_remapping.c +@@ -1400,6 +1400,8 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain, + irq_data = irq_domain_get_irq_data(domain, virq + i); + irq_cfg = irqd_cfg(irq_data); + if (!irq_data || !irq_cfg) { ++ if (!i) ++ kfree(data); + ret = -EINVAL; + goto out_free_data; + } +diff --git a/drivers/lightnvm/Kconfig b/drivers/lightnvm/Kconfig +index 8f39f9ba5c80e..4c2ce210c1237 100644 +--- a/drivers/lightnvm/Kconfig ++++ b/drivers/lightnvm/Kconfig +@@ -19,6 +19,7 @@ if NVM + + config NVM_PBLK + tristate "Physical Block Device Open-Channel SSD target" ++ select CRC32 + help + Allows an open-channel SSD to be exposed as a block device to the + host. The target assumes the device exposes raw flash and must be +diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig +index 17c166cc8482d..e4d944770ccaf 100644 +--- a/drivers/net/can/Kconfig ++++ b/drivers/net/can/Kconfig +@@ -123,6 +123,7 @@ config CAN_JANZ_ICAN3 + config CAN_KVASER_PCIEFD + depends on PCI + tristate "Kvaser PCIe FD cards" ++ select CRC32 + help + This is a driver for the Kvaser PCI Express CAN FD family. + +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index d2bb9a87eff9a..8a842545e3f69 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -1868,8 +1868,6 @@ void m_can_class_unregister(struct m_can_classdev *m_can_dev) + { + unregister_candev(m_can_dev->net); + +- m_can_clk_stop(m_can_dev); +- + free_candev(m_can_dev->net); + } + EXPORT_SYMBOL_GPL(m_can_class_unregister); +diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c +index 681bb861de05e..1f8710b35c6d7 100644 +--- a/drivers/net/can/m_can/tcan4x5x.c ++++ b/drivers/net/can/m_can/tcan4x5x.c +@@ -126,30 +126,6 @@ struct tcan4x5x_priv { + int reg_offset; + }; + +-static struct can_bittiming_const tcan4x5x_bittiming_const = { +- .name = DEVICE_NAME, +- .tseg1_min = 2, +- .tseg1_max = 31, +- .tseg2_min = 2, +- .tseg2_max = 16, +- .sjw_max = 16, +- .brp_min = 1, +- .brp_max = 32, +- .brp_inc = 1, +-}; +- +-static struct can_bittiming_const tcan4x5x_data_bittiming_const = { +- .name = DEVICE_NAME, +- .tseg1_min = 1, +- .tseg1_max = 32, +- .tseg2_min = 1, +- .tseg2_max = 16, +- .sjw_max = 16, +- .brp_min = 1, +- .brp_max = 32, +- .brp_inc = 1, +-}; +- + static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) + { + int wake_state = 0; +@@ -449,8 +425,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi) + mcan_class->dev = &spi->dev; + mcan_class->ops = &tcan4x5x_ops; + mcan_class->is_peripheral = true; +- mcan_class->bit_timing = &tcan4x5x_bittiming_const; +- mcan_class->data_timing = &tcan4x5x_data_bittiming_const; + mcan_class->net->irq = spi->irq; + + spi_set_drvdata(spi, priv); +diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c +index 0d9b3fa7bd94e..ee1e67df1e7b4 100644 +--- a/drivers/net/dsa/lantiq_gswip.c ++++ b/drivers/net/dsa/lantiq_gswip.c +@@ -1419,11 +1419,12 @@ static void gswip_phylink_validate(struct dsa_switch *ds, int port, + phylink_set(mask, Pause); + phylink_set(mask, Asym_Pause); + +- /* With the exclusion of MII and Reverse MII, we support Gigabit, +- * including Half duplex ++ /* With the exclusion of MII, Reverse MII and Reduced MII, we ++ * support Gigabit, including Half duplex + */ + if (state->interface != PHY_INTERFACE_MODE_MII && +- state->interface != PHY_INTERFACE_MODE_REVMII) { ++ state->interface != PHY_INTERFACE_MODE_REVMII && ++ state->interface != PHY_INTERFACE_MODE_RMII) { + phylink_set(mask, 1000baseT_Full); + phylink_set(mask, 1000baseT_Half); + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +index f8a87f8ca9833..148e53812d89c 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +@@ -123,7 +123,7 @@ struct hclgevf_mbx_arq_ring { + #define hclge_mbx_ring_ptr_move_crq(crq) \ + (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) + #define hclge_mbx_tail_ptr_move_arq(arq) \ +- (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) ++ (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) + #define hclge_mbx_head_ptr_move_arq(arq) \ +- (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) ++ (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) + #endif +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 6c3d13110993f..6887b7fda6e07 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -746,7 +746,8 @@ static int hclge_get_sset_count(struct hnae3_handle *handle, int stringset) + handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; + handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; + +- if (hdev->hw.mac.phydev) { ++ if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv && ++ hdev->hw.mac.phydev->drv->set_loopback) { + count += 1; + handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK; + } +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index 8827ab4b4932e..6988bbf2576f5 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -4545,7 +4545,7 @@ static int mvpp2_port_init(struct mvpp2_port *port) + struct mvpp2 *priv = port->priv; + struct mvpp2_txq_pcpu *txq_pcpu; + unsigned int thread; +- int queue, err; ++ int queue, err, val; + + /* Checks for hardware constraints */ + if (port->first_rxq + port->nrxqs > +@@ -4559,6 +4559,18 @@ static int mvpp2_port_init(struct mvpp2_port *port) + mvpp2_egress_disable(port); + mvpp2_port_disable(port); + ++ if (mvpp2_is_xlg(port->phy_interface)) { ++ val = readl(port->base + MVPP22_XLG_CTRL0_REG); ++ val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_PASS; ++ val |= MVPP22_XLG_CTRL0_FORCE_LINK_DOWN; ++ writel(val, port->base + MVPP22_XLG_CTRL0_REG); ++ } else { ++ val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG); ++ val &= ~MVPP2_GMAC_FORCE_LINK_PASS; ++ val |= MVPP2_GMAC_FORCE_LINK_DOWN; ++ writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG); ++ } ++ + port->tx_time_coal = MVPP2_TXDONE_COAL_USEC; + + port->txqs = devm_kcalloc(dev, port->ntxqs, sizeof(*port->txqs), +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 6d55e3d0b7ea2..54e9f6dc24ea0 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -725,8 +725,10 @@ static int cgx_lmac_init(struct cgx *cgx) + if (!lmac) + return -ENOMEM; + lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); +- if (!lmac->name) +- return -ENOMEM; ++ if (!lmac->name) { ++ err = -ENOMEM; ++ goto err_lmac_free; ++ } + sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i); + lmac->lmac_id = i; + lmac->cgx = cgx; +@@ -737,7 +739,7 @@ static int cgx_lmac_init(struct cgx *cgx) + CGX_LMAC_FWI + i * 9), + cgx_fwi_event_handler, 0, lmac->name, lmac); + if (err) +- return err; ++ goto err_irq; + + /* Enable interrupt */ + cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S, +@@ -748,6 +750,12 @@ static int cgx_lmac_init(struct cgx *cgx) + } + + return cgx_lmac_verify_fwi_version(cgx); ++ ++err_irq: ++ kfree(lmac->name); ++err_lmac_free: ++ kfree(lmac); ++ return err; + } + + static int cgx_lmac_exit(struct cgx *cgx) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index 8cd529556b214..01089c2283d7f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -976,6 +976,22 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, + return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings); + } + ++static int mlx5e_speed_validate(struct net_device *netdev, bool ext, ++ const unsigned long link_modes, u8 autoneg) ++{ ++ /* Extended link-mode has no speed limitations. */ ++ if (ext) ++ return 0; ++ ++ if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && ++ autoneg != AUTONEG_ENABLE) { ++ netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n", ++ __func__); ++ return -EINVAL; ++ } ++ return 0; ++} ++ + static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes) + { + u32 i, ptys_modes = 0; +@@ -1068,13 +1084,9 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, + link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : + mlx5e_port_speed2linkmodes(mdev, speed, !ext); + +- if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && +- autoneg != AUTONEG_ENABLE) { +- netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n", +- __func__); +- err = -EINVAL; ++ err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg); ++ if (err) + goto out; +- } + + link_modes = link_modes & eproto.cap; + if (!link_modes) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +index 713dc210f710c..c4ac7a9968d16 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +@@ -927,6 +927,7 @@ static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, + in = kvzalloc(inlen, GFP_KERNEL); + if (!in) { + kfree(ft->g); ++ ft->g = NULL; + return -ENOMEM; + } + +@@ -1067,6 +1068,7 @@ static int mlx5e_create_inner_ttc_table_groups(struct mlx5e_ttc_table *ttc) + in = kvzalloc(inlen, GFP_KERNEL); + if (!in) { + kfree(ft->g); ++ ft->g = NULL; + return -ENOMEM; + } + +@@ -1346,6 +1348,7 @@ err_destroy_groups: + ft->g[ft->num_groups] = NULL; + mlx5e_destroy_groups(ft); + kvfree(in); ++ kfree(ft->g); + + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +index 0fc7de4aa572f..8e0dddc6383f0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +@@ -116,7 +116,7 @@ free: + static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev) + { + mlx5_core_roce_gid_set(dev, 0, 0, 0, +- NULL, NULL, false, 0, 0); ++ NULL, NULL, false, 0, 1); + } + + static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid) +diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c +index 0937fc2a928ed..23c9394cd5d22 100644 +--- a/drivers/net/ethernet/natsemi/macsonic.c ++++ b/drivers/net/ethernet/natsemi/macsonic.c +@@ -540,10 +540,14 @@ static int mac_sonic_platform_probe(struct platform_device *pdev) + + err = register_netdev(dev); + if (err) +- goto out; ++ goto undo_probe; + + return 0; + ++undo_probe: ++ dma_free_coherent(lp->device, ++ SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), ++ lp->descriptors, lp->descriptors_laddr); + out: + free_netdev(dev); + +@@ -618,12 +622,16 @@ static int mac_sonic_nubus_probe(struct nubus_board *board) + + err = register_netdev(ndev); + if (err) +- goto out; ++ goto undo_probe; + + nubus_set_drvdata(board, ndev); + + return 0; + ++undo_probe: ++ dma_free_coherent(lp->device, ++ SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), ++ lp->descriptors, lp->descriptors_laddr); + out: + free_netdev(ndev); + return err; +diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c +index e1b886e87a762..44171d7bb434c 100644 +--- a/drivers/net/ethernet/natsemi/xtsonic.c ++++ b/drivers/net/ethernet/natsemi/xtsonic.c +@@ -265,11 +265,14 @@ int xtsonic_probe(struct platform_device *pdev) + sonic_msg_init(dev); + + if ((err = register_netdev(dev))) +- goto out1; ++ goto undo_probe1; + + return 0; + +-out1: ++undo_probe1: ++ dma_free_coherent(lp->device, ++ SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), ++ lp->descriptors, lp->descriptors_laddr); + release_region(dev->base_addr, SONIC_MEM_SIZE); + out: + free_netdev(dev); +diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig +index 55a29ec766807..58eac2471d53a 100644 +--- a/drivers/net/ethernet/qlogic/Kconfig ++++ b/drivers/net/ethernet/qlogic/Kconfig +@@ -78,6 +78,7 @@ config QED + depends on PCI + select ZLIB_INFLATE + select CRC8 ++ select CRC32 + select NET_DEVLINK + ---help--- + This enables the support for ... +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index e9e0867ec139d..c4c9cbdeb601e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -64,6 +64,7 @@ struct emac_variant { + * @variant: reference to the current board variant + * @regmap: regmap for using the syscon + * @internal_phy_powered: Does the internal PHY is enabled ++ * @use_internal_phy: Is the internal PHY selected for use + * @mux_handle: Internal pointer used by mdio-mux lib + */ + struct sunxi_priv_data { +@@ -74,6 +75,7 @@ struct sunxi_priv_data { + const struct emac_variant *variant; + struct regmap_field *regmap_field; + bool internal_phy_powered; ++ bool use_internal_phy; + void *mux_handle; + }; + +@@ -523,8 +525,11 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = { + .dma_interrupt = sun8i_dwmac_dma_interrupt, + }; + ++static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv); ++ + static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) + { ++ struct net_device *ndev = platform_get_drvdata(pdev); + struct sunxi_priv_data *gmac = priv; + int ret; + +@@ -538,13 +543,25 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) + + ret = clk_prepare_enable(gmac->tx_clk); + if (ret) { +- if (gmac->regulator) +- regulator_disable(gmac->regulator); + dev_err(&pdev->dev, "Could not enable AHB clock\n"); +- return ret; ++ goto err_disable_regulator; ++ } ++ ++ if (gmac->use_internal_phy) { ++ ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev)); ++ if (ret) ++ goto err_disable_clk; + } + + return 0; ++ ++err_disable_clk: ++ clk_disable_unprepare(gmac->tx_clk); ++err_disable_regulator: ++ if (gmac->regulator) ++ regulator_disable(gmac->regulator); ++ ++ return ret; + } + + static void sun8i_dwmac_core_init(struct mac_device_info *hw, +@@ -815,7 +832,6 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, + struct sunxi_priv_data *gmac = priv->plat->bsp_priv; + u32 reg, val; + int ret = 0; +- bool need_power_ephy = false; + + if (current_child ^ desired_child) { + regmap_field_read(gmac->regmap_field, ®); +@@ -823,13 +839,12 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, + case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: + dev_info(priv->device, "Switch mux to internal PHY"); + val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; +- +- need_power_ephy = true; ++ gmac->use_internal_phy = true; + break; + case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: + dev_info(priv->device, "Switch mux to external PHY"); + val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; +- need_power_ephy = false; ++ gmac->use_internal_phy = false; + break; + default: + dev_err(priv->device, "Invalid child ID %x\n", +@@ -837,7 +852,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, + return -EINVAL; + } + regmap_field_write(gmac->regmap_field, val); +- if (need_power_ephy) { ++ if (gmac->use_internal_phy) { + ret = sun8i_dwmac_power_internal_phy(priv); + if (ret) + return ret; +@@ -988,17 +1003,12 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) + struct sunxi_priv_data *gmac = priv; + + if (gmac->variant->soc_has_internal_phy) { +- /* sun8i_dwmac_exit could be called with mdiomux uninit */ +- if (gmac->mux_handle) +- mdio_mux_uninit(gmac->mux_handle); + if (gmac->internal_phy_powered) + sun8i_dwmac_unpower_internal_phy(gmac); + } + + sun8i_dwmac_unset_syscon(gmac); + +- reset_control_put(gmac->rst_ephy); +- + clk_disable_unprepare(gmac->tx_clk); + + if (gmac->regulator) +@@ -1227,12 +1237,32 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) + + return ret; + dwmac_mux: ++ reset_control_put(gmac->rst_ephy); ++ clk_put(gmac->ephy_clk); + sun8i_dwmac_unset_syscon(gmac); + dwmac_exit: + stmmac_pltfr_remove(pdev); + return ret; + } + ++static int sun8i_dwmac_remove(struct platform_device *pdev) ++{ ++ struct net_device *ndev = platform_get_drvdata(pdev); ++ struct stmmac_priv *priv = netdev_priv(ndev); ++ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; ++ ++ if (gmac->variant->soc_has_internal_phy) { ++ mdio_mux_uninit(gmac->mux_handle); ++ sun8i_dwmac_unpower_internal_phy(gmac); ++ reset_control_put(gmac->rst_ephy); ++ clk_put(gmac->ephy_clk); ++ } ++ ++ stmmac_pltfr_remove(pdev); ++ ++ return 0; ++} ++ + static const struct of_device_id sun8i_dwmac_match[] = { + { .compatible = "allwinner,sun8i-h3-emac", + .data = &emac_variant_h3 }, +@@ -1252,7 +1282,7 @@ MODULE_DEVICE_TABLE(of, sun8i_dwmac_match); + + static struct platform_driver sun8i_dwmac_driver = { + .probe = sun8i_dwmac_probe, +- .remove = stmmac_pltfr_remove, ++ .remove = sun8i_dwmac_remove, + .driver = { + .name = "dwmac-sun8i", + .pm = &stmmac_pltfr_pm_ops, +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index d407489cec904..cbe7f35eac982 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1126,7 +1126,10 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + * accordingly. Otherwise, we should check here. + */ + if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) +- delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus); ++ delayed_ndp_size = ctx->max_ndp_size + ++ max_t(u32, ++ ctx->tx_ndp_modulus, ++ ctx->tx_modulus + ctx->tx_remainder) - 1; + else + delayed_ndp_size = 0; + +@@ -1307,7 +1310,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && + skb_out->len > ctx->min_tx_pkt) { + padding_count = ctx->tx_curr_size - skb_out->len; +- skb_put_zero(skb_out, padding_count); ++ if (!WARN_ON(padding_count > ctx->tx_curr_size)) ++ skb_put_zero(skb_out, padding_count); + } else if (skb_out->len < ctx->tx_curr_size && + (skb_out->len % dev->maxpacket) == 0) { + skb_put_u8(skb_out, 0); /* force short packet */ +diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig +index 058d77d2e693d..0d6e1829e0ac9 100644 +--- a/drivers/net/wan/Kconfig ++++ b/drivers/net/wan/Kconfig +@@ -282,6 +282,7 @@ config SLIC_DS26522 + tristate "Slic Maxim ds26522 card support" + depends on SPI + depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST ++ select BITREVERSE + help + This module initializes and configures the slic maxim card + in T1 or E1 mode. +diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig +index 0d1a8dab30ed4..32e1c036f3ac9 100644 +--- a/drivers/net/wireless/ath/wil6210/Kconfig ++++ b/drivers/net/wireless/ath/wil6210/Kconfig +@@ -2,6 +2,7 @@ + config WIL6210 + tristate "Wilocity 60g WiFi card wil6210 support" + select WANT_DEV_COREDUMP ++ select CRC32 + depends on CFG80211 + depends on PCI + default n +diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c +index f11e4bfbc91be..a47f87b8373df 100644 +--- a/drivers/regulator/qcom-rpmh-regulator.c ++++ b/drivers/regulator/qcom-rpmh-regulator.c +@@ -726,7 +726,7 @@ static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = { + static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_ops, +- .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600), ++ .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 16000), + .n_voltages = 5, + .pmic_mode_map = pmic_mode_map_pmic5_smps, + .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, +diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c +index a1c23e998f977..8dee16aca421f 100644 +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -2114,7 +2114,7 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) + { +- if (qeth_get_ip_version(skb) != 4) ++ if (vlan_get_protocol(skb) != htons(ETH_P_IP)) + features &= ~NETIF_F_HW_VLAN_CTAG_TX; + return qeth_features_check(skb, dev, features); + } +diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c +index ed20ad2950885..77ddf23b65d65 100644 +--- a/drivers/spi/spi-stm32.c ++++ b/drivers/spi/spi-stm32.c +@@ -494,9 +494,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len) + + /* align packet size with data registers access */ + if (spi->cur_bpw > 8) +- fthlv -= (fthlv % 2); /* multiple of 2 */ ++ fthlv += (fthlv % 2) ? 1 : 0; + else +- fthlv -= (fthlv % 4); /* multiple of 4 */ ++ fthlv += (fthlv % 4) ? (4 - (fthlv % 4)) : 0; + + if (!fthlv) + fthlv = 1; +diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c +index 58c7d66060f7e..dd12777b9a788 100644 +--- a/drivers/staging/exfat/exfat_super.c ++++ b/drivers/staging/exfat/exfat_super.c +@@ -59,7 +59,7 @@ static void exfat_write_super(struct super_block *sb); + /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ + static void exfat_time_fat2unix(struct timespec64 *ts, struct date_time_t *tp) + { +- ts->tv_sec = mktime64(tp->Year + 1980, tp->Month + 1, tp->Day, ++ ts->tv_sec = mktime64(tp->Year + 1980, tp->Month, tp->Day, + tp->Hour, tp->Minute, tp->Second); + + ts->tv_nsec = tp->MilliSecond * NSEC_PER_MSEC; +diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c +index 3b31e83a92155..bc6ba41686fa3 100644 +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -2303,6 +2303,24 @@ out_unlock: + return ret; + } + ++static int vfio_iommu_dma_avail_build_caps(struct vfio_iommu *iommu, ++ struct vfio_info_cap *caps) ++{ ++ struct vfio_iommu_type1_info_dma_avail cap_dma_avail; ++ int ret; ++ ++ mutex_lock(&iommu->lock); ++ cap_dma_avail.header.id = VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL; ++ cap_dma_avail.header.version = 1; ++ ++ cap_dma_avail.avail = iommu->dma_avail; ++ ++ ret = vfio_info_add_capability(caps, &cap_dma_avail.header, ++ sizeof(cap_dma_avail)); ++ mutex_unlock(&iommu->lock); ++ return ret; ++} ++ + static long vfio_iommu_type1_ioctl(void *iommu_data, + unsigned int cmd, unsigned long arg) + { +@@ -2349,6 +2367,10 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, + info.iova_pgsizes = vfio_pgsize_bitmap(iommu); + + ret = vfio_iommu_iova_build_caps(iommu, &caps); ++ ++ if (!ret) ++ ret = vfio_iommu_dma_avail_build_caps(iommu, &caps); ++ + if (ret) + return ret; + +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index e5e2425875953..130f16cc0b86d 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -520,7 +520,10 @@ + */ + #define TEXT_TEXT \ + ALIGN_FUNCTION(); \ +- *(.text.hot TEXT_MAIN .text.fixup .text.unlikely) \ ++ *(.text.hot .text.hot.*) \ ++ *(TEXT_MAIN .text.fixup) \ ++ *(.text.unlikely .text.unlikely.*) \ ++ *(.text.unknown .text.unknown.*) \ + *(.text..refcount) \ + *(.ref.text) \ + MEM_KEEP(init.text*) \ +diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h +index 9e843a147ead0..cabc93118f9c8 100644 +--- a/include/uapi/linux/vfio.h ++++ b/include/uapi/linux/vfio.h +@@ -748,6 +748,21 @@ struct vfio_iommu_type1_info_cap_iova_range { + struct vfio_iova_range iova_ranges[]; + }; + ++/* ++ * The DMA available capability allows to report the current number of ++ * simultaneously outstanding DMA mappings that are allowed. ++ * ++ * The structure below defines version 1 of this capability. ++ * ++ * avail: specifies the current number of outstanding DMA mappings allowed. ++ */ ++#define VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL 3 ++ ++struct vfio_iommu_type1_info_dma_avail { ++ struct vfio_info_cap_header header; ++ __u32 avail; ++}; ++ + #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) + + /** +diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c +index d4bcfd8f95bf6..3f47abf9ef4a6 100644 +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -280,7 +280,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) + return 0; + + out_free_newdev: +- if (new_dev->reg_state == NETREG_UNINITIALIZED) ++ if (new_dev->reg_state == NETREG_UNINITIALIZED || ++ new_dev->reg_state == NETREG_UNREGISTERED) + free_netdev(new_dev); + return err; + } +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index a0486dcf5425b..49d923c227a21 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2017,6 +2017,12 @@ int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len) + skb->csum = csum_block_sub(skb->csum, + skb_checksum(skb, len, delta, 0), + len); ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ int hdlen = (len > skb_headlen(skb)) ? skb_headlen(skb) : len; ++ int offset = skb_checksum_start_offset(skb) + skb->csum_offset; ++ ++ if (offset + sizeof(__sum16) > hdlen) ++ return -EINVAL; + } + return __pskb_trim(skb, len); + } +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 079dcf9f0c56d..7a394479dd56c 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -303,7 +303,7 @@ static int __ip_finish_output(struct net *net, struct sock *sk, struct sk_buff * + if (skb_is_gso(skb)) + return ip_finish_output_gso(net, sk, skb, mtu); + +- if (skb->len > mtu || (IPCB(skb)->flags & IPSKB_FRAG_PMTU)) ++ if (skb->len > mtu || IPCB(skb)->frag_max_size) + return ip_fragment(net, sk, skb, mtu, ip_finish_output2); + + return ip_finish_output2(net, sk, skb); +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index f61c5a0b502a8..ca525cf681a4e 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -765,8 +765,11 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + goto tx_error; + } + +- if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph, +- 0, 0, false)) { ++ df = tnl_params->frag_off; ++ if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) ++ df |= (inner_iph->frag_off & htons(IP_DF)); ++ ++ if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) { + ip_rt_put(rt); + goto tx_error; + } +@@ -794,10 +797,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + ttl = ip4_dst_hoplimit(&rt->dst); + } + +- df = tnl_params->frag_off; +- if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df) +- df |= (inner_iph->frag_off&htons(IP_DF)); +- + max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); + if (max_headroom > dev->needed_headroom) +diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c +index ea32b113089d3..c2b7d43d92b0e 100644 +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -1157,8 +1157,10 @@ static struct nexthop *nexthop_create_group(struct net *net, + return nh; + + out_no_nh: +- for (; i >= 0; --i) ++ for (i--; i >= 0; --i) { ++ list_del(&nhg->nh_entries[i].nh_list); + nexthop_put(nhg->nh_entries[i].nh); ++ } + + kfree(nhg->spare); + kfree(nhg); +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 0646fce31b67a..906ac5e6d96cd 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -973,6 +973,8 @@ static void fib6_purge_rt(struct fib6_info *rt, struct fib6_node *fn, + { + struct fib6_table *table = rt->fib6_table; + ++ /* Flush all cached dst in exception table */ ++ rt6_flush_exceptions(rt); + fib6_drop_pcpu_from(rt, table); + + if (rt->nh && !list_empty(&rt->nh_list)) +@@ -1839,9 +1841,6 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn, + net->ipv6.rt6_stats->fib_rt_entries--; + net->ipv6.rt6_stats->fib_discarded_routes++; + +- /* Flush all cached dst in exception table */ +- rt6_flush_exceptions(rt); +- + /* Reset round-robin state, if necessary */ + if (rcu_access_pointer(fn->rr_ptr) == rt) + fn->rr_ptr = NULL; +diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c +index bb311ccc6c487..c6787a1daa481 100644 +--- a/tools/bpf/bpftool/net.c ++++ b/tools/bpf/bpftool/net.c +@@ -9,7 +9,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index 71a62e7e35b1c..3429767cadcdd 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -119,7 +119,15 @@ + # - list_flush_ipv6_exception + # Using the same topology as in pmtu_ipv6, create exceptions, and check + # they are shown when listing exception caches, gone after flushing them +- ++# ++# - pmtu_ipv4_route_change ++# Use the same topology as in pmtu_ipv4, but issue a route replacement ++# command and delete the corresponding device afterward. This tests for ++# proper cleanup of the PMTU exceptions by the route replacement path. ++# Device unregistration should complete successfully ++# ++# - pmtu_ipv6_route_change ++# Same as above but with IPv6 + + # Kselftest framework requirement - SKIP code is 4. + ksft_skip=4 +@@ -161,7 +169,9 @@ tests=" + cleanup_ipv4_exception ipv4: cleanup of cached exceptions 1 + cleanup_ipv6_exception ipv6: cleanup of cached exceptions 1 + list_flush_ipv4_exception ipv4: list and flush cached exceptions 1 +- list_flush_ipv6_exception ipv6: list and flush cached exceptions 1" ++ list_flush_ipv6_exception ipv6: list and flush cached exceptions 1 ++ pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1 ++ pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1" + + NS_A="ns-A" + NS_B="ns-B" +@@ -1316,6 +1326,63 @@ test_list_flush_ipv6_exception() { + return ${fail} + } + ++test_pmtu_ipvX_route_change() { ++ family=${1} ++ ++ setup namespaces routing || return 2 ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ if [ ${family} -eq 4 ]; then ++ ping=ping ++ dst1="${prefix4}.${b_r1}.1" ++ dst2="${prefix4}.${b_r2}.1" ++ gw="${prefix4}.${a_r1}.2" ++ else ++ ping=${ping6} ++ dst1="${prefix6}:${b_r1}::1" ++ dst2="${prefix6}:${b_r2}::1" ++ gw="${prefix6}:${a_r1}::2" ++ fi ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1400 ++ mtu "${ns_b}" veth_B-R1 1400 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ # Create route exceptions ++ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1} ++ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2} ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" ++ check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" ++ check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 ++ ++ # Replace the route from A to R1 ++ run_cmd ${ns_a} ip route change default via ${gw} ++ ++ # Delete the device in A ++ run_cmd ${ns_a} ip link del "veth_A-R1" ++} ++ ++test_pmtu_ipv4_route_change() { ++ test_pmtu_ipvX_route_change 4 ++} ++ ++test_pmtu_ipv6_route_change() { ++ test_pmtu_ipvX_route_change 6 ++} ++ + usage() { + echo + echo "$0 [OPTIONS] [TEST]..." diff --git a/patch/kernel/odroidxu4-current/patch-5.4.90-91.patch b/patch/kernel/odroidxu4-current/patch-5.4.90-91.patch new file mode 100644 index 0000000000..7e767856f5 --- /dev/null +++ b/patch/kernel/odroidxu4-current/patch-5.4.90-91.patch @@ -0,0 +1,2316 @@ +diff --git a/Makefile b/Makefile +index 5c9d680b7ce51..a5edbd4f34145 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 90 ++SUBLEVEL = 91 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +@@ -480,7 +480,7 @@ KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE + KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ +- -Wno-format-security \ ++ -Werror=return-type -Wno-format-security \ + -std=gnu89 + KBUILD_CPPFLAGS := -D__KERNEL__ + KBUILD_AFLAGS_KERNEL := +diff --git a/arch/arc/Makefile b/arch/arc/Makefile +index f1c44cccf8d6c..6f05e509889f6 100644 +--- a/arch/arc/Makefile ++++ b/arch/arc/Makefile +@@ -90,16 +90,22 @@ libs-y += arch/arc/lib/ $(LIBGCC) + + boot := arch/arc/boot + +-#default target for make without any arguments. +-KBUILD_IMAGE := $(boot)/bootpImage +- +-all: bootpImage +-bootpImage: vmlinux +- +-boot_targets += uImage uImage.bin uImage.gz ++boot_targets := uImage.bin uImage.gz uImage.lzma + ++PHONY += $(boot_targets) + $(boot_targets): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + ++uimage-default-y := uImage.bin ++uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz ++uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma ++ ++PHONY += uImage ++uImage: $(uimage-default-y) ++ @ln -sf $< $(boot)/uImage ++ @$(kecho) ' Image $(boot)/uImage is ready' ++ ++CLEAN_FILES += $(boot)/uImage ++ + archclean: + $(Q)$(MAKE) $(clean)=$(boot) +diff --git a/arch/arc/boot/Makefile b/arch/arc/boot/Makefile +index 538b92f4dd253..3b1f8a69a89ef 100644 +--- a/arch/arc/boot/Makefile ++++ b/arch/arc/boot/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 +-targets := vmlinux.bin vmlinux.bin.gz uImage ++targets := vmlinux.bin vmlinux.bin.gz + + # uImage build relies on mkimage being availble on your host for ARC target + # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage +@@ -13,11 +13,6 @@ LINUX_START_TEXT = $$(readelf -h vmlinux | \ + UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) + UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) + +-suffix-y := bin +-suffix-$(CONFIG_KERNEL_GZIP) := gz +-suffix-$(CONFIG_KERNEL_LZMA) := lzma +- +-targets += uImage + targets += uImage.bin + targets += uImage.gz + targets += uImage.lzma +@@ -42,7 +37,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE + + $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE + $(call if_changed,uimage,lzma) +- +-$(obj)/uImage: $(obj)/uImage.$(suffix-y) +- @ln -sf $(notdir $<) $@ +- @echo ' Image $@ is ready' +diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h +index 0a32e8cfd074d..bcd1920ae75a3 100644 +--- a/arch/arc/include/asm/page.h ++++ b/arch/arc/include/asm/page.h +@@ -10,6 +10,7 @@ + #ifndef __ASSEMBLY__ + + #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) ++#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) + #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) + + struct vm_area_struct; +diff --git a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi +index 5ae8607883395..3fcc86d7b735f 100644 +--- a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi ++++ b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi +@@ -45,18 +45,21 @@ + emac: gem@30000 { + compatible = "cadence,gem"; + reg = <0x30000 0x10000>; ++ interrupt-parent = <&vic0>; + interrupts = <31>; + }; + + dmac1: dmac@40000 { + compatible = "snps,dw-dmac"; + reg = <0x40000 0x10000>; ++ interrupt-parent = <&vic0>; + interrupts = <25>; + }; + + dmac2: dmac@50000 { + compatible = "snps,dw-dmac"; + reg = <0x50000 0x10000>; ++ interrupt-parent = <&vic0>; + interrupts = <26>; + }; + +@@ -234,6 +237,7 @@ + axi2pico@c0000000 { + compatible = "picochip,axi2pico-pc3x2"; + reg = <0xc0000000 0x10000>; ++ interrupt-parent = <&vic0>; + interrupts = <13 14 15 16 17 18 19 20 21>; + }; + }; +diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c +index 88f5d637b1c49..a52e929381ea4 100644 +--- a/arch/mips/boot/compressed/decompress.c ++++ b/arch/mips/boot/compressed/decompress.c +@@ -13,6 +13,7 @@ + #include + + #include ++#include + + /* + * These two variables specify the free mem region +@@ -113,7 +114,7 @@ void decompress_kernel(unsigned long boot_heap_start) + dtb_size = fdt_totalsize((void *)&__appended_dtb); + + /* last four bytes is always image size in little endian */ +- image_size = le32_to_cpup((void *)&__image_end - 4); ++ image_size = get_unaligned_le32((void *)&__image_end - 4); + + /* copy dtb to where the booted kernel will expect it */ + memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, +diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c +index 3d80a51256de6..dab8febb57419 100644 +--- a/arch/mips/kernel/relocate.c ++++ b/arch/mips/kernel/relocate.c +@@ -187,8 +187,14 @@ static int __init relocate_exception_table(long offset) + static inline __init unsigned long rotate_xor(unsigned long hash, + const void *area, size_t size) + { +- size_t i; +- unsigned long *ptr = (unsigned long *)area; ++ const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); ++ size_t diff, i; ++ ++ diff = (void *)ptr - area; ++ if (unlikely(size < diff + sizeof(hash))) ++ return hash; ++ ++ size = ALIGN_DOWN(size - diff, sizeof(hash)); + + for (i = 0; i < size / sizeof(hash); i++) { + /* Rotate by odd number of bits and XOR. */ +diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c +index 09d5deea747f2..f80a67c092b63 100644 +--- a/arch/mips/lib/uncached.c ++++ b/arch/mips/lib/uncached.c +@@ -37,10 +37,12 @@ + */ + unsigned long run_uncached(void *func) + { +- register long sp __asm__("$sp"); + register long ret __asm__("$2"); + long lfunc = (long)func, ufunc; + long usp; ++ long sp; ++ ++ __asm__("move %0, $sp" : "=r" (sp)); + + if (sp >= (long)CKSEG0 && sp < (long)CKSEG2) + usp = CKSEG1ADDR(sp); +diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c +index c4785a456dedc..504fd61592405 100644 +--- a/arch/mips/mm/c-r4k.c ++++ b/arch/mips/mm/c-r4k.c +@@ -1576,7 +1576,7 @@ static void __init loongson2_sc_init(void) + c->options |= MIPS_CPU_INCLUSIVE_CACHES; + } + +-static void __init loongson3_sc_init(void) ++static void loongson3_sc_init(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config2, lsize; +diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c +index dbdbfe5d84086..e67374268b42d 100644 +--- a/arch/mips/mm/sc-mips.c ++++ b/arch/mips/mm/sc-mips.c +@@ -147,7 +147,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) + return 1; + } + +-static int __init mips_sc_probe_cm3(void) ++static int mips_sc_probe_cm3(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long cfg = read_gcr_l2_config(); +@@ -181,7 +181,7 @@ static int __init mips_sc_probe_cm3(void) + return 0; + } + +-static inline int __init mips_sc_probe(void) ++static inline int mips_sc_probe(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config1, config2; +diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c +index 5208ba49c89a9..2c87350c1fb09 100644 +--- a/arch/x86/hyperv/mmu.c ++++ b/arch/x86/hyperv/mmu.c +@@ -66,11 +66,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus, + if (!hv_hypercall_pg) + goto do_native; + +- if (cpumask_empty(cpus)) +- return; +- + local_irq_save(flags); + ++ /* ++ * Only check the mask _after_ interrupt has been disabled to avoid the ++ * mask changing under our feet. ++ */ ++ if (cpumask_empty(cpus)) { ++ local_irq_restore(flags); ++ return; ++ } ++ + flush_pcpu = (struct hv_tlb_flush **) + this_cpu_ptr(hyperv_pcpu_input_arg); + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index ba32adaeefdd0..7d19aae015aeb 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -6320,13 +6320,13 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, + * limit 'something'. + */ + /* no more than 50% of tags for async I/O */ +- bfqd->word_depths[0][0] = max((1U << bt->sb.shift) >> 1, 1U); ++ bfqd->word_depths[0][0] = max(bt->sb.depth >> 1, 1U); + /* + * no more than 75% of tags for sync writes (25% extra tags + * w.r.t. async I/O, to prevent async I/O from starving sync + * writes) + */ +- bfqd->word_depths[0][1] = max(((1U << bt->sb.shift) * 3) >> 2, 1U); ++ bfqd->word_depths[0][1] = max((bt->sb.depth * 3) >> 2, 1U); + + /* + * In-word depths in case some bfq_queue is being weight- +@@ -6336,9 +6336,9 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, + * shortage. + */ + /* no more than ~18% of tags for async I/O */ +- bfqd->word_depths[1][0] = max(((1U << bt->sb.shift) * 3) >> 4, 1U); ++ bfqd->word_depths[1][0] = max((bt->sb.depth * 3) >> 4, 1U); + /* no more than ~37% of tags for sync writes (~20% extra tags) */ +- bfqd->word_depths[1][1] = max(((1U << bt->sb.shift) * 6) >> 4, 1U); ++ bfqd->word_depths[1][1] = max((bt->sb.depth * 6) >> 4, 1U); + + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) +diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h +index afe6636f9ad39..1db2e1bb72ba6 100644 +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -97,7 +97,7 @@ void acpi_scan_table_handler(u32 event, void *table, void *context); + extern struct list_head acpi_bus_id_list; + + struct acpi_device_bus_id { +- char bus_id[15]; ++ const char *bus_id; + unsigned int instance_no; + struct list_head node; + }; +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 2527938a30b54..6c8c9509e03d1 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -487,6 +487,7 @@ static void acpi_device_del(struct acpi_device *device) + acpi_device_bus_id->instance_no--; + else { + list_del(&acpi_device_bus_id->node); ++ kfree_const(acpi_device_bus_id->bus_id); + kfree(acpi_device_bus_id); + } + break; +@@ -675,7 +676,14 @@ int acpi_device_add(struct acpi_device *device, + } + if (!found) { + acpi_device_bus_id = new_bus_id; +- strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); ++ acpi_device_bus_id->bus_id = ++ kstrdup_const(acpi_device_hid(device), GFP_KERNEL); ++ if (!acpi_device_bus_id->bus_id) { ++ pr_err(PREFIX "Memory allocation error for bus id\n"); ++ result = -ENOMEM; ++ goto err_free_new_bus_id; ++ } ++ + acpi_device_bus_id->instance_no = 0; + list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); + } +@@ -710,6 +718,11 @@ int acpi_device_add(struct acpi_device *device, + if (device->parent) + list_del(&device->node); + list_del(&device->wakeup_list); ++ ++ err_free_new_bus_id: ++ if (!found) ++ kfree(new_bus_id); ++ + mutex_unlock(&acpi_device_lock); + + err_detach: +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 29141bff4b572..3b3fc9a426e91 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2057,11 +2057,11 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) + if (adev->gmc.xgmi.num_physical_nodes > 1) + amdgpu_xgmi_remove_device(adev); + +- amdgpu_amdkfd_device_fini(adev); +- + amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); + amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); + ++ amdgpu_amdkfd_device_fini(adev); ++ + /* need to disable SMC first */ + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.hw) +diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c +index bc14e9c0285a0..23edc1b8e43fa 100644 +--- a/drivers/gpu/drm/i915/display/intel_panel.c ++++ b/drivers/gpu/drm/i915/display/intel_panel.c +@@ -1603,20 +1603,21 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus + val = pch_get_backlight(connector); + else + val = lpt_get_backlight(connector); +- val = intel_panel_compute_brightness(connector, val); +- panel->backlight.level = clamp(val, panel->backlight.min, +- panel->backlight.max); + + if (cpu_mode) { + DRM_DEBUG_KMS("CPU backlight register was enabled, switching to PCH override\n"); + + /* Write converted CPU PWM value to PCH override register */ +- lpt_set_backlight(connector->base.state, panel->backlight.level); ++ lpt_set_backlight(connector->base.state, val); + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); + + I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 & ~BLM_PWM_ENABLE); + } + ++ val = intel_panel_compute_brightness(connector, val); ++ panel->backlight.level = clamp(val, panel->backlight.min, ++ panel->backlight.max); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c +index a71b22bdd95b5..7f329d8118a46 100644 +--- a/drivers/gpu/drm/i915/display/vlv_dsi.c ++++ b/drivers/gpu/drm/i915/display/vlv_dsi.c +@@ -797,10 +797,20 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, + if (intel_dsi->gpio_panel) + gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1); + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); +- intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); + +- /* Deassert reset */ +- intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); ++ /* ++ * Give the panel time to power-on and then deassert its reset. ++ * Depending on the VBT MIPI sequences version the deassert-seq ++ * may contain the necessary delay, intel_dsi_msleep() will skip ++ * the delay in that case. If there is no deassert-seq, then an ++ * unconditional msleep is used to give the panel time to power-on. ++ */ ++ if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { ++ intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); ++ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); ++ } else { ++ msleep(intel_dsi->panel_on_delay); ++ } + + if (IS_GEMINILAKE(dev_priv)) { + glk_cold_boot = glk_dsi_enable_io(encoder); +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index 108632a1f2438..8d9d86c76a4e9 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -432,14 +432,14 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) + + drm_mode_config_init(ddev); + +- /* Bind all our sub-components: */ +- ret = component_bind_all(dev, ddev); ++ ret = msm_init_vram(ddev); + if (ret) + goto err_destroy_mdss; + +- ret = msm_init_vram(ddev); ++ /* Bind all our sub-components: */ ++ ret = component_bind_all(dev, ddev); + if (ret) +- goto err_msm_uninit; ++ goto err_destroy_mdss; + + if (!dev->dma_parms) { + dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), +diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c +index c88ce77fe6763..df6f042fb605e 100644 +--- a/drivers/hwmon/pwm-fan.c ++++ b/drivers/hwmon/pwm-fan.c +@@ -330,8 +330,18 @@ static int pwm_fan_probe(struct platform_device *pdev) + + ctx->pwm_value = MAX_PWM; + +- /* Set duty cycle to maximum allowed and enable PWM output */ + pwm_init_state(ctx->pwm, &state); ++ /* ++ * __set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned ++ * long. Check this here to prevent the fan running at a too low ++ * frequency. ++ */ ++ if (state.period > ULONG_MAX / MAX_PWM + 1) { ++ dev_err(dev, "Configured period too big\n"); ++ return -EINVAL; ++ } ++ ++ /* Set duty cycle to maximum allowed and enable PWM output */ + state.duty_cycle = ctx->pwm->args.period - 1; + state.enabled = true; + +diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c +index a07665f7ef8ce..f1b4db80913f7 100644 +--- a/drivers/infiniband/core/restrack.c ++++ b/drivers/infiniband/core/restrack.c +@@ -234,6 +234,7 @@ static void rdma_restrack_add(struct rdma_restrack_entry *res) + } else { + ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b, + &rt->next_id, GFP_KERNEL); ++ ret = (ret < 0) ? ret : 0; + } + + if (!ret) +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index 40c1a05c2445d..c9e583c05ef27 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -6173,7 +6173,7 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) + + err = set_has_smi_cap(dev); + if (err) +- return err; ++ goto err_mp; + + if (!mlx5_core_mp_enabled(mdev)) { + for (i = 1; i <= dev->num_ports; i++) { +@@ -6626,7 +6626,7 @@ static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev) + + err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true); + if (err) +- mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg); ++ mlx5_free_bfreg(dev->mdev, &dev->bfreg); + + return err; + } +diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +index e8267e5907722..55bd8873da466 100644 +--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c ++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +@@ -442,9 +442,9 @@ static void ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx) + pr_err("%s(%d) Freeing in use pdid=0x%x.\n", + __func__, dev->id, pd->id); + } +- kfree(uctx->cntxt_pd); + uctx->cntxt_pd = NULL; + _ocrdma_dealloc_pd(dev, pd); ++ kfree(pd); + } + + static struct ocrdma_pd *ocrdma_get_ucontext_pd(struct ocrdma_ucontext *uctx) +diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +index 556b8e44a51c4..a102a5d8769f2 100644 +--- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c ++++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +@@ -214,6 +214,7 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, + + } + usnic_uiom_free_dev_list(dev_list); ++ dev_list = NULL; + } + + /* Try to find resources on an unused vf */ +@@ -239,6 +240,8 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, + qp_grp_check: + if (IS_ERR_OR_NULL(qp_grp)) { + usnic_err("Failed to allocate qp_grp\n"); ++ if (usnic_ib_share_vf) ++ usnic_uiom_free_dev_list(dev_list); + return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); + } + return qp_grp; +diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c +index ec69a99b99bab..a3739f626629c 100644 +--- a/drivers/iommu/intel-svm.c ++++ b/drivers/iommu/intel-svm.c +@@ -99,8 +99,10 @@ int intel_svm_finish_prq(struct intel_iommu *iommu) + return 0; + } + +-static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev, +- unsigned long address, unsigned long pages, int ih) ++static void __flush_svm_range_dev(struct intel_svm *svm, ++ struct intel_svm_dev *sdev, ++ unsigned long address, ++ unsigned long pages, int ih) + { + struct qi_desc desc; + +@@ -151,6 +153,22 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d + } + } + ++static void intel_flush_svm_range_dev(struct intel_svm *svm, ++ struct intel_svm_dev *sdev, ++ unsigned long address, ++ unsigned long pages, int ih) ++{ ++ unsigned long shift = ilog2(__roundup_pow_of_two(pages)); ++ unsigned long align = (1ULL << (VTD_PAGE_SHIFT + shift)); ++ unsigned long start = ALIGN_DOWN(address, align); ++ unsigned long end = ALIGN(address + (pages << VTD_PAGE_SHIFT), align); ++ ++ while (start < end) { ++ __flush_svm_range_dev(svm, sdev, start, align >> VTD_PAGE_SHIFT, ih); ++ start += align; ++ } ++} ++ + static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address, + unsigned long pages, int ih) + { +diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig +index 26cf0ac9c4ad0..c9a53c2224728 100644 +--- a/drivers/isdn/mISDN/Kconfig ++++ b/drivers/isdn/mISDN/Kconfig +@@ -13,6 +13,7 @@ if MISDN != n + config MISDN_DSP + tristate "Digital Audio Processing of transparent data" + depends on MISDN ++ select BITREVERSE + help + Enable support for digital audio processing capability. + +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index 2d519c2235626..a9529dc2b26e6 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1446,6 +1446,12 @@ sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) + } + EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); + ++struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c) ++{ ++ return c->dm_io; ++} ++EXPORT_SYMBOL_GPL(dm_bufio_get_dm_io_client); ++ + sector_t dm_bufio_get_block_number(struct dm_buffer *b) + { + return b->block; +diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c +index d6edfe84e7490..25efe382e78fa 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -1343,12 +1343,52 @@ static int dm_integrity_rw_tag(struct dm_integrity_c *ic, unsigned char *tag, se + return 0; + } + +-static void dm_integrity_flush_buffers(struct dm_integrity_c *ic) ++struct flush_request { ++ struct dm_io_request io_req; ++ struct dm_io_region io_reg; ++ struct dm_integrity_c *ic; ++ struct completion comp; ++}; ++ ++static void flush_notify(unsigned long error, void *fr_) ++{ ++ struct flush_request *fr = fr_; ++ if (unlikely(error != 0)) ++ dm_integrity_io_error(fr->ic, "flusing disk cache", -EIO); ++ complete(&fr->comp); ++} ++ ++static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_data) + { + int r; ++ ++ struct flush_request fr; ++ ++ if (!ic->meta_dev) ++ flush_data = false; ++ if (flush_data) { ++ fr.io_req.bi_op = REQ_OP_WRITE, ++ fr.io_req.bi_op_flags = REQ_PREFLUSH | REQ_SYNC, ++ fr.io_req.mem.type = DM_IO_KMEM, ++ fr.io_req.mem.ptr.addr = NULL, ++ fr.io_req.notify.fn = flush_notify, ++ fr.io_req.notify.context = &fr; ++ fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio), ++ fr.io_reg.bdev = ic->dev->bdev, ++ fr.io_reg.sector = 0, ++ fr.io_reg.count = 0, ++ fr.ic = ic; ++ init_completion(&fr.comp); ++ r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL); ++ BUG_ON(r); ++ } ++ + r = dm_bufio_write_dirty_buffers(ic->bufio); + if (unlikely(r)) + dm_integrity_io_error(ic, "writing tags", r); ++ ++ if (flush_data) ++ wait_for_completion(&fr.comp); + } + + static void sleep_on_endio_wait(struct dm_integrity_c *ic) +@@ -2077,7 +2117,7 @@ static void integrity_commit(struct work_struct *w) + flushes = bio_list_get(&ic->flush_bio_list); + if (unlikely(ic->mode != 'J')) { + spin_unlock_irq(&ic->endio_wait.lock); +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + goto release_flush_bios; + } + +@@ -2287,7 +2327,7 @@ skip_io: + complete_journal_op(&comp); + wait_for_completion_io(&comp.comp); + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + } + + static void integrity_writer(struct work_struct *w) +@@ -2329,7 +2369,7 @@ static void recalc_write_super(struct dm_integrity_c *ic) + { + int r; + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, false); + if (dm_integrity_failed(ic)) + return; + +@@ -2532,7 +2572,7 @@ static void bitmap_flush_work(struct work_struct *work) + unsigned long limit; + struct bio *bio; + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, false); + + range.logical_sector = 0; + range.n_sectors = ic->provided_data_sectors; +@@ -2541,7 +2581,7 @@ static void bitmap_flush_work(struct work_struct *work) + add_new_range_and_wait(ic, &range); + spin_unlock_irq(&ic->endio_wait.lock); + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + if (ic->meta_dev) + blkdev_issue_flush(ic->dev->bdev, GFP_NOIO, NULL); + +@@ -2812,11 +2852,11 @@ static void dm_integrity_postsuspend(struct dm_target *ti) + if (ic->meta_dev) + queue_work(ic->writer_wq, &ic->writer_work); + drain_workqueue(ic->writer_wq); +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + } + + if (ic->mode == 'B') { +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + #if 1 + /* set to 0 to test bitmap replay code */ + init_journal(ic, 0, ic->journal_sections, 0); +@@ -3585,7 +3625,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) + unsigned extra_args; + struct dm_arg_set as; + static const struct dm_arg _args[] = { +- {0, 9, "Invalid number of feature args"}, ++ {0, 15, "Invalid number of feature args"}, + }; + unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; + bool should_write_sb; +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index b0aa595e4375d..70210a7e4bc80 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3744,10 +3744,10 @@ static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits) + blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); + + /* +- * RAID1 and RAID10 personalities require bio splitting, +- * RAID0/4/5/6 don't and process large discard bios properly. ++ * RAID0 and RAID10 personalities require bio splitting, ++ * RAID1/4/5/6 don't and process large discard bios properly. + */ +- if (rs_is_raid1(rs) || rs_is_raid10(rs)) { ++ if (rs_is_raid0(rs) || rs_is_raid10(rs)) { + limits->discard_granularity = chunk_size_bytes; + limits->max_discard_sectors = rs->md.chunk_sectors; + } +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index 4fb1a40e68a08..0164c9ca984ba 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -141,6 +141,11 @@ struct dm_snapshot { + * for them to be committed. + */ + struct bio_list bios_queued_during_merge; ++ ++ /* ++ * Flush data after merge. ++ */ ++ struct bio flush_bio; + }; + + /* +@@ -1121,6 +1126,17 @@ shut: + + static void error_bios(struct bio *bio); + ++static int flush_data(struct dm_snapshot *s) ++{ ++ struct bio *flush_bio = &s->flush_bio; ++ ++ bio_reset(flush_bio); ++ bio_set_dev(flush_bio, s->origin->bdev); ++ flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; ++ ++ return submit_bio_wait(flush_bio); ++} ++ + static void merge_callback(int read_err, unsigned long write_err, void *context) + { + struct dm_snapshot *s = context; +@@ -1134,6 +1150,11 @@ static void merge_callback(int read_err, unsigned long write_err, void *context) + goto shut; + } + ++ if (flush_data(s) < 0) { ++ DMERR("Flush after merge failed: shutting down merge"); ++ goto shut; ++ } ++ + if (s->store->type->commit_merge(s->store, + s->num_merging_chunks) < 0) { + DMERR("Write error in exception store: shutting down merge"); +@@ -1318,6 +1339,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) + s->first_merging_chunk = 0; + s->num_merging_chunks = 0; + bio_list_init(&s->bios_queued_during_merge); ++ bio_init(&s->flush_bio, NULL, 0); + + /* Allocate hash table for COW data */ + if (init_hash_tables(s)) { +@@ -1504,6 +1526,8 @@ static void snapshot_dtr(struct dm_target *ti) + + dm_exception_store_destroy(s->store); + ++ bio_uninit(&s->flush_bio); ++ + dm_put_device(ti, s->cow); + + dm_put_device(ti, s->origin); +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index bf3c2a1159e68..c6ce42daff27b 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -548,7 +548,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, + * subset of the parent bdev; require extra privileges. + */ + if (!capable(CAP_SYS_RAWIO)) { +- DMWARN_LIMIT( ++ DMDEBUG_LIMIT( + "%s: sending ioctl %x to DM device without required privilege.", + current->comm, cmd); + r = -ENOIOCTLCMD; +diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c +index 3eeb1920ddb43..3486bf33474d9 100644 +--- a/drivers/misc/habanalabs/device.c ++++ b/drivers/misc/habanalabs/device.c +@@ -959,6 +959,7 @@ again: + GFP_KERNEL); + if (!hdev->kernel_ctx) { + rc = -ENOMEM; ++ hl_mmu_fini(hdev); + goto out_err; + } + +@@ -970,6 +971,7 @@ again: + "failed to init kernel ctx in hard reset\n"); + kfree(hdev->kernel_ctx); + hdev->kernel_ctx = NULL; ++ hl_mmu_fini(hdev); + goto out_err; + } + } +diff --git a/drivers/misc/habanalabs/habanalabs_drv.c b/drivers/misc/habanalabs/habanalabs_drv.c +index 8c342fb499ca6..ae50bd55f30af 100644 +--- a/drivers/misc/habanalabs/habanalabs_drv.c ++++ b/drivers/misc/habanalabs/habanalabs_drv.c +@@ -443,6 +443,7 @@ static struct pci_driver hl_pci_driver = { + .id_table = ids, + .probe = hl_pci_probe, + .remove = hl_pci_remove, ++ .shutdown = hl_pci_remove, + .driver.pm = &hl_pm_ops, + }; + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +index 30816ec4fa915..13ef6a9afaa09 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +@@ -216,8 +216,12 @@ int bnxt_get_ulp_msix_base(struct bnxt *bp) + + int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) + { +- if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) +- return BNXT_MIN_ROCE_STAT_CTXS; ++ if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { ++ struct bnxt_en_dev *edev = bp->edev; ++ ++ if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) ++ return BNXT_MIN_ROCE_STAT_CTXS; ++ } + + return 0; + } +diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +index c8e5d889bd81f..21de56345503f 100644 +--- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c ++++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +@@ -223,3 +223,4 @@ static struct platform_driver fs_enet_bb_mdio_driver = { + }; + + module_platform_driver(fs_enet_bb_mdio_driver); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +index 1582d82483eca..4e6a9c5d8af55 100644 +--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c ++++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +@@ -224,3 +224,4 @@ static struct platform_driver fs_enet_fec_mdio_driver = { + }; + + module_platform_driver(fs_enet_fec_mdio_driver); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h +index a86a42131fc71..b00fbef612cfe 100644 +--- a/drivers/net/ethernet/freescale/ucc_geth.h ++++ b/drivers/net/ethernet/freescale/ucc_geth.h +@@ -576,7 +576,14 @@ struct ucc_geth_tx_global_pram { + u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ + u32 tqptr; /* a base pointer to the Tx Queues Memory + Region */ +- u8 res2[0x80 - 0x74]; ++ u8 res2[0x78 - 0x74]; ++ u64 snums_en; ++ u32 l2l3baseptr; /* top byte consists of a few other bit fields */ ++ ++ u16 mtu[8]; ++ u8 res3[0xa8 - 0x94]; ++ u32 wrrtablebase; /* top byte is reserved */ ++ u8 res4[0xc0 - 0xac]; + } __packed; + + /* structure representing Extended Filtering Global Parameters in PRAM */ +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 9bb37ac99a108..8325f6d65dccc 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -787,6 +787,13 @@ static const struct usb_device_id products[] = { + .driver_info = 0, + }, + ++/* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ ++{ ++ USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = 0, ++}, ++ + /* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ + { + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index cd1a07175e111..22f093797f417 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -5845,6 +5845,7 @@ static const struct usb_device_id rtl8152_table[] = { + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, + {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 9b1fc8633cfe1..ef93bd3ed339c 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3145,7 +3145,8 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */ + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ +- .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, ++ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | ++ NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ + .driver_data = NVME_QUIRK_LIGHTNVM, }, + { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index a31c6e1f6063a..a554021e1ab92 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -186,7 +186,7 @@ static inline size_t nvme_tcp_req_cur_offset(struct nvme_tcp_request *req) + + static inline size_t nvme_tcp_req_cur_length(struct nvme_tcp_request *req) + { +- return min_t(size_t, req->iter.bvec->bv_len - req->iter.iov_offset, ++ return min_t(size_t, iov_iter_single_seg_count(&req->iter), + req->pdu_len - req->pdu_sent); + } + +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index b5314164479e9..50e2007092bc0 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -1351,6 +1351,16 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue) + spin_lock_irqsave(&queue->state_lock, flags); + switch (queue->state) { + case NVMET_RDMA_Q_CONNECTING: ++ while (!list_empty(&queue->rsp_wait_list)) { ++ struct nvmet_rdma_rsp *rsp; ++ ++ rsp = list_first_entry(&queue->rsp_wait_list, ++ struct nvmet_rdma_rsp, ++ wait_list); ++ list_del(&rsp->wait_list); ++ nvmet_rdma_put_rsp(rsp); ++ } ++ fallthrough; + case NVMET_RDMA_Q_LIVE: + queue->state = NVMET_RDMA_Q_DISCONNECTING; + disconnect = true; +diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c +index bdab46a5c4617..6c431456d2983 100644 +--- a/drivers/regulator/bd718x7-regulator.c ++++ b/drivers/regulator/bd718x7-regulator.c +@@ -15,6 +15,36 @@ + #include + #include + ++/* Typical regulator startup times as per data sheet in uS */ ++#define BD71847_BUCK1_STARTUP_TIME 144 ++#define BD71847_BUCK2_STARTUP_TIME 162 ++#define BD71847_BUCK3_STARTUP_TIME 162 ++#define BD71847_BUCK4_STARTUP_TIME 240 ++#define BD71847_BUCK5_STARTUP_TIME 270 ++#define BD71847_BUCK6_STARTUP_TIME 200 ++#define BD71847_LDO1_STARTUP_TIME 440 ++#define BD71847_LDO2_STARTUP_TIME 370 ++#define BD71847_LDO3_STARTUP_TIME 310 ++#define BD71847_LDO4_STARTUP_TIME 400 ++#define BD71847_LDO5_STARTUP_TIME 530 ++#define BD71847_LDO6_STARTUP_TIME 400 ++ ++#define BD71837_BUCK1_STARTUP_TIME 160 ++#define BD71837_BUCK2_STARTUP_TIME 180 ++#define BD71837_BUCK3_STARTUP_TIME 180 ++#define BD71837_BUCK4_STARTUP_TIME 180 ++#define BD71837_BUCK5_STARTUP_TIME 160 ++#define BD71837_BUCK6_STARTUP_TIME 240 ++#define BD71837_BUCK7_STARTUP_TIME 220 ++#define BD71837_BUCK8_STARTUP_TIME 200 ++#define BD71837_LDO1_STARTUP_TIME 440 ++#define BD71837_LDO2_STARTUP_TIME 370 ++#define BD71837_LDO3_STARTUP_TIME 310 ++#define BD71837_LDO4_STARTUP_TIME 400 ++#define BD71837_LDO5_STARTUP_TIME 310 ++#define BD71837_LDO6_STARTUP_TIME 400 ++#define BD71837_LDO7_STARTUP_TIME 530 ++ + /* + * BUCK1/2/3/4 + * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting +@@ -495,6 +525,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD718XX_REG_BUCK1_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK1_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck1_set_hw_dvs_levels, + }, +@@ -519,6 +550,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD718XX_REG_BUCK2_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK2_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck2_set_hw_dvs_levels, + }, +@@ -547,6 +579,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .linear_range_selectors = bd71847_buck3_volt_range_sel, + .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK3_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -574,6 +607,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, + .linear_range_selectors = bd71847_buck4_volt_range_sel, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK4_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -596,6 +630,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, + .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK5_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -620,6 +655,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, + .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71847_BUCK6_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -646,6 +682,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .linear_range_selectors = bd718xx_ldo1_volt_range_sel, + .enable_reg = BD718XX_REG_LDO1_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO1_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -668,6 +705,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .n_voltages = ARRAY_SIZE(ldo_2_volts), + .enable_reg = BD718XX_REG_LDO2_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO2_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -691,6 +729,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = BD718XX_LDO3_MASK, + .enable_reg = BD718XX_REG_LDO3_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO3_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -714,6 +753,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = BD718XX_LDO4_MASK, + .enable_reg = BD718XX_REG_LDO4_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO4_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -740,6 +780,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .linear_range_selectors = bd71847_ldo5_volt_range_sel, + .enable_reg = BD718XX_REG_LDO5_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO5_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -765,6 +806,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { + .vsel_mask = BD718XX_LDO6_MASK, + .enable_reg = BD718XX_REG_LDO6_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71847_LDO6_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -791,6 +833,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD718XX_REG_BUCK1_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK1_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck1_set_hw_dvs_levels, + }, +@@ -815,6 +858,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD718XX_REG_BUCK2_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK2_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck2_set_hw_dvs_levels, + }, +@@ -839,6 +883,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD71837_REG_BUCK3_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK3_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck3_set_hw_dvs_levels, + }, +@@ -863,6 +908,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = DVS_BUCK_RUN_MASK, + .enable_reg = BD71837_REG_BUCK4_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK4_STARTUP_TIME, + .owner = THIS_MODULE, + .of_parse_cb = buck4_set_hw_dvs_levels, + }, +@@ -891,6 +937,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .linear_range_selectors = bd71837_buck5_volt_range_sel, + .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK5_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -915,6 +962,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD71837_BUCK6_MASK, + .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK6_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -937,6 +985,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, + .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK7_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -961,6 +1010,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, + .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, + .enable_mask = BD718XX_BUCK_EN, ++ .enable_time = BD71837_BUCK8_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -987,6 +1037,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .linear_range_selectors = bd718xx_ldo1_volt_range_sel, + .enable_reg = BD718XX_REG_LDO1_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO1_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1009,6 +1060,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .n_voltages = ARRAY_SIZE(ldo_2_volts), + .enable_reg = BD718XX_REG_LDO2_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO2_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1032,6 +1084,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD718XX_LDO3_MASK, + .enable_reg = BD718XX_REG_LDO3_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO3_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1055,6 +1108,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD718XX_LDO4_MASK, + .enable_reg = BD718XX_REG_LDO4_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO4_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1080,6 +1134,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD71837_LDO5_MASK, + .enable_reg = BD718XX_REG_LDO5_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO5_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1107,6 +1162,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD718XX_LDO6_MASK, + .enable_reg = BD718XX_REG_LDO6_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO6_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +@@ -1132,6 +1188,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { + .vsel_mask = BD71837_LDO7_MASK, + .enable_reg = BD71837_REG_LDO7_VOLT, + .enable_mask = BD718XX_LDO_EN, ++ .enable_time = BD71837_LDO7_STARTUP_TIME, + .owner = THIS_MODULE, + }, + .init = { +diff --git a/drivers/usb/typec/altmodes/Kconfig b/drivers/usb/typec/altmodes/Kconfig +index 187690fd1a5bd..60d375e9c3c7c 100644 +--- a/drivers/usb/typec/altmodes/Kconfig ++++ b/drivers/usb/typec/altmodes/Kconfig +@@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE + to enable support for VirtualLink devices with NVIDIA GPUs. + + To compile this driver as a module, choose M here: the +- module will be called typec_displayport. ++ module will be called typec_nvidia. + + endmenu +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 60c21cfb19480..95205bde240f7 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -647,9 +647,7 @@ alloc_extent_state_atomic(struct extent_state *prealloc) + + static void extent_io_tree_panic(struct extent_io_tree *tree, int err) + { +- struct inode *inode = tree->private_data; +- +- btrfs_panic(btrfs_sb(inode->i_sb), err, ++ btrfs_panic(tree->fs_info, err, + "locking error: extent tree was modified by another thread while locked"); + } + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index d9246fb8cea65..cd8e81c02f63f 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -3144,6 +3144,12 @@ out: + return ret; + } + ++static bool rescan_should_stop(struct btrfs_fs_info *fs_info) ++{ ++ return btrfs_fs_closing(fs_info) || ++ test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); ++} ++ + static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) + { + struct btrfs_fs_info *fs_info = container_of(work, struct btrfs_fs_info, +@@ -3152,6 +3158,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) + struct btrfs_trans_handle *trans = NULL; + int err = -ENOMEM; + int ret = 0; ++ bool stopped = false; + + path = btrfs_alloc_path(); + if (!path) +@@ -3164,7 +3171,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) + path->skip_locking = 1; + + err = 0; +- while (!err && !btrfs_fs_closing(fs_info)) { ++ while (!err && !(stopped = rescan_should_stop(fs_info))) { + trans = btrfs_start_transaction(fs_info->fs_root, 0); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); +@@ -3207,7 +3214,7 @@ out: + } + + mutex_lock(&fs_info->qgroup_rescan_lock); +- if (!btrfs_fs_closing(fs_info)) ++ if (!stopped) + fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN; + if (trans) { + ret = update_qgroup_status_item(trans); +@@ -3226,7 +3233,7 @@ out: + + btrfs_end_transaction(trans); + +- if (btrfs_fs_closing(fs_info)) { ++ if (stopped) { + btrfs_info(fs_info, "qgroup scan paused"); + } else if (err >= 0) { + btrfs_info(fs_info, "qgroup scan completed%s", +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index 6a2ae208ff80a..1a69bdb96fb2a 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -1792,6 +1792,14 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) + btrfs_scrub_cancel(fs_info); + btrfs_pause_balance(fs_info); + ++ /* ++ * Pause the qgroup rescan worker if it is running. We don't want ++ * it to be still running after we are in RO mode, as after that, ++ * by the time we unmount, it might have left a transaction open, ++ * so we would leak the transaction and/or crash. ++ */ ++ btrfs_qgroup_wait_for_completion(fs_info, false); ++ + ret = btrfs_commit_super(fs_info); + if (ret) + goto restore; +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index 9feb8a1793efb..7d06842a3d747 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -571,6 +571,7 @@ int btrfs_check_chunk_valid(struct extent_buffer *leaf, + { + struct btrfs_fs_info *fs_info = leaf->fs_info; + u64 length; ++ u64 chunk_end; + u64 stripe_len; + u16 num_stripes; + u16 sub_stripes; +@@ -625,6 +626,12 @@ int btrfs_check_chunk_valid(struct extent_buffer *leaf, + "invalid chunk length, have %llu", length); + return -EUCLEAN; + } ++ if (unlikely(check_add_overflow(logical, length, &chunk_end))) { ++ chunk_err(leaf, chunk, logical, ++"invalid chunk logical start and length, have logical start %llu length %llu", ++ logical, length); ++ return -EUCLEAN; ++ } + if (!is_power_of_2(stripe_len) || stripe_len != BTRFS_STRIPE_LEN) { + chunk_err(leaf, chunk, logical, + "invalid chunk stripe length: %llu", +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 7ff05c06f2a4c..be06b26d6ca03 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -2945,8 +2945,8 @@ SMB2_close_free(struct smb_rqst *rqst) + } + + int +-SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, +- u64 persistent_fid, u64 volatile_fid, int flags) ++SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, ++ u64 persistent_fid, u64 volatile_fid) + { + struct smb_rqst rqst; + struct smb2_close_rsp *rsp = NULL; +@@ -2955,6 +2955,7 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, + struct kvec rsp_iov; + int resp_buftype = CIFS_NO_BUFFER; + int rc = 0; ++ int flags = 0; + + cifs_dbg(FYI, "Close\n"); + +@@ -2993,27 +2994,17 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, + close_exit: + SMB2_close_free(&rqst); + free_rsp_buf(resp_buftype, rsp); +- return rc; +-} +- +-int +-SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, +- u64 persistent_fid, u64 volatile_fid) +-{ +- int rc; +- int tmp_rc; +- +- rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); + + /* retry close in a worker thread if this one is interrupted */ +- if (rc == -EINTR) { ++ if (is_interrupt_error(rc)) { ++ int tmp_rc; ++ + tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid, + volatile_fid); + if (tmp_rc) + cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n", + persistent_fid, tmp_rc); + } +- + return rc; + } + +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index 2a12a2fa38a22..57f7075a35871 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -156,8 +156,6 @@ extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, + + extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id); +-extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, +- u64 persistent_fid, u64 volatile_fid, int flags); + extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, + u64 persistent_file_id, u64 volatile_file_id); + extern void SMB2_close_free(struct smb_rqst *rqst); +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index fd7ce3573a00a..1513e90fb6d2f 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -432,7 +432,7 @@ static int ext4_sample_last_mounted(struct super_block *sb, + err = ext4_journal_get_write_access(handle, sbi->s_sbh); + if (err) + goto out_journal; +- strlcpy(sbi->s_es->s_last_mounted, cp, ++ strncpy(sbi->s_es->s_last_mounted, cp, + sizeof(sbi->s_es->s_last_mounted)); + ext4_handle_dirty_super(handle, sb); + out_journal: +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 0b7f316fd30f4..ba13fbb443d58 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -1160,7 +1160,10 @@ resizefs_out: + err = ext4_journal_get_write_access(handle, sbi->s_sbh); + if (err) + goto pwsalt_err_journal; ++ lock_buffer(sbi->s_sbh); + generate_random_uuid(sbi->s_es->s_encrypt_pw_salt); ++ ext4_superblock_csum_set(sb); ++ unlock_buffer(sbi->s_sbh); + err = ext4_handle_dirty_metadata(handle, NULL, + sbi->s_sbh); + pwsalt_err_journal: +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 59038e361337c..f05ec9bfbf4fd 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3544,8 +3544,6 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, + return retval; + } + } +- brelse(ent->bh); +- ent->bh = NULL; + + return 0; + } +@@ -3745,6 +3743,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + } + } + ++ old_file_type = old.de->file_type; + if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) + ext4_handle_sync(handle); + +@@ -3772,7 +3771,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + force_reread = (new.dir->i_ino == old.dir->i_ino && + ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA)); + +- old_file_type = old.de->file_type; + if (whiteout) { + /* + * Do this before adding a new entry, so the old entry is sure +@@ -3844,15 +3842,19 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, + retval = 0; + + end_rename: +- brelse(old.dir_bh); +- brelse(old.bh); +- brelse(new.bh); + if (whiteout) { +- if (retval) ++ if (retval) { ++ ext4_setent(handle, &old, ++ old.inode->i_ino, old_file_type); + drop_nlink(whiteout); ++ } + unlock_new_inode(whiteout); + iput(whiteout); ++ + } ++ brelse(old.dir_bh); ++ brelse(old.bh); ++ brelse(new.bh); + if (handle) + ext4_journal_stop(handle); + return retval; +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index 447a3c17fa8e6..9e717796e57b7 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -569,12 +569,14 @@ extern void nfs4_test_session_trunk(struct rpc_clnt *clnt, + + static inline struct inode *nfs_igrab_and_active(struct inode *inode) + { +- inode = igrab(inode); +- if (inode != NULL && !nfs_sb_active(inode->i_sb)) { +- iput(inode); +- inode = NULL; ++ struct super_block *sb = inode->i_sb; ++ ++ if (sb && nfs_sb_active(sb)) { ++ if (igrab(inode)) ++ return inode; ++ nfs_sb_deactive(sb); + } +- return inode; ++ return NULL; + } + + static inline void nfs_iput_and_deactive(struct inode *inode) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 8598eba3fc234..30e44b33040a4 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -3488,10 +3488,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data) + trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status); + + /* Handle Layoutreturn errors */ +- if (pnfs_roc_done(task, calldata->inode, +- &calldata->arg.lr_args, +- &calldata->res.lr_res, +- &calldata->res.lr_ret) == -EAGAIN) ++ if (pnfs_roc_done(task, &calldata->arg.lr_args, &calldata->res.lr_res, ++ &calldata->res.lr_ret) == -EAGAIN) + goto out_restart; + + /* hmm. we are done with the inode, and in the process of freeing +@@ -6238,10 +6236,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) + trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status); + + /* Handle Layoutreturn errors */ +- if (pnfs_roc_done(task, data->inode, +- &data->args.lr_args, +- &data->res.lr_res, +- &data->res.lr_ret) == -EAGAIN) ++ if (pnfs_roc_done(task, &data->args.lr_args, &data->res.lr_res, ++ &data->res.lr_ret) == -EAGAIN) + goto out_restart; + + switch (task->tk_status) { +@@ -6290,10 +6286,10 @@ static void nfs4_delegreturn_release(void *calldata) + struct nfs4_delegreturndata *data = calldata; + struct inode *inode = data->inode; + ++ if (data->lr.roc) ++ pnfs_roc_release(&data->lr.arg, &data->lr.res, ++ data->res.lr_ret); + if (inode) { +- if (data->lr.roc) +- pnfs_roc_release(&data->lr.arg, &data->lr.res, +- data->res.lr_ret); + nfs_post_op_update_inode_force_wcc(inode, &data->fattr); + nfs_iput_and_deactive(inode); + } +@@ -6368,16 +6364,14 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, + nfs_fattr_init(data->res.fattr); + data->timestamp = jiffies; + data->rpc_status = 0; +- data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res, cred); + data->inode = nfs_igrab_and_active(inode); +- if (data->inode) { ++ if (data->inode || issync) { ++ data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res, ++ cred); + if (data->lr.roc) { + data->args.lr_args = &data->lr.arg; + data->res.lr_res = &data->lr.res; + } +- } else if (data->lr.roc) { +- pnfs_roc_release(&data->lr.arg, &data->lr.res, 0); +- data->lr.roc = false; + } + + task_setup_data.callback_data = data; +@@ -6959,9 +6953,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f + data->arg.new_lock_owner, ret); + } else + data->cancelled = true; ++ trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret); + rpc_put_task(task); + dprintk("%s: done, ret = %d!\n", __func__, ret); +- trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret); + return ret; + } + +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 9fd115c4d0a2f..4232f956bdac0 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1475,10 +1475,8 @@ out_noroc: + return false; + } + +-int pnfs_roc_done(struct rpc_task *task, struct inode *inode, +- struct nfs4_layoutreturn_args **argpp, +- struct nfs4_layoutreturn_res **respp, +- int *ret) ++int pnfs_roc_done(struct rpc_task *task, struct nfs4_layoutreturn_args **argpp, ++ struct nfs4_layoutreturn_res **respp, int *ret) + { + struct nfs4_layoutreturn_args *arg = *argpp; + int retval = -EAGAIN; +@@ -1511,7 +1509,7 @@ int pnfs_roc_done(struct rpc_task *task, struct inode *inode, + return 0; + case -NFS4ERR_OLD_STATEID: + if (!nfs4_layout_refresh_old_stateid(&arg->stateid, +- &arg->range, inode)) ++ &arg->range, arg->inode)) + break; + *ret = -NFS4ERR_NOMATCHING_LAYOUT; + return -EAGAIN; +@@ -1526,12 +1524,18 @@ void pnfs_roc_release(struct nfs4_layoutreturn_args *args, + int ret) + { + struct pnfs_layout_hdr *lo = args->layout; ++ struct inode *inode = args->inode; + const nfs4_stateid *arg_stateid = NULL; + const nfs4_stateid *res_stateid = NULL; + struct nfs4_xdr_opaque_data *ld_private = args->ld_private; + + switch (ret) { + case -NFS4ERR_NOMATCHING_LAYOUT: ++ spin_lock(&inode->i_lock); ++ if (pnfs_layout_is_valid(lo) && ++ nfs4_stateid_match_other(&args->stateid, &lo->plh_stateid)) ++ pnfs_set_plh_return_info(lo, args->range.iomode, 0); ++ spin_unlock(&inode->i_lock); + break; + case 0: + if (res->lrs_present) +@@ -1982,6 +1986,27 @@ lookup_again: + goto lookup_again; + } + ++ /* ++ * Because we free lsegs when sending LAYOUTRETURN, we need to wait ++ * for LAYOUTRETURN. ++ */ ++ if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) { ++ spin_unlock(&ino->i_lock); ++ dprintk("%s wait for layoutreturn\n", __func__); ++ lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo)); ++ if (!IS_ERR(lseg)) { ++ pnfs_put_layout_hdr(lo); ++ dprintk("%s retrying\n", __func__); ++ trace_pnfs_update_layout(ino, pos, count, iomode, lo, ++ lseg, ++ PNFS_UPDATE_LAYOUT_RETRY); ++ goto lookup_again; ++ } ++ trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, ++ PNFS_UPDATE_LAYOUT_RETURN); ++ goto out_put_layout_hdr; ++ } ++ + lseg = pnfs_find_lseg(lo, &arg, strict_iomode); + if (lseg) { + trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, +@@ -2035,28 +2060,6 @@ lookup_again: + nfs4_stateid_copy(&stateid, &lo->plh_stateid); + } + +- /* +- * Because we free lsegs before sending LAYOUTRETURN, we need to wait +- * for LAYOUTRETURN even if first is true. +- */ +- if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) { +- spin_unlock(&ino->i_lock); +- dprintk("%s wait for layoutreturn\n", __func__); +- lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo)); +- if (!IS_ERR(lseg)) { +- if (first) +- pnfs_clear_first_layoutget(lo); +- pnfs_put_layout_hdr(lo); +- dprintk("%s retrying\n", __func__); +- trace_pnfs_update_layout(ino, pos, count, iomode, lo, +- lseg, PNFS_UPDATE_LAYOUT_RETRY); +- goto lookup_again; +- } +- trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, +- PNFS_UPDATE_LAYOUT_RETURN); +- goto out_put_layout_hdr; +- } +- + if (pnfs_layoutgets_blocked(lo)) { + trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, + PNFS_UPDATE_LAYOUT_BLOCKED); +@@ -2212,6 +2215,7 @@ static void _lgopen_prepare_attached(struct nfs4_opendata *data, + &rng, GFP_KERNEL); + if (!lgp) { + pnfs_clear_first_layoutget(lo); ++ nfs_layoutget_end(lo); + pnfs_put_layout_hdr(lo); + return; + } +diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h +index 63da33a92d831..3d55edd6b25ad 100644 +--- a/fs/nfs/pnfs.h ++++ b/fs/nfs/pnfs.h +@@ -283,10 +283,8 @@ bool pnfs_roc(struct inode *ino, + struct nfs4_layoutreturn_args *args, + struct nfs4_layoutreturn_res *res, + const struct cred *cred); +-int pnfs_roc_done(struct rpc_task *task, struct inode *inode, +- struct nfs4_layoutreturn_args **argpp, +- struct nfs4_layoutreturn_res **respp, +- int *ret); ++int pnfs_roc_done(struct rpc_task *task, struct nfs4_layoutreturn_args **argpp, ++ struct nfs4_layoutreturn_res **respp, int *ret); + void pnfs_roc_release(struct nfs4_layoutreturn_args *args, + struct nfs4_layoutreturn_res *res, + int ret); +@@ -711,7 +709,7 @@ pnfs_roc(struct inode *ino, + } + + static inline int +-pnfs_roc_done(struct rpc_task *task, struct inode *inode, ++pnfs_roc_done(struct rpc_task *task, + struct nfs4_layoutreturn_args **argpp, + struct nfs4_layoutreturn_res **respp, + int *ret) +diff --git a/include/linux/acpi.h b/include/linux/acpi.h +index ce29a014e591c..dd6170357ec72 100644 +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -837,6 +837,13 @@ static inline int acpi_device_modalias(struct device *dev, + return -ENODEV; + } + ++static inline struct platform_device * ++acpi_create_platform_device(struct acpi_device *adev, ++ struct property_entry *properties) ++{ ++ return NULL; ++} ++ + static inline bool acpi_dma_supported(struct acpi_device *adev) + { + return false; +diff --git a/include/linux/dm-bufio.h b/include/linux/dm-bufio.h +index 3c8b7d274bd9b..45ba37aaf6b78 100644 +--- a/include/linux/dm-bufio.h ++++ b/include/linux/dm-bufio.h +@@ -138,6 +138,7 @@ void dm_bufio_set_minimum_buffers(struct dm_bufio_client *c, unsigned n); + + unsigned dm_bufio_get_block_size(struct dm_bufio_client *c); + sector_t dm_bufio_get_device_size(struct dm_bufio_client *c); ++struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c); + sector_t dm_bufio_get_block_number(struct dm_buffer *b); + void *dm_bufio_get_block_data(struct dm_buffer *b); + void *dm_bufio_get_aux_data(struct dm_buffer *b); +diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig +index f3f2fc8ad81aa..9fa01dad655b4 100644 +--- a/kernel/trace/Kconfig ++++ b/kernel/trace/Kconfig +@@ -478,7 +478,7 @@ config KPROBE_EVENTS + config KPROBE_EVENTS_ON_NOTRACE + bool "Do NOT protect notrace function from kprobe events" + depends on KPROBE_EVENTS +- depends on KPROBES_ON_FTRACE ++ depends on DYNAMIC_FTRACE + default n + help + This is only for the developers who want to debug ftrace itself +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 26de9c6549566..1074a69beff3f 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -433,7 +433,7 @@ static int disable_trace_kprobe(struct trace_event_call *call, + return 0; + } + +-#if defined(CONFIG_KPROBES_ON_FTRACE) && \ ++#if defined(CONFIG_DYNAMIC_FTRACE) && \ + !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE) + static bool __within_notrace_func(unsigned long addr) + { +diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile +index 0083b5cc646c9..d4d56ca6eafce 100644 +--- a/lib/raid6/Makefile ++++ b/lib/raid6/Makefile +@@ -48,7 +48,7 @@ endif + endif + + quiet_cmd_unroll = UNROLL $@ +- cmd_unroll = $(AWK) -f$(srctree)/$(src)/unroll.awk -vN=$* < $< > $@ ++ cmd_unroll = $(AWK) -v N=$* -f $(srctree)/$(src)/unroll.awk < $< > $@ + + targets += int1.c int2.c int4.c int8.c int16.c int32.c + $(obj)/int%.c: $(src)/int.uc $(src)/unroll.awk FORCE +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 62ec514dae658..3bc33fa838177 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4036,7 +4036,7 @@ retry: + * So we need to block hugepage fault by PG_hwpoison bit check. + */ + if (unlikely(PageHWPoison(page))) { +- ret = VM_FAULT_HWPOISON | ++ ret = VM_FAULT_HWPOISON_LARGE | + VM_FAULT_SET_HINDEX(hstate_index(h)); + goto backout_unlocked; + } +diff --git a/mm/slub.c b/mm/slub.c +index f41414571c9eb..8b3ef45a0f103 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1887,7 +1887,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, + + t = acquire_slab(s, n, page, object == NULL, &objects); + if (!t) +- break; ++ continue; /* cmpxchg raced */ + + available += objects; + if (!object) { +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index 1a58cfdb862d6..500de37858ac8 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -630,7 +630,7 @@ mtype_resize(struct ip_set *set, bool retried) + struct htype *h = set->data; + struct htable *t, *orig; + u8 htable_bits; +- size_t dsize = set->dsize; ++ size_t hsize, dsize = set->dsize; + #ifdef IP_SET_HASH_WITH_NETS + u8 flags; + struct mtype_elem *tmp; +@@ -654,14 +654,12 @@ mtype_resize(struct ip_set *set, bool retried) + retry: + ret = 0; + htable_bits++; +- if (!htable_bits) { +- /* In case we have plenty of memory :-) */ +- pr_warn("Cannot increase the hashsize of set %s further\n", +- set->name); +- ret = -IPSET_ERR_HASH_FULL; +- goto out; +- } +- t = ip_set_alloc(htable_size(htable_bits)); ++ if (!htable_bits) ++ goto hbwarn; ++ hsize = htable_size(htable_bits); ++ if (!hsize) ++ goto hbwarn; ++ t = ip_set_alloc(hsize); + if (!t) { + ret = -ENOMEM; + goto out; +@@ -803,6 +801,12 @@ cleanup: + if (ret == -EAGAIN) + goto retry; + goto out; ++ ++hbwarn: ++ /* In case we have plenty of memory :-) */ ++ pr_warn("Cannot increase the hashsize of set %s further\n", set->name); ++ ret = -IPSET_ERR_HASH_FULL; ++ goto out; + } + + /* Get the current number of elements and ext_size in the set */ +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index 4912069627b65..dc57f530df9db 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -521,6 +521,9 @@ nf_conntrack_hash_sysctl(struct ctl_table *table, int write, + { + int ret; + ++ /* module_param hashsize could have changed value */ ++ nf_conntrack_htable_size_user = nf_conntrack_htable_size; ++ + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret < 0 || !write) + return ret; +diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c +index bfc555fcbc729..89b58aa890a74 100644 +--- a/net/netfilter/nf_nat_core.c ++++ b/net/netfilter/nf_nat_core.c +@@ -1174,6 +1174,7 @@ static int __init nf_nat_init(void) + ret = register_pernet_subsys(&nat_net_ops); + if (ret < 0) { + nf_ct_extend_unregister(&nat_extend); ++ kvfree(nf_nat_bysource); + return ret; + } + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 0e3e0ff805812..bbe03b9a03b12 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -27,8 +27,6 @@ struct nft_xt_match_priv { + void *info; + }; + +-static refcount_t nft_compat_pending_destroy = REFCOUNT_INIT(1); +- + static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx, + const char *tablename) + { +@@ -215,6 +213,17 @@ static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) + return 0; + } + ++static void nft_compat_wait_for_destructors(void) ++{ ++ /* xtables matches or targets can have side effects, e.g. ++ * creation/destruction of /proc files. ++ * The xt ->destroy functions are run asynchronously from ++ * work queue. If we have pending invocations we thus ++ * need to wait for those to finish. ++ */ ++ nf_tables_trans_destroy_flush_work(); ++} ++ + static int + nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + const struct nlattr * const tb[]) +@@ -238,14 +247,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + + nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); + +- /* xtables matches or targets can have side effects, e.g. +- * creation/destruction of /proc files. +- * The xt ->destroy functions are run asynchronously from +- * work queue. If we have pending invocations we thus +- * need to wait for those to finish. +- */ +- if (refcount_read(&nft_compat_pending_destroy) > 1) +- nf_tables_trans_destroy_flush_work(); ++ nft_compat_wait_for_destructors(); + + ret = xt_check_target(&par, size, proto, inv); + if (ret < 0) +@@ -260,7 +262,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + + static void __nft_mt_tg_destroy(struct module *me, const struct nft_expr *expr) + { +- refcount_dec(&nft_compat_pending_destroy); + module_put(me); + kfree(expr->ops); + } +@@ -468,6 +469,8 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + + nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); + ++ nft_compat_wait_for_destructors(); ++ + return xt_check_match(&par, size, proto, inv); + } + +@@ -716,14 +719,6 @@ static const struct nfnetlink_subsystem nfnl_compat_subsys = { + + static struct nft_expr_type nft_match_type; + +-static void nft_mt_tg_deactivate(const struct nft_ctx *ctx, +- const struct nft_expr *expr, +- enum nft_trans_phase phase) +-{ +- if (phase == NFT_TRANS_COMMIT) +- refcount_inc(&nft_compat_pending_destroy); +-} +- + static const struct nft_expr_ops * + nft_match_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) +@@ -762,7 +757,6 @@ nft_match_select_ops(const struct nft_ctx *ctx, + ops->type = &nft_match_type; + ops->eval = nft_match_eval; + ops->init = nft_match_init; +- ops->deactivate = nft_mt_tg_deactivate, + ops->destroy = nft_match_destroy; + ops->dump = nft_match_dump; + ops->validate = nft_match_validate; +@@ -853,7 +847,6 @@ nft_target_select_ops(const struct nft_ctx *ctx, + ops->size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize)); + ops->init = nft_target_init; + ops->destroy = nft_target_destroy; +- ops->deactivate = nft_mt_tg_deactivate, + ops->dump = nft_target_dump; + ops->validate = nft_target_validate; + ops->data = target; +@@ -917,8 +910,6 @@ static void __exit nft_compat_module_exit(void) + nfnetlink_subsys_unregister(&nfnl_compat_subsys); + nft_unregister_expr(&nft_target_type); + nft_unregister_expr(&nft_match_type); +- +- WARN_ON_ONCE(refcount_read(&nft_compat_pending_destroy) != 1); + } + + MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT); +diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c +index 105d17af4abcc..0d4a2bb09589c 100644 +--- a/net/sunrpc/addr.c ++++ b/net/sunrpc/addr.c +@@ -185,7 +185,7 @@ static int rpc_parse_scope_id(struct net *net, const char *buf, + scope_id = dev->ifindex; + dev_put(dev); + } else { +- if (kstrtou32(p, 10, &scope_id) == 0) { ++ if (kstrtou32(p, 10, &scope_id) != 0) { + kfree(p); + return 0; + } +diff --git a/security/lsm_audit.c b/security/lsm_audit.c +index e40874373f2b4..d025f575a9e30 100644 +--- a/security/lsm_audit.c ++++ b/security/lsm_audit.c +@@ -274,7 +274,9 @@ static void dump_common_audit_data(struct audit_buffer *ab, + struct inode *inode; + + audit_log_format(ab, " name="); ++ spin_lock(&a->u.dentry->d_lock); + audit_log_untrustedstring(ab, a->u.dentry->d_name.name); ++ spin_unlock(&a->u.dentry->d_lock); + + inode = d_backing_inode(a->u.dentry); + if (inode) { +@@ -292,8 +294,9 @@ static void dump_common_audit_data(struct audit_buffer *ab, + dentry = d_find_alias(inode); + if (dentry) { + audit_log_format(ab, " name="); +- audit_log_untrustedstring(ab, +- dentry->d_name.name); ++ spin_lock(&dentry->d_lock); ++ audit_log_untrustedstring(ab, dentry->d_name.name); ++ spin_unlock(&dentry->d_lock); + dput(dentry); + } + audit_log_format(ab, " dev="); +diff --git a/sound/firewire/fireface/ff-transaction.c b/sound/firewire/fireface/ff-transaction.c +index 7f82762ccc8c8..ee7122c461d46 100644 +--- a/sound/firewire/fireface/ff-transaction.c ++++ b/sound/firewire/fireface/ff-transaction.c +@@ -88,7 +88,7 @@ static void transmit_midi_msg(struct snd_ff *ff, unsigned int port) + + /* Set interval to next transaction. */ + ff->next_ktime[port] = ktime_add_ns(ktime_get(), +- ff->rx_bytes[port] * 8 * NSEC_PER_SEC / 31250); ++ ff->rx_bytes[port] * 8 * (NSEC_PER_SEC / 31250)); + + if (quad_count == 1) + tcode = TCODE_WRITE_QUADLET_REQUEST; +diff --git a/sound/firewire/tascam/tascam-transaction.c b/sound/firewire/tascam/tascam-transaction.c +index 90288b4b46379..a073cece4a7d5 100644 +--- a/sound/firewire/tascam/tascam-transaction.c ++++ b/sound/firewire/tascam/tascam-transaction.c +@@ -209,7 +209,7 @@ static void midi_port_work(struct work_struct *work) + + /* Set interval to next transaction. */ + port->next_ktime = ktime_add_ns(ktime_get(), +- port->consume_bytes * 8 * NSEC_PER_SEC / 31250); ++ port->consume_bytes * 8 * (NSEC_PER_SEC / 31250)); + + /* Start this transaction. */ + port->idling = false; +diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c +index c6abcd5aa67b9..e808f62960ba7 100644 +--- a/sound/soc/intel/skylake/cnl-sst.c ++++ b/sound/soc/intel/skylake/cnl-sst.c +@@ -224,6 +224,7 @@ static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) + "dsp boot timeout, status=%#x error=%#x\n", + sst_dsp_shim_read(ctx, CNL_ADSP_FW_STATUS), + sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE)); ++ ret = -ETIMEDOUT; + goto err; + } + } else { +diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c +index e25336f739123..f5a431b8de6c3 100644 +--- a/sound/soc/meson/axg-tdm-interface.c ++++ b/sound/soc/meson/axg-tdm-interface.c +@@ -467,8 +467,20 @@ static int axg_tdm_iface_set_bias_level(struct snd_soc_component *component, + return ret; + } + ++static const struct snd_soc_dapm_widget axg_tdm_iface_dapm_widgets[] = { ++ SND_SOC_DAPM_SIGGEN("Playback Signal"), ++}; ++ ++static const struct snd_soc_dapm_route axg_tdm_iface_dapm_routes[] = { ++ { "Loopback", NULL, "Playback Signal" }, ++}; ++ + static const struct snd_soc_component_driver axg_tdm_iface_component_drv = { +- .set_bias_level = axg_tdm_iface_set_bias_level, ++ .dapm_widgets = axg_tdm_iface_dapm_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(axg_tdm_iface_dapm_widgets), ++ .dapm_routes = axg_tdm_iface_dapm_routes, ++ .num_dapm_routes = ARRAY_SIZE(axg_tdm_iface_dapm_routes), ++ .set_bias_level = axg_tdm_iface_set_bias_level, + }; + + static const struct of_device_id axg_tdm_iface_of_match[] = { +diff --git a/sound/soc/meson/axg-tdmin.c b/sound/soc/meson/axg-tdmin.c +index 88ed95ae886bb..b4faf9d5c1aad 100644 +--- a/sound/soc/meson/axg-tdmin.c ++++ b/sound/soc/meson/axg-tdmin.c +@@ -224,15 +224,6 @@ static const struct axg_tdm_formatter_ops axg_tdmin_ops = { + }; + + static const struct axg_tdm_formatter_driver axg_tdmin_drv = { +- .component_drv = &axg_tdmin_component_drv, +- .regmap_cfg = &axg_tdmin_regmap_cfg, +- .ops = &axg_tdmin_ops, +- .quirks = &(const struct axg_tdm_formatter_hw) { +- .skew_offset = 2, +- }, +-}; +- +-static const struct axg_tdm_formatter_driver g12a_tdmin_drv = { + .component_drv = &axg_tdmin_component_drv, + .regmap_cfg = &axg_tdmin_regmap_cfg, + .ops = &axg_tdmin_ops, +@@ -247,10 +238,10 @@ static const struct of_device_id axg_tdmin_of_match[] = { + .data = &axg_tdmin_drv, + }, { + .compatible = "amlogic,g12a-tdmin", +- .data = &g12a_tdmin_drv, ++ .data = &axg_tdmin_drv, + }, { + .compatible = "amlogic,sm1-tdmin", +- .data = &g12a_tdmin_drv, ++ .data = &axg_tdmin_drv, + }, {} + }; + MODULE_DEVICE_TABLE(of, axg_tdmin_of_match); +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 06aa393797497..7c4d5963692dd 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -2484,6 +2484,7 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) + enum snd_soc_dapm_direction dir; + + list_del(&w->list); ++ list_del(&w->dirty); + /* + * remove source and sink paths associated to this widget. + * While removing the path, remove reference to it from both +diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c +index ea277ce63a463..767fe1bfd922c 100644 +--- a/tools/perf/util/machine.c ++++ b/tools/perf/util/machine.c +@@ -2587,7 +2587,7 @@ int machines__for_each_thread(struct machines *machines, + + pid_t machine__get_current_tid(struct machine *machine, int cpu) + { +- int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); ++ int nr_cpus = min(machine->env->nr_cpus_avail, MAX_NR_CPUS); + + if (cpu < 0 || cpu >= nr_cpus || !machine->current_tid) + return -1; +@@ -2599,7 +2599,7 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, + pid_t tid) + { + struct thread *thread; +- int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); ++ int nr_cpus = min(machine->env->nr_cpus_avail, MAX_NR_CPUS); + + if (cpu < 0) + return -EINVAL; +diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c +index ff524a3fc5003..b21a4b1918db5 100644 +--- a/tools/perf/util/session.c ++++ b/tools/perf/util/session.c +@@ -2314,7 +2314,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, + { + int i, err = -1; + struct perf_cpu_map *map; +- int nr_cpus = min(session->header.env.nr_cpus_online, MAX_NR_CPUS); ++ int nr_cpus = min(session->header.env.nr_cpus_avail, MAX_NR_CPUS); + + for (i = 0; i < PERF_TYPE_MAX; ++i) { + struct evsel *evsel; +diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh +index ac2a30be9b325..f8a19f548ae9d 100755 +--- a/tools/testing/selftests/net/udpgro.sh ++++ b/tools/testing/selftests/net/udpgro.sh +@@ -5,6 +5,14 @@ + + readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" + ++# set global exit status, but never reset nonzero one. ++check_err() ++{ ++ if [ $ret -eq 0 ]; then ++ ret=$1 ++ fi ++} ++ + cleanup() { + local -r jobs="$(jobs -p)" + local -r ns="$(ip netns list|grep $PEER_NS)" +@@ -44,7 +52,9 @@ run_one() { + # Hack: let bg programs complete the startup + sleep 0.1 + ./udpgso_bench_tx ${tx_args} ++ ret=$? + wait $(jobs -p) ++ return $ret + } + + run_test() { +@@ -87,8 +97,10 @@ run_one_nat() { + + sleep 0.1 + ./udpgso_bench_tx ${tx_args} ++ ret=$? + kill -INT $pid + wait $(jobs -p) ++ return $ret + } + + run_one_2sock() { +@@ -110,7 +122,9 @@ run_one_2sock() { + sleep 0.1 + # first UDP GSO socket should be closed at this point + ./udpgso_bench_tx ${tx_args} ++ ret=$? + wait $(jobs -p) ++ return $ret + } + + run_nat_test() { +@@ -131,36 +145,54 @@ run_all() { + local -r core_args="-l 4" + local -r ipv4_args="${core_args} -4 -D 192.168.1.1" + local -r ipv6_args="${core_args} -6 -D 2001:db8::1" ++ ret=0 + + echo "ipv4" + run_test "no GRO" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400" ++ check_err $? + + # explicitly check we are not receiving UDP_SEGMENT cmsg (-S -1) + # when GRO does not take place + run_test "no GRO chk cmsg" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400 -S -1" ++ check_err $? + + # the GSO packets are aggregated because: + # * veth schedule napi after each xmit + # * segmentation happens in BH context, veth napi poll is delayed after + # the transmission of the last segment + run_test "GRO" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720" ++ check_err $? + run_test "GRO chk cmsg" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472" ++ check_err $? + run_test "GRO with custom segment size" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720" ++ check_err $? + run_test "GRO with custom segment size cmsg" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720 -S 500" ++ check_err $? + + run_nat_test "bad GRO lookup" "${ipv4_args} -M 1 -s 14720 -S 0" "-n 10 -l 1472" ++ check_err $? + run_2sock_test "multiple GRO socks" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472" ++ check_err $? + + echo "ipv6" + run_test "no GRO" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400" ++ check_err $? + run_test "no GRO chk cmsg" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400 -S -1" ++ check_err $? + run_test "GRO" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520" ++ check_err $? + run_test "GRO chk cmsg" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520 -S 1452" ++ check_err $? + run_test "GRO with custom segment size" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520" ++ check_err $? + run_test "GRO with custom segment size cmsg" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520 -S 500" ++ check_err $? + + run_nat_test "bad GRO lookup" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 10 -l 1452" ++ check_err $? + run_2sock_test "multiple GRO socks" "${ipv6_args} -M 1 -s 14520 -S 0 " "-n 1 -l 14520 -S 1452" ++ check_err $? ++ return $ret + } + + if [ ! -f ../bpf/xdp_dummy.o ]; then +@@ -180,3 +212,5 @@ elif [[ $1 == "__subprocess_2sock" ]]; then + shift + run_one_2sock $@ + fi ++ ++exit $?