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))

Reply via email to