commit: f927b5f48ad13b6aff7c45ff00262f45ce98b287 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Tue Aug 7 18:12:21 2018 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Tue Aug 7 18:12:21 2018 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f927b5f4
Linux patch 4.9.118 0000_README | 4 + 1117_linux-4.9.118.patch | 824 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 828 insertions(+) diff --git a/0000_README b/0000_README index 6be74fa..72692be 100644 --- a/0000_README +++ b/0000_README @@ -511,6 +511,10 @@ Patch: 1116_linux-4.9.117.patch From: http://www.kernel.org Desc: Linux 4.9.117 +Patch: 1117_linux-4.9.118.patch +From: http://www.kernel.org +Desc: Linux 4.9.118 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1117_linux-4.9.118.patch b/1117_linux-4.9.118.patch new file mode 100644 index 0000000..828be2f --- /dev/null +++ b/1117_linux-4.9.118.patch @@ -0,0 +1,824 @@ +diff --git a/Makefile b/Makefile +index 773c26c95d98..0940f11fa071 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 117 ++SUBLEVEL = 118 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 4e0292e0aafb..30b74b491909 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -7085,6 +7085,8 @@ static int handle_vmon(struct kvm_vcpu *vcpu) + HRTIMER_MODE_REL_PINNED); + vmx->nested.preemption_timer.function = vmx_preemption_timer_fn; + ++ vmx->nested.vpid02 = allocate_vpid(); ++ + vmx->nested.vmxon = true; + + skip_emulated_instruction(vcpu); +@@ -9264,10 +9266,8 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) + goto free_vmcs; + } + +- if (nested) { ++ if (nested) + nested_vmx_setup_ctls_msrs(vmx); +- vmx->nested.vpid02 = allocate_vpid(); +- } + + vmx->nested.posted_intr_nv = -1; + vmx->nested.current_vmptr = -1ull; +@@ -9285,7 +9285,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) + return &vmx->vcpu; + + free_vmcs: +- free_vpid(vmx->nested.vpid02); + free_loaded_vmcs(vmx->loaded_vmcs); + free_msrs: + kfree(vmx->guest_msrs); +diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c +index 9126627cbf4d..75f2bef79718 100644 +--- a/drivers/crypto/padlock-aes.c ++++ b/drivers/crypto/padlock-aes.c +@@ -266,6 +266,8 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, + return; + } + ++ count -= initial; ++ + if (initial) + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "+S"(input), "+D"(output) +@@ -273,7 +275,7 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, + + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "+S"(input), "+D"(output) +- : "d"(control_word), "b"(key), "c"(count - initial)); ++ : "d"(control_word), "b"(key), "c"(count)); + } + + static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, +@@ -284,6 +286,8 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, + if (count < cbc_fetch_blocks) + return cbc_crypt(input, output, key, iv, control_word, count); + ++ count -= initial; ++ + if (initial) + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ + : "+S" (input), "+D" (output), "+a" (iv) +@@ -291,7 +295,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, + + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ + : "+S" (input), "+D" (output), "+a" (iv) +- : "d" (control_word), "b" (key), "c" (count-initial)); ++ : "d" (control_word), "b" (key), "c" (count)); + return iv; + } + +diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c +index 75056553b06c..f8c9f6f4f822 100644 +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -350,6 +350,9 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) + vc4_state->x_scaling[0] = VC4_SCALING_TPZ; + if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) + vc4_state->y_scaling[0] = VC4_SCALING_TPZ; ++ } else { ++ vc4_state->x_scaling[1] = VC4_SCALING_NONE; ++ vc4_state->y_scaling[1] = VC4_SCALING_NONE; + } + + vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE && +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index f5fcc0850dac..8a5e0ae4e4c0 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1682,6 +1682,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + goto err_upper_unlink; + } + ++ bond->nest_level = dev_get_nest_level(bond_dev) + 1; ++ + /* If the mode uses primary, then the following is handled by + * bond_change_active_slave(). + */ +@@ -1729,7 +1731,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + if (bond_mode_uses_xmit_hash(bond)) + bond_update_slave_arr(bond, NULL); + +- bond->nest_level = dev_get_nest_level(bond_dev); + + netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", + slave_dev->name, +@@ -3359,6 +3360,13 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res, + } + } + ++static int bond_get_nest_level(struct net_device *bond_dev) ++{ ++ struct bonding *bond = netdev_priv(bond_dev); ++ ++ return bond->nest_level; ++} ++ + static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 *stats) + { +@@ -3367,7 +3375,7 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, + struct list_head *iter; + struct slave *slave; + +- spin_lock(&bond->stats_lock); ++ spin_lock_nested(&bond->stats_lock, bond_get_nest_level(bond_dev)); + memcpy(stats, &bond->bond_stats, sizeof(*stats)); + + rcu_read_lock(); +@@ -4163,6 +4171,7 @@ static const struct net_device_ops bond_netdev_ops = { + .ndo_neigh_setup = bond_neigh_setup, + .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, ++ .ndo_get_lock_subclass = bond_get_nest_level, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_netpoll_setup = bond_netpoll_setup, + .ndo_netpoll_cleanup = bond_netpoll_cleanup, +@@ -4655,6 +4664,7 @@ static int bond_init(struct net_device *bond_dev) + if (!bond->wq) + return -ENOMEM; + ++ bond->nest_level = SINGLE_DEPTH_NESTING; + netdev_lockdep_set_classes(bond_dev); + + list_add_tail(&bond->bond_list, &bn->dev_list); +diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c +index b00358297424..d0846ae9e0e4 100644 +--- a/drivers/net/can/usb/ems_usb.c ++++ b/drivers/net/can/usb/ems_usb.c +@@ -1071,6 +1071,7 @@ static void ems_usb_disconnect(struct usb_interface *intf) + usb_free_urb(dev->intr_urb); + + kfree(dev->intr_in_buffer); ++ kfree(dev->tx_msg_buffer); + } + } + +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c +index e13c9cd45dc0..bcd993140f84 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -331,6 +331,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev, + + memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr)); + ++ io_sq->dma_addr_bits = ena_dev->dma_addr_bits; + io_sq->desc_entry_size = + (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ? + sizeof(struct ena_eth_io_tx_desc) : +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +index 84c5d296d13e..684835833fe3 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +@@ -877,14 +877,14 @@ static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata) + + if (pdata->tx_pause != pdata->phy.tx_pause) { + new_state = 1; +- pdata->hw_if.config_tx_flow_control(pdata); + pdata->tx_pause = pdata->phy.tx_pause; ++ pdata->hw_if.config_tx_flow_control(pdata); + } + + if (pdata->rx_pause != pdata->phy.rx_pause) { + new_state = 1; +- pdata->hw_if.config_rx_flow_control(pdata); + pdata->rx_pause = pdata->phy.rx_pause; ++ pdata->hw_if.config_rx_flow_control(pdata); + } + + /* Speed support */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index b3bc1287b2a7..0df71865fab1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -55,7 +55,7 @@ + #include <linux/of_mdio.h> + #include "dwmac1000.h" + +-#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) ++#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) + #define TSO_MAX_BUFF_SIZE (SZ_16K - 1) + + /* Module parameters */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +index 56c8a2342c14..eafc28142cd2 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +@@ -183,7 +183,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev, + return -ENOMEM; + + /* Enable pci device */ +- ret = pcim_enable_device(pdev); ++ ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", + __func__); +@@ -232,9 +232,45 @@ static int stmmac_pci_probe(struct pci_dev *pdev, + static void stmmac_pci_remove(struct pci_dev *pdev) + { + stmmac_dvr_remove(&pdev->dev); ++ pci_disable_device(pdev); + } + +-static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_suspend, stmmac_resume); ++static int stmmac_pci_suspend(struct device *dev) ++{ ++ struct pci_dev *pdev = to_pci_dev(dev); ++ int ret; ++ ++ ret = stmmac_suspend(dev); ++ if (ret) ++ return ret; ++ ++ ret = pci_save_state(pdev); ++ if (ret) ++ return ret; ++ ++ pci_disable_device(pdev); ++ pci_wake_from_d3(pdev, true); ++ return 0; ++} ++ ++static int stmmac_pci_resume(struct device *dev) ++{ ++ struct pci_dev *pdev = to_pci_dev(dev); ++ int ret; ++ ++ pci_restore_state(pdev); ++ pci_set_power_state(pdev, PCI_D0); ++ ++ ret = pci_enable_device(pdev); ++ if (ret) ++ return ret; ++ ++ pci_set_master(pdev); ++ ++ return stmmac_resume(dev); ++} ++ ++static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume); + + #define STMMAC_VENDOR_ID 0x700 + #define STMMAC_QUARK_ID 0x0937 +diff --git a/drivers/net/phy/mdio-mux-bcm-iproc.c b/drivers/net/phy/mdio-mux-bcm-iproc.c +index 0a5f62e0efcc..487bf5b8f545 100644 +--- a/drivers/net/phy/mdio-mux-bcm-iproc.c ++++ b/drivers/net/phy/mdio-mux-bcm-iproc.c +@@ -218,7 +218,7 @@ out: + + static int mdio_mux_iproc_remove(struct platform_device *pdev) + { +- struct iproc_mdiomux_desc *md = dev_get_platdata(&pdev->dev); ++ struct iproc_mdiomux_desc *md = platform_get_drvdata(pdev); + + mdio_mux_uninit(md->mux_handle); + mdiobus_unregister(md->mii_bus); +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 5e0626c80b81..c5e04d1ad73a 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1170,6 +1170,8 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + mod_timer(&dev->stat_monitor, + jiffies + STAT_UPDATE_TIMER); + } ++ ++ tasklet_schedule(&dev->bh); + } + + return ret; +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index a5908e4c06cb..681256f97cb3 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -86,6 +86,7 @@ struct netfront_cb { + /* IRQ name is queue name with "-tx" or "-rx" appended */ + #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) + ++static DECLARE_WAIT_QUEUE_HEAD(module_load_q); + static DECLARE_WAIT_QUEUE_HEAD(module_unload_q); + + struct netfront_stats { +@@ -1349,6 +1350,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) + netif_carrier_off(netdev); + + xenbus_switch_state(dev, XenbusStateInitialising); ++ wait_event(module_load_q, ++ xenbus_read_driver_state(dev->otherend) != ++ XenbusStateClosed && ++ xenbus_read_driver_state(dev->otherend) != ++ XenbusStateUnknown); + return netdev; + + exit: +diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c +index b40a074822cf..15aeeb2159cc 100644 +--- a/drivers/pinctrl/intel/pinctrl-intel.c ++++ b/drivers/pinctrl/intel/pinctrl-intel.c +@@ -604,12 +604,17 @@ static int intel_gpio_get(struct gpio_chip *chip, unsigned offset) + { + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + void __iomem *reg; ++ u32 padcfg0; + + reg = intel_get_padcfg(pctrl, offset, PADCFG0); + if (!reg) + return -EINVAL; + +- return !!(readl(reg) & PADCFG0_GPIORXSTATE); ++ padcfg0 = readl(reg); ++ if (!(padcfg0 & PADCFG0_GPIOTXDIS)) ++ return !!(padcfg0 & PADCFG0_GPIOTXSTATE); ++ ++ return !!(padcfg0 & PADCFG0_GPIORXSTATE); + } + + static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 2065a0f9dca6..8d9b416399f9 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -2185,6 +2185,7 @@ sg_add_sfp(Sg_device * sdp) + write_lock_irqsave(&sdp->sfd_lock, iflags); + if (atomic_read(&sdp->detaching)) { + write_unlock_irqrestore(&sdp->sfd_lock, iflags); ++ kfree(sfp); + return ERR_PTR(-ENODEV); + } + list_add_tail(&sfp->sfd_siblings, &sdp->sfds); +diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c +index a7c08cc4c1b7..30076956a096 100644 +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -493,7 +493,9 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, + tell_host(vb, vb->inflate_vq); + + /* balloon's page migration 2nd step -- deflate "page" */ ++ spin_lock_irqsave(&vb_dev_info->pages_lock, flags); + balloon_page_delete(page); ++ spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags); + vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; + set_page_pfns(vb, vb->pfns, page); + tell_host(vb, vb->deflate_vq); +diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c +index ce62a380314f..cec0fa208078 100644 +--- a/fs/squashfs/block.c ++++ b/fs/squashfs/block.c +@@ -166,6 +166,8 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, + } + + if (compressed) { ++ if (!msblk->stream) ++ goto read_failure; + length = squashfs_decompress(msblk, bh, b, offset, length, + output); + if (length < 0) +diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c +index 86ad9a4b8c36..0681feab4a84 100644 +--- a/fs/squashfs/fragment.c ++++ b/fs/squashfs/fragment.c +@@ -49,11 +49,16 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment, + u64 *fragment_block) + { + struct squashfs_sb_info *msblk = sb->s_fs_info; +- int block = SQUASHFS_FRAGMENT_INDEX(fragment); +- int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); +- u64 start_block = le64_to_cpu(msblk->fragment_index[block]); ++ int block, offset, size; + struct squashfs_fragment_entry fragment_entry; +- int size; ++ u64 start_block; ++ ++ if (fragment >= msblk->fragments) ++ return -EIO; ++ block = SQUASHFS_FRAGMENT_INDEX(fragment); ++ offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); ++ ++ start_block = le64_to_cpu(msblk->fragment_index[block]); + + size = squashfs_read_metadata(sb, &fragment_entry, &start_block, + &offset, sizeof(fragment_entry)); +diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h +index 1da565cb50c3..ef69c31947bf 100644 +--- a/fs/squashfs/squashfs_fs_sb.h ++++ b/fs/squashfs/squashfs_fs_sb.h +@@ -75,6 +75,7 @@ struct squashfs_sb_info { + unsigned short block_log; + long long bytes_used; + unsigned int inodes; ++ unsigned int fragments; + int xattr_ids; + }; + #endif +diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c +index cf01e15a7b16..1516bb779b8d 100644 +--- a/fs/squashfs/super.c ++++ b/fs/squashfs/super.c +@@ -175,6 +175,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) + msblk->inode_table = le64_to_cpu(sblk->inode_table_start); + msblk->directory_table = le64_to_cpu(sblk->directory_table_start); + msblk->inodes = le32_to_cpu(sblk->inodes); ++ msblk->fragments = le32_to_cpu(sblk->fragments); + flags = le16_to_cpu(sblk->flags); + + TRACE("Found valid superblock on %pg\n", sb->s_bdev); +@@ -185,7 +186,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) + TRACE("Filesystem size %lld bytes\n", msblk->bytes_used); + TRACE("Block size %d\n", msblk->block_size); + TRACE("Number of inodes %d\n", msblk->inodes); +- TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments)); ++ TRACE("Number of fragments %d\n", msblk->fragments); + TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids)); + TRACE("sblk->inode_table_start %llx\n", msblk->inode_table); + TRACE("sblk->directory_table_start %llx\n", msblk->directory_table); +@@ -272,7 +273,7 @@ allocate_id_index_table: + sb->s_export_op = &squashfs_export_ops; + + handle_fragments: +- fragments = le32_to_cpu(sblk->fragments); ++ fragments = msblk->fragments; + if (fragments == 0) + goto check_directory_table; + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 5d440bb0e409..97d210535cdd 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -363,7 +363,7 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); + +-void tcp_enter_quickack_mode(struct sock *sk); ++void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks); + static inline void tcp_dec_quickack_mode(struct sock *sk, + const unsigned int pkts) + { +diff --git a/kernel/sched/swait.c b/kernel/sched/swait.c +index 82f0dff90030..9c2da06a8869 100644 +--- a/kernel/sched/swait.c ++++ b/kernel/sched/swait.c +@@ -33,9 +33,6 @@ void swake_up(struct swait_queue_head *q) + { + unsigned long flags; + +- if (!swait_active(q)) +- return; +- + raw_spin_lock_irqsave(&q->lock, flags); + swake_up_locked(q); + raw_spin_unlock_irqrestore(&q->lock, flags); +@@ -51,9 +48,6 @@ void swake_up_all(struct swait_queue_head *q) + struct swait_queue *curr; + LIST_HEAD(tmp); + +- if (!swait_active(q)) +- return; +- + raw_spin_lock_irq(&q->lock); + list_splice_init(&q->task_list, &tmp); + while (!list_empty(&tmp)) { +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 5000e6f20f4a..339d9c678d3e 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -1199,6 +1199,9 @@ int dsa_slave_suspend(struct net_device *slave_dev) + { + struct dsa_slave_priv *p = netdev_priv(slave_dev); + ++ if (!netif_running(slave_dev)) ++ return 0; ++ + netif_device_detach(slave_dev); + + if (p->phy) { +@@ -1216,6 +1219,9 @@ int dsa_slave_resume(struct net_device *slave_dev) + { + struct dsa_slave_priv *p = netdev_priv(slave_dev); + ++ if (!netif_running(slave_dev)) ++ return 0; ++ + netif_device_attach(slave_dev); + + if (p->phy) { +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 7bdd89354db5..6a2ef162088d 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -282,19 +282,19 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) + return ip_hdr(skb)->daddr; + + in_dev = __in_dev_get_rcu(dev); +- BUG_ON(!in_dev); + + net = dev_net(dev); + + scope = RT_SCOPE_UNIVERSE; + if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) { ++ bool vmark = in_dev && IN_DEV_SRC_VMARK(in_dev); + struct flowi4 fl4 = { + .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_scope = scope, +- .flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0, ++ .flowi4_mark = vmark ? skb->mark : 0, + }; + if (!fib_lookup(net, &fl4, &res, 0)) + return FIB_RES_PREFSRC(net, res); +diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c +index 8effac0f2219..f8b41aaac76f 100644 +--- a/net/ipv4/inet_fragment.c ++++ b/net/ipv4/inet_fragment.c +@@ -356,11 +356,6 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, + { + struct inet_frag_queue *q; + +- if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh) { +- inet_frag_schedule_worker(f); +- return NULL; +- } +- + q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC); + if (!q) + return NULL; +@@ -397,6 +392,11 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, + struct inet_frag_queue *q; + int depth = 0; + ++ if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh) { ++ inet_frag_schedule_worker(f); ++ return NULL; ++ } ++ + if (frag_mem_limit(nf) > nf->low_thresh) + inet_frag_schedule_worker(f); + +diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c +index 4bf3b8af0257..752711cd4834 100644 +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -446,11 +446,16 @@ found: + int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */ + + if (i < next->len) { ++ int delta = -next->truesize; ++ + /* Eat head of the next overlapped fragment + * and leave the loop. The next ones cannot overlap. + */ + if (!pskb_pull(next, i)) + goto err; ++ delta += next->truesize; ++ if (delta) ++ add_frag_mem_limit(qp->q.net, delta); + FRAG_CB(next)->offset += i; + qp->q.meat -= i; + if (next->ip_summed != CHECKSUM_UNNECESSARY) +diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c +index 9169859506b7..7e44d23b0328 100644 +--- a/net/ipv4/tcp_bbr.c ++++ b/net/ipv4/tcp_bbr.c +@@ -324,6 +324,10 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain) + /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ + cwnd = (cwnd + 1) & ~1U; + ++ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ ++ if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT) ++ cwnd += 2; ++ + return cwnd; + } + +diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c +index dd52ccb812ea..8905a0aec8ee 100644 +--- a/net/ipv4/tcp_dctcp.c ++++ b/net/ipv4/tcp_dctcp.c +@@ -138,7 +138,7 @@ static void dctcp_ce_state_0_to_1(struct sock *sk) + */ + if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER) + __tcp_send_ack(sk, ca->prior_rcv_nxt); +- tcp_enter_quickack_mode(sk); ++ tcp_enter_quickack_mode(sk, 1); + } + + ca->prior_rcv_nxt = tp->rcv_nxt; +@@ -159,7 +159,7 @@ static void dctcp_ce_state_1_to_0(struct sock *sk) + */ + if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER) + __tcp_send_ack(sk, ca->prior_rcv_nxt); +- tcp_enter_quickack_mode(sk); ++ tcp_enter_quickack_mode(sk, 1); + } + + ca->prior_rcv_nxt = tp->rcv_nxt; +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 44d136fd2af5..a9be8df108b4 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -198,21 +198,23 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb) + } + } + +-static void tcp_incr_quickack(struct sock *sk) ++static void tcp_incr_quickack(struct sock *sk, unsigned int max_quickacks) + { + struct inet_connection_sock *icsk = inet_csk(sk); + unsigned int quickacks = tcp_sk(sk)->rcv_wnd / (2 * icsk->icsk_ack.rcv_mss); + + if (quickacks == 0) + quickacks = 2; ++ quickacks = min(quickacks, max_quickacks); + if (quickacks > icsk->icsk_ack.quick) +- icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); ++ icsk->icsk_ack.quick = quickacks; + } + +-void tcp_enter_quickack_mode(struct sock *sk) ++void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) + { + struct inet_connection_sock *icsk = inet_csk(sk); +- tcp_incr_quickack(sk); ++ ++ tcp_incr_quickack(sk, max_quickacks); + icsk->icsk_ack.pingpong = 0; + icsk->icsk_ack.ato = TCP_ATO_MIN; + } +@@ -248,8 +250,10 @@ static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp) + tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; + } + +-static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb) ++static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb) + { ++ struct tcp_sock *tp = tcp_sk(sk); ++ + switch (TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK) { + case INET_ECN_NOT_ECT: + /* Funny extension: if ECT is not set on a segment, +@@ -257,31 +261,31 @@ static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb) + * it is probably a retransmit. + */ + if (tp->ecn_flags & TCP_ECN_SEEN) +- tcp_enter_quickack_mode((struct sock *)tp); ++ tcp_enter_quickack_mode(sk, 2); + break; + case INET_ECN_CE: +- if (tcp_ca_needs_ecn((struct sock *)tp)) +- tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_IS_CE); ++ if (tcp_ca_needs_ecn(sk)) ++ tcp_ca_event(sk, CA_EVENT_ECN_IS_CE); + + if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) { + /* Better not delay acks, sender can have a very low cwnd */ +- tcp_enter_quickack_mode((struct sock *)tp); ++ tcp_enter_quickack_mode(sk, 2); + tp->ecn_flags |= TCP_ECN_DEMAND_CWR; + } + tp->ecn_flags |= TCP_ECN_SEEN; + break; + default: +- if (tcp_ca_needs_ecn((struct sock *)tp)) +- tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_NO_CE); ++ if (tcp_ca_needs_ecn(sk)) ++ tcp_ca_event(sk, CA_EVENT_ECN_NO_CE); + tp->ecn_flags |= TCP_ECN_SEEN; + break; + } + } + +-static void tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb) ++static void tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb) + { +- if (tp->ecn_flags & TCP_ECN_OK) +- __tcp_ecn_check_ce(tp, skb); ++ if (tcp_sk(sk)->ecn_flags & TCP_ECN_OK) ++ __tcp_ecn_check_ce(sk, skb); + } + + static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th) +@@ -675,7 +679,7 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb) + /* The _first_ data packet received, initialize + * delayed ACK engine. + */ +- tcp_incr_quickack(sk); ++ tcp_incr_quickack(sk, TCP_MAX_QUICKACKS); + icsk->icsk_ack.ato = TCP_ATO_MIN; + } else { + int m = now - icsk->icsk_ack.lrcvtime; +@@ -691,13 +695,13 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb) + /* Too long gap. Apparently sender failed to + * restart window, so that we send ACKs quickly. + */ +- tcp_incr_quickack(sk); ++ tcp_incr_quickack(sk, TCP_MAX_QUICKACKS); + sk_mem_reclaim(sk); + } + } + icsk->icsk_ack.lrcvtime = now; + +- tcp_ecn_check_ce(tp, skb); ++ tcp_ecn_check_ce(sk, skb); + + if (skb->len >= 128) + tcp_grow_window(sk, skb); +@@ -4210,7 +4214,7 @@ static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb) + if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && + before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); +- tcp_enter_quickack_mode(sk); ++ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); + + if (tcp_is_sack(tp) && sysctl_tcp_dsack) { + u32 end_seq = TCP_SKB_CB(skb)->end_seq; +@@ -4454,7 +4458,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) + u32 seq, end_seq; + bool fragstolen; + +- tcp_ecn_check_ce(tp, skb); ++ tcp_ecn_check_ce(sk, skb); + + if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFODROP); +@@ -4734,7 +4738,7 @@ queue_and_out: + tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + + out_of_window: +- tcp_enter_quickack_mode(sk); ++ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); + inet_csk_schedule_ack(sk); + drop: + tcp_drop(sk, skb); +@@ -4745,8 +4749,6 @@ drop: + if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp))) + goto out_of_window; + +- tcp_enter_quickack_mode(sk); +- + if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { + /* Partial packet, seq < rcv_next < end_seq */ + SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n", +@@ -5830,7 +5832,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, + * to stand against the temptation 8) --ANK + */ + inet_csk_schedule_ack(sk); +- tcp_enter_quickack_mode(sk); ++ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, + TCP_DELACK_MAX, TCP_RTO_MAX); + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 15e6e7b9fd2b..8d0aafbdbbc3 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -62,6 +62,7 @@ + #include <asm/cacheflush.h> + #include <linux/hash.h> + #include <linux/genetlink.h> ++#include <linux/nospec.h> + + #include <net/net_namespace.h> + #include <net/sock.h> +@@ -654,6 +655,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, + + if (protocol < 0 || protocol >= MAX_LINKS) + return -EPROTONOSUPPORT; ++ protocol = array_index_nospec(protocol, MAX_LINKS); + + netlink_lock_table(); + #ifdef CONFIG_MODULES +diff --git a/net/socket.c b/net/socket.c +index bd3b33988ee0..35fa349ba274 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -89,6 +89,7 @@ + #include <linux/magic.h> + #include <linux/slab.h> + #include <linux/xattr.h> ++#include <linux/nospec.h> + + #include <asm/uaccess.h> + #include <asm/unistd.h> +@@ -2338,6 +2339,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) + + if (call < 1 || call > SYS_SENDMMSG) + return -EINVAL; ++ call = array_index_nospec(call, SYS_SENDMMSG + 1); + + len = nargs[call]; + if (len > sizeof(a))