commit:     b6aa0fa5f13c32b79a14188b9a278d59a1da37d1
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 15 22:57:04 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Jan 15 22:57:04 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b6aa0fa5

Linux patch 4.4.43

 0000_README             |   4 +
 1042_linux-4.4.43.patch | 698 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 702 insertions(+)

diff --git a/0000_README b/0000_README
index 335640e..9bc2193 100644
--- a/0000_README
+++ b/0000_README
@@ -211,6 +211,10 @@ Patch:  1041_linux-4.4.42.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.42
 
+Patch:  1042_linux-4.4.43.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.43
+
 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/1042_linux-4.4.43.patch b/1042_linux-4.4.43.patch
new file mode 100644
index 0000000..edc808d
--- /dev/null
+++ b/1042_linux-4.4.43.patch
@@ -0,0 +1,698 @@
+diff --git a/Makefile b/Makefile
+index b8a90f9a463d..04a2186a4276 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 42
++SUBLEVEL = 43
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c 
b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+index 65024af169d3..d3c14da7d216 100644
+--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
++++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+@@ -243,10 +243,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int 
power_state)
+               save_state = 1;
+               break;
+       case PWRDM_POWER_RET:
+-              if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
++              if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
+                       save_state = 0;
+-                      break;
+-              }
++              break;
+       default:
+               /*
+                * CPUx CSWR is invalid hardware state. Also CPUx OSWR
+diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
+index 6f39d03cc27e..0a43143e9ceb 100644
+--- a/arch/arm/mach-zynq/common.c
++++ b/arch/arm/mach-zynq/common.c
+@@ -59,7 +59,7 @@ void __iomem *zynq_scu_base;
+ static void __init zynq_memory_init(void)
+ {
+       if (!__pa(PAGE_OFFSET))
+-              memblock_reserve(__pa(PAGE_OFFSET), __pa(swapper_pg_dir));
++              memblock_reserve(__pa(PAGE_OFFSET), 0x80000);
+ }
+ 
+ static struct platform_device zynq_cpuidle_device = {
+diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
+index ed3ab509faca..df4efa304b2c 100644
+--- a/arch/powerpc/kernel/misc_32.S
++++ b/arch/powerpc/kernel/misc_32.S
+@@ -313,7 +313,7 @@ _GLOBAL(flush_instruction_cache)
+       lis     r3, KERNELBASE@h
+       iccci   0,r3
+ #endif
+-#elif CONFIG_FSL_BOOKE
++#elif defined(CONFIG_FSL_BOOKE)
+ BEGIN_FTR_SECTION
+       mfspr   r3,SPRN_L1CSR0
+       ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
+diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
+index 1b764d1745f3..1689568b597d 100644
+--- a/drivers/hid/hid-cypress.c
++++ b/drivers/hid/hid-cypress.c
+@@ -39,6 +39,9 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 
*rdesc,
+       if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
+               return rdesc;
+ 
++      if (*rsize < 4)
++              return rdesc;
++
+       for (i = 0; i < *rsize - 4; i++)
+               if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
+                       rdesc[i] = 0x19;
+diff --git a/drivers/isdn/gigaset/ser-gigaset.c 
b/drivers/isdn/gigaset/ser-gigaset.c
+index 2a506fe0c8a4..74bf1a17ae7c 100644
+--- a/drivers/isdn/gigaset/ser-gigaset.c
++++ b/drivers/isdn/gigaset/ser-gigaset.c
+@@ -762,8 +762,10 @@ static int __init ser_gigaset_init(void)
+       driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
+                                   GIGASET_MODULENAME, GIGASET_DEVNAME,
+                                   &ops, THIS_MODULE);
+-      if (!driver)
++      if (!driver) {
++              rc = -ENOMEM;
+               goto error;
++      }
+ 
+       rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
+       if (rc != 0) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c 
b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 6cf6d93d8831..ba115ec7aa92 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -432,6 +432,13 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
+       MLX5_SET(cmd_hca_cap, set_hca_cap, pkey_table_size,
+                to_fw_pkey_sz(128));
+ 
++      /* Check log_max_qp from HCA caps to set in current profile */
++      if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < profile[prof_sel].log_max_qp) {
++              mlx5_core_warn(dev, "log_max_qp value in current profile is %d, 
changing it to HCA capability limit (%d)\n",
++                             profile[prof_sel].log_max_qp,
++                             MLX5_CAP_GEN_MAX(dev, log_max_qp));
++              profile[prof_sel].log_max_qp = MLX5_CAP_GEN_MAX(dev, 
log_max_qp);
++      }
+       if (prof->mask & MLX5_PROF_MASK_QP_SIZE)
+               MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_qp,
+                        prof->log_max_qp);
+@@ -505,7 +512,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev 
*mdev, int i)
+       struct mlx5_priv *priv  = &mdev->priv;
+       struct msix_entry *msix = priv->msix_arr;
+       int irq                 = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
+-      int numa_node           = priv->numa_node;
+       int err;
+ 
+       if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
+@@ -513,7 +519,7 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev 
*mdev, int i)
+               return -ENOMEM;
+       }
+ 
+-      cpumask_set_cpu(cpumask_local_spread(i, numa_node),
++      cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
+                       priv->irq_info[i].mask);
+ 
+       err = irq_set_affinity_hint(irq, priv->irq_info[i].mask);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index a5b869eb4678..4b100ef4af9f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2939,12 +2939,6 @@ int stmmac_dvr_probe(struct device *device,
+       spin_lock_init(&priv->lock);
+       spin_lock_init(&priv->tx_lock);
+ 
+-      ret = register_netdev(ndev);
+-      if (ret) {
+-              pr_err("%s: ERROR %i registering the device\n", __func__, ret);
+-              goto error_netdev_register;
+-      }
+-
+       /* If a specific clk_csr value is passed from the platform
+        * this means that the CSR Clock Range selection cannot be
+        * changed at run-time and it is fixed. Viceversa the driver'll try to
+@@ -2969,11 +2963,21 @@ int stmmac_dvr_probe(struct device *device,
+               }
+       }
+ 
+-      return 0;
++      ret = register_netdev(ndev);
++      if (ret) {
++              netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
++                         __func__, ret);
++              goto error_netdev_register;
++      }
++
++      return ret;
+ 
+-error_mdio_register:
+-      unregister_netdev(ndev);
+ error_netdev_register:
++      if (priv->pcs != STMMAC_PCS_RGMII &&
++          priv->pcs != STMMAC_PCS_TBI &&
++          priv->pcs != STMMAC_PCS_RTBI)
++              stmmac_mdio_unregister(ndev);
++error_mdio_register:
+       netif_napi_del(&priv->napi);
+ error_hw_init:
+       clk_disable_unprepare(priv->pclk);
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 409b48e1e589..7a601d8c615e 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -40,6 +40,8 @@
+ 
+ #include "hyperv_net.h"
+ 
++/* Restrict GSO size to account for NVGRE */
++#define NETVSC_GSO_MAX_SIZE   62768
+ 
+ #define RING_SIZE_MIN 64
+ static int ring_size = 128;
+@@ -852,6 +854,7 @@ static int netvsc_set_channels(struct net_device *net,
+               }
+               goto recover;
+       }
++      netif_set_gso_max_size(net, NETVSC_GSO_MAX_SIZE);
+ 
+  out:
+       netvsc_open(net);
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 2fb637ad594a..32b7ec976dcc 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -3446,39 +3446,87 @@ static bool delay_autosuspend(struct r8152 *tp)
+               return false;
+ }
+ 
+-static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
++static int rtl8152_rumtime_suspend(struct r8152 *tp)
+ {
+-      struct r8152 *tp = usb_get_intfdata(intf);
+       struct net_device *netdev = tp->netdev;
+       int ret = 0;
+ 
+-      mutex_lock(&tp->control);
++      if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
++              u32 rcr = 0;
+ 
+-      if (PMSG_IS_AUTO(message)) {
+-              if (netif_running(netdev) && delay_autosuspend(tp)) {
++              if (delay_autosuspend(tp)) {
+                       ret = -EBUSY;
+                       goto out1;
+               }
+ 
+-              set_bit(SELECTIVE_SUSPEND, &tp->flags);
+-      } else {
+-              netif_device_detach(netdev);
++              if (netif_carrier_ok(netdev)) {
++                      u32 ocp_data;
++
++                      rcr = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
++                      ocp_data = rcr & ~RCR_ACPT_ALL;
++                      ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
++                      rxdy_gated_en(tp, true);
++                      ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA,
++                                               PLA_OOB_CTRL);
++                      if (!(ocp_data & RXFIFO_EMPTY)) {
++                              rxdy_gated_en(tp, false);
++                              ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
++                              ret = -EBUSY;
++                              goto out1;
++                      }
++              }
++
++              clear_bit(WORK_ENABLE, &tp->flags);
++              usb_kill_urb(tp->intr_urb);
++
++              rtl_runtime_suspend_enable(tp, true);
++
++              if (netif_carrier_ok(netdev)) {
++                      napi_disable(&tp->napi);
++                      rtl_stop_rx(tp);
++                      rxdy_gated_en(tp, false);
++                      ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
++                      napi_enable(&tp->napi);
++              }
+       }
+ 
++      set_bit(SELECTIVE_SUSPEND, &tp->flags);
++
++out1:
++      return ret;
++}
++
++static int rtl8152_system_suspend(struct r8152 *tp)
++{
++      struct net_device *netdev = tp->netdev;
++      int ret = 0;
++
++      netif_device_detach(netdev);
++
+       if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
+               clear_bit(WORK_ENABLE, &tp->flags);
+               usb_kill_urb(tp->intr_urb);
+               napi_disable(&tp->napi);
+-              if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+-                      rtl_stop_rx(tp);
+-                      rtl_runtime_suspend_enable(tp, true);
+-              } else {
+-                      cancel_delayed_work_sync(&tp->schedule);
+-                      tp->rtl_ops.down(tp);
+-              }
++              cancel_delayed_work_sync(&tp->schedule);
++              tp->rtl_ops.down(tp);
+               napi_enable(&tp->napi);
+       }
+-out1:
++
++      return ret;
++}
++
++static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
++{
++      struct r8152 *tp = usb_get_intfdata(intf);
++      int ret;
++
++      mutex_lock(&tp->control);
++
++      if (PMSG_IS_AUTO(message))
++              ret = rtl8152_rumtime_suspend(tp);
++      else
++              ret = rtl8152_system_suspend(tp);
++
+       mutex_unlock(&tp->control);
+ 
+       return ret;
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 903bda437839..d6b619667f1a 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -301,7 +301,9 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff 
*skb,
+               .flowi4_tos = RT_TOS(ip4h->tos),
+               .flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_L3MDEV_SRC |
+                               FLOWI_FLAG_SKIP_NH_OIF,
++              .flowi4_proto = ip4h->protocol,
+               .daddr = ip4h->daddr,
++              .saddr = ip4h->saddr,
+       };
+ 
+       if (vrf_send_v4_prep(skb, &fl4, vrf_dev))
+@@ -410,6 +412,8 @@ static int vrf_finish_output6(struct net *net, struct sock 
*sk,
+       struct in6_addr *nexthop;
+       int ret;
+ 
++      nf_reset(skb);
++
+       skb->protocol = htons(ETH_P_IPV6);
+       skb->dev = dev;
+ 
+@@ -521,6 +525,8 @@ static int vrf_finish_output(struct net *net, struct sock 
*sk, struct sk_buff *s
+       u32 nexthop;
+       int ret = -EINVAL;
+ 
++      nf_reset(skb);
++
+       /* Be paranoid, rather than too clever. */
+       if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
+               struct sk_buff *skb2;
+@@ -919,6 +925,8 @@ static int vrf_newlink(struct net *src_net, struct 
net_device *dev,
+               return -EINVAL;
+ 
+       vrf->tb_id = nla_get_u32(data[IFLA_VRF_TABLE]);
++      if (vrf->tb_id == RT_TABLE_UNSPEC)
++              return -EINVAL;
+ 
+       dev->priv_flags |= IFF_L3MDEV_MASTER;
+ 
+diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
+index a87cfd4ba17b..61a86d391599 100644
+--- a/drivers/spi/spi-orion.c
++++ b/drivers/spi/spi-orion.c
+@@ -127,37 +127,62 @@ static int orion_spi_baudrate_set(struct spi_device 
*spi, unsigned int speed)
+       tclk_hz = clk_get_rate(orion_spi->clk);
+ 
+       if (devdata->typ == ARMADA_SPI) {
+-              unsigned int clk, spr, sppr, sppr2, err;
+-              unsigned int best_spr, best_sppr, best_err;
+-
+-              best_err = speed;
+-              best_spr = 0;
+-              best_sppr = 0;
+-
+-              /* Iterate over the valid range looking for best fit */
+-              for (sppr = 0; sppr < 8; sppr++) {
+-                      sppr2 = 0x1 << sppr;
+-
+-                      spr = tclk_hz / sppr2;
+-                      spr = DIV_ROUND_UP(spr, speed);
+-                      if ((spr == 0) || (spr > 15))
+-                              continue;
+-
+-                      clk = tclk_hz / (spr * sppr2);
+-                      err = speed - clk;
+-
+-                      if (err < best_err) {
+-                              best_spr = spr;
+-                              best_sppr = sppr;
+-                              best_err = err;
+-                      }
+-              }
++              /*
++               * Given the core_clk (tclk_hz) and the target rate (speed) we
++               * determine the best values for SPR (in [0 .. 15]) and SPPR (in
++               * [0..7]) such that
++               *
++               *      core_clk / (SPR * 2 ** SPPR)
++               *
++               * is as big as possible but not bigger than speed.
++               */
+ 
+-              if ((best_sppr == 0) && (best_spr == 0))
+-                      return -EINVAL;
++              /* best integer divider: */
++              unsigned divider = DIV_ROUND_UP(tclk_hz, speed);
++              unsigned spr, sppr;
++
++              if (divider < 16) {
++                      /* This is the easy case, divider is less than 16 */
++                      spr = divider;
++                      sppr = 0;
++
++              } else {
++                      unsigned two_pow_sppr;
++                      /*
++                       * Find the highest bit set in divider. This and the
++                       * three next bits define SPR (apart from rounding).
++                       * SPPR is then the number of zero bits that must be
++                       * appended:
++                       */
++                      sppr = fls(divider) - 4;
++
++                      /*
++                       * As SPR only has 4 bits, we have to round divider up
++                       * to the next multiple of 2 ** sppr.
++                       */
++                      two_pow_sppr = 1 << sppr;
++                      divider = (divider + two_pow_sppr - 1) & -two_pow_sppr;
++
++                      /*
++                       * recalculate sppr as rounding up divider might have
++                       * increased it enough to change the position of the
++                       * highest set bit. In this case the bit that now
++                       * doesn't make it into SPR is 0, so there is no need to
++                       * round again.
++                       */
++                      sppr = fls(divider) - 4;
++                      spr = divider >> sppr;
++
++                      /*
++                       * Now do range checking. SPR is constructed to have a
++                       * width of 4 bits, so this is fine for sure. So we
++                       * still need to check for sppr to fit into 3 bits:
++                       */
++                      if (sppr > 7)
++                              return -EINVAL;
++              }
+ 
+-              prescale = ((best_sppr & 0x6) << 5) |
+-                      ((best_sppr & 0x1) << 4) | best_spr;
++              prescale = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr;
+       } else {
+               /*
+                * the supported rates are: 4,6,8...30
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 9d6025703f73..93a6a2c66d15 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2325,14 +2325,19 @@ static inline int skb_gro_header_hard(struct sk_buff 
*skb, unsigned int hlen)
+       return NAPI_GRO_CB(skb)->frag0_len < hlen;
+ }
+ 
++static inline void skb_gro_frag0_invalidate(struct sk_buff *skb)
++{
++      NAPI_GRO_CB(skb)->frag0 = NULL;
++      NAPI_GRO_CB(skb)->frag0_len = 0;
++}
++
+ static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int 
hlen,
+                                       unsigned int offset)
+ {
+       if (!pskb_may_pull(skb, hlen))
+               return NULL;
+ 
+-      NAPI_GRO_CB(skb)->frag0 = NULL;
+-      NAPI_GRO_CB(skb)->frag0_len = 0;
++      skb_gro_frag0_invalidate(skb);
+       return skb->data + offset;
+ }
+ 
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 2bcdfbf8c36d..6a117213feb8 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -5696,15 +5696,18 @@ void __init free_area_init_nodes(unsigned long 
*max_zone_pfn)
+                               sizeof(arch_zone_lowest_possible_pfn));
+       memset(arch_zone_highest_possible_pfn, 0,
+                               sizeof(arch_zone_highest_possible_pfn));
+-      arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions();
+-      arch_zone_highest_possible_pfn[0] = max_zone_pfn[0];
+-      for (i = 1; i < MAX_NR_ZONES; i++) {
++
++      start_pfn = find_min_pfn_with_active_regions();
++
++      for (i = 0; i < MAX_NR_ZONES; i++) {
+               if (i == ZONE_MOVABLE)
+                       continue;
+-              arch_zone_lowest_possible_pfn[i] =
+-                      arch_zone_highest_possible_pfn[i-1];
+-              arch_zone_highest_possible_pfn[i] =
+-                      max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
++
++              end_pfn = max(max_zone_pfn[i], start_pfn);
++              arch_zone_lowest_possible_pfn[i] = start_pfn;
++              arch_zone_highest_possible_pfn[i] = end_pfn;
++
++              start_pfn = end_pfn;
+       }
+       arch_zone_lowest_possible_pfn[ZONE_MOVABLE] = 0;
+       arch_zone_highest_possible_pfn[ZONE_MOVABLE] = 0;
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 9ca749c81b6c..6f203c7fb166 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4187,7 +4187,9 @@ static void skb_gro_reset_offset(struct sk_buff *skb)
+           pinfo->nr_frags &&
+           !PageHighMem(skb_frag_page(frag0))) {
+               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+-              NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
++              NAPI_GRO_CB(skb)->frag0_len = min_t(unsigned int,
++                                                  skb_frag_size(frag0),
++                                                  skb->end - skb->tail);
+       }
+ }
+ 
+diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
+index 252e155c837b..a2270188b864 100644
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -80,6 +80,7 @@ static struct sk_buff *reset_per_cpu_data(struct 
per_cpu_dm_data *data)
+       struct nlattr *nla;
+       struct sk_buff *skb;
+       unsigned long flags;
++      void *msg_header;
+ 
+       al = sizeof(struct net_dm_alert_msg);
+       al += dm_hit_limit * sizeof(struct net_dm_drop_point);
+@@ -87,21 +88,41 @@ static struct sk_buff *reset_per_cpu_data(struct 
per_cpu_dm_data *data)
+ 
+       skb = genlmsg_new(al, GFP_KERNEL);
+ 
+-      if (skb) {
+-              genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
+-                              0, NET_DM_CMD_ALERT);
+-              nla = nla_reserve(skb, NLA_UNSPEC,
+-                                sizeof(struct net_dm_alert_msg));
+-              msg = nla_data(nla);
+-              memset(msg, 0, al);
+-      } else {
+-              mod_timer(&data->send_timer, jiffies + HZ / 10);
++      if (!skb)
++              goto err;
++
++      msg_header = genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
++                               0, NET_DM_CMD_ALERT);
++      if (!msg_header) {
++              nlmsg_free(skb);
++              skb = NULL;
++              goto err;
++      }
++      nla = nla_reserve(skb, NLA_UNSPEC,
++                        sizeof(struct net_dm_alert_msg));
++      if (!nla) {
++              nlmsg_free(skb);
++              skb = NULL;
++              goto err;
+       }
++      msg = nla_data(nla);
++      memset(msg, 0, al);
++      goto out;
+ 
++err:
++      mod_timer(&data->send_timer, jiffies + HZ / 10);
++out:
+       spin_lock_irqsave(&data->lock, flags);
+       swap(data->skb, skb);
+       spin_unlock_irqrestore(&data->lock, flags);
+ 
++      if (skb) {
++              struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
++              struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlh);
++
++              genlmsg_end(skb, genlmsg_data(gnlh));
++      }
++
+       return skb;
+ }
+ 
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 63566ec54794..4e60dae86df5 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -85,7 +85,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
+       if (tb)
+               return tb;
+ 
+-      if (id == RT_TABLE_LOCAL)
++      if (id == RT_TABLE_LOCAL && !net->ipv4.fib_has_custom_rules)
+               alias = fib_new_table(net, RT_TABLE_MAIN);
+ 
+       tb = fib_trie_table(id, alias);
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index ffe95d954007..840b450aab46 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -1588,8 +1588,13 @@ void fib_select_multipath(struct fib_result *res, int 
hash)
+ void fib_select_path(struct net *net, struct fib_result *res,
+                    struct flowi4 *fl4, int mp_hash)
+ {
++      bool oif_check;
++
++      oif_check = (fl4->flowi4_oif == 0 ||
++                   fl4->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF);
++
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH
+-      if (res->fi->fib_nhs > 1 && fl4->flowi4_oif == 0) {
++      if (res->fi->fib_nhs > 1 && oif_check) {
+               if (mp_hash < 0)
+                       mp_hash = get_hash_from_flowi4(fl4) >> 1;
+ 
+@@ -1599,7 +1604,7 @@ void fib_select_path(struct net *net, struct fib_result 
*res,
+ #endif
+       if (!res->prefixlen &&
+           res->table->tb_num_default > 1 &&
+-          res->type == RTN_UNICAST && !fl4->flowi4_oif)
++          res->type == RTN_UNICAST && oif_check)
+               fib_select_default(fl4, res);
+ 
+       if (!fl4->saddr)
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index b3086cf27027..17adfdaf5795 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -225,9 +225,14 @@ static void igmp_start_timer(struct ip_mc_list *im, int 
max_delay)
+ static void igmp_gq_start_timer(struct in_device *in_dev)
+ {
+       int tv = prandom_u32() % in_dev->mr_maxdelay;
++      unsigned long exp = jiffies + tv + 2;
++
++      if (in_dev->mr_gq_running &&
++          time_after_eq(exp, (in_dev->mr_gq_timer).expires))
++              return;
+ 
+       in_dev->mr_gq_running = 1;
+-      if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
++      if (!mod_timer(&in_dev->mr_gq_timer, exp))
+               in_dev_hold(in_dev);
+ }
+ 
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
+index efe6268b8bc3..225f5f7f26ba 100644
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -196,6 +196,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff 
**head,
+       ops = rcu_dereference(inet6_offloads[proto]);
+       if (!ops || !ops->callbacks.gro_receive) {
+               __pskb_pull(skb, skb_gro_offset(skb));
++              skb_gro_frag0_invalidate(skb);
+               proto = ipv6_gso_pull_exthdrs(skb, proto);
+               skb_gro_pull(skb, -skb_transport_offset(skb));
+               skb_reset_transport_header(skb);
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 99140986e887..8bca90d6d915 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -589,7 +589,11 @@ static int rawv6_push_pending_frames(struct sock *sk, 
struct flowi6 *fl6,
+       }
+ 
+       offset += skb_transport_offset(skb);
+-      BUG_ON(skb_copy_bits(skb, offset, &csum, 2));
++      err = skb_copy_bits(skb, offset, &csum, 2);
++      if (err < 0) {
++              ip6_flush_pending_frames(sk);
++              goto out;
++      }
+ 
+       /* in case cksum was not initialized */
+       if (unlikely(csum))
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index ecc1904e454f..20b2f867c5a1 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -137,13 +137,15 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct 
nlmsghdr *n)
+       unsigned long cl;
+       unsigned long fh;
+       int err;
+-      int tp_created = 0;
++      int tp_created;
+ 
+       if ((n->nlmsg_type != RTM_GETTFILTER) &&
+           !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
+               return -EPERM;
+ 
+ replay:
++      tp_created = 0;
++
+       err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
+       if (err < 0)
+               return err;
+diff --git a/sound/firewire/tascam/tascam-stream.c 
b/sound/firewire/tascam/tascam-stream.c
+index 0e6dd5c61f53..e4c306398b35 100644
+--- a/sound/firewire/tascam/tascam-stream.c
++++ b/sound/firewire/tascam/tascam-stream.c
+@@ -343,7 +343,7 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
+       if (err < 0)
+               amdtp_stream_destroy(&tscm->rx_stream);
+ 
+-      return 0;
++      return err;
+ }
+ 
+ /* At bus reset, streaming is stopped and some registers are clear. */
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 3039e907f1f8..29f38e2b4ca9 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1136,6 +1136,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio 
*chip)
+       case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
+       case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
+       case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
++      case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */
+       case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
+       case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
+       case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */

Reply via email to