]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Jul 2017 16:52:20 +0000 (18:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Jul 2017 16:52:20 +0000 (18:52 +0200)
added patches:
brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch
cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch
geneve-fix-hlist-corruption.patch
ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
liquidio-fix-bug-in-soft-reset-failure-detection.patch
net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch
net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
net-mlx5-fix-driver-load-error-flow-when-firmware-is-stuck.patch
net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch
net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch
rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
sfc-don-t-read-beyond-unicast-address-list.patch
staging-android-uapi-drop-definitions-of-removed-ion_ioc_-free-share-ioctls.patch
tap-convert-a-mutex-to-a-spinlock.patch
virtio-net-fix-leaking-of-ctx-array.patch
vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
vxlan-fix-hlist-corruption.patch

19 files changed:
queue-4.12/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch [new file with mode: 0644]
queue-4.12/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch [new file with mode: 0644]
queue-4.12/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch [new file with mode: 0644]
queue-4.12/geneve-fix-hlist-corruption.patch [new file with mode: 0644]
queue-4.12/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch [new file with mode: 0644]
queue-4.12/liquidio-fix-bug-in-soft-reset-failure-detection.patch [new file with mode: 0644]
queue-4.12/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch [new file with mode: 0644]
queue-4.12/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch [new file with mode: 0644]
queue-4.12/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch [new file with mode: 0644]
queue-4.12/net-mlx5-fix-driver-load-error-flow-when-firmware-is-stuck.patch [new file with mode: 0644]
queue-4.12/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch [new file with mode: 0644]
queue-4.12/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch [new file with mode: 0644]
queue-4.12/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch [new file with mode: 0644]
queue-4.12/sfc-don-t-read-beyond-unicast-address-list.patch [new file with mode: 0644]
queue-4.12/staging-android-uapi-drop-definitions-of-removed-ion_ioc_-free-share-ioctls.patch [new file with mode: 0644]
queue-4.12/tap-convert-a-mutex-to-a-spinlock.patch [new file with mode: 0644]
queue-4.12/virtio-net-fix-leaking-of-ctx-array.patch [new file with mode: 0644]
queue-4.12/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch [new file with mode: 0644]
queue-4.12/vxlan-fix-hlist-corruption.patch [new file with mode: 0644]

diff --git a/queue-4.12/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch b/queue-4.12/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
new file mode 100644 (file)
index 0000000..701c2b9
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Fri, 7 Jul 2017 21:09:06 +0100
+Subject: brcmfmac: fix possible buffer overflow in brcmf_cfg80211_mgmt_tx()
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+
+[ Upstream commit 8f44c9a41386729fea410e688959ddaa9d51be7c ]
+
+The lower level nl80211 code in cfg80211 ensures that "len" is between
+25 and NL80211_ATTR_FRAME (2304).  We subtract DOT11_MGMT_HDR_LEN (24) from
+"len" so thats's max of 2280.  However, the action_frame->data[] buffer is
+only BRCMF_FIL_ACTION_FRAME_SIZE (1800) bytes long so this memcpy() can
+overflow.
+
+       memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
+              le16_to_cpu(action_frame->len));
+
+Cc: stable@vger.kernel.org # 3.9.x
+Fixes: 18e2f61db3b70 ("brcmfmac: P2P action frame tx.")
+Reported-by: "freenerguo(郭大兴)" <freenerguo@tencent.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -4851,6 +4851,11 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
+               cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
+                                       GFP_KERNEL);
+       } else if (ieee80211_is_action(mgmt->frame_control)) {
++              if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
++                      brcmf_err("invalid action frame length\n");
++                      err = -EINVAL;
++                      goto exit;
++              }
+               af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
+               if (af_params == NULL) {
+                       brcmf_err("unable to allocate frame\n");
diff --git a/queue-4.12/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch b/queue-4.12/bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch
new file mode 100644 (file)
index 0000000..c383fb5
--- /dev/null
@@ -0,0 +1,57 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Eduardo Valentin <eduval@amazon.com>
+Date: Tue, 11 Jul 2017 14:55:12 -0700
+Subject: bridge: mdb: fix leak on complete_info ptr on fail path
+
+From: Eduardo Valentin <eduval@amazon.com>
+
+
+[ Upstream commit 1bfb159673957644951ab0a8d2aec44b93ddb1ae ]
+
+We currently get the following kmemleak report:
+unreferenced object 0xffff8800039d9820 (size 32):
+  comm "softirq", pid 0, jiffies 4295212383 (age 792.416s)
+  hex dump (first 32 bytes):
+    00 0c e0 03 00 88 ff ff ff 02 00 00 00 00 00 00  ................
+    00 00 00 01 ff 11 00 02 86 dd 00 00 ff ff ff ff  ................
+  backtrace:
+    [<ffffffff8152b4aa>] kmemleak_alloc+0x4a/0xa0
+    [<ffffffff811d8ec8>] kmem_cache_alloc_trace+0xb8/0x1c0
+    [<ffffffffa0389683>] __br_mdb_notify+0x2a3/0x300 [bridge]
+    [<ffffffffa038a0ce>] br_mdb_notify+0x6e/0x70 [bridge]
+    [<ffffffffa0386479>] br_multicast_add_group+0x109/0x150 [bridge]
+    [<ffffffffa0386518>] br_ip6_multicast_add_group+0x58/0x60 [bridge]
+    [<ffffffffa0387fb5>] br_multicast_rcv+0x1d5/0xdb0 [bridge]
+    [<ffffffffa037d7cf>] br_handle_frame_finish+0xcf/0x510 [bridge]
+    [<ffffffffa03a236b>] br_nf_hook_thresh.part.27+0xb/0x10 [br_netfilter]
+    [<ffffffffa03a3738>] br_nf_hook_thresh+0x48/0xb0 [br_netfilter]
+    [<ffffffffa03a3fb9>] br_nf_pre_routing_finish_ipv6+0x109/0x1d0 [br_netfilter]
+    [<ffffffffa03a4400>] br_nf_pre_routing_ipv6+0xd0/0x14c [br_netfilter]
+    [<ffffffffa03a3c27>] br_nf_pre_routing+0x197/0x3d0 [br_netfilter]
+    [<ffffffff814a2952>] nf_iterate+0x52/0x60
+    [<ffffffff814a29bc>] nf_hook_slow+0x5c/0xb0
+    [<ffffffffa037ddf4>] br_handle_frame+0x1a4/0x2c0 [bridge]
+
+This happens when switchdev_port_obj_add() fails. This patch
+frees complete_info object in the fail path.
+
+Reviewed-by: Vallish Vaidyeshwara <vallish@amazon.com>
+Signed-off-by: Eduardo Valentin <eduval@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_mdb.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/bridge/br_mdb.c
++++ b/net/bridge/br_mdb.c
+@@ -323,7 +323,8 @@ static void __br_mdb_notify(struct net_d
+                       __mdb_entry_to_br_ip(entry, &complete_info->ip);
+                       mdb.obj.complete_priv = complete_info;
+                       mdb.obj.complete = br_mdb_complete;
+-                      switchdev_port_obj_add(port_dev, &mdb.obj);
++                      if (switchdev_port_obj_add(port_dev, &mdb.obj))
++                              kfree(complete_info);
+               }
+       } else if (port_dev && type == RTM_DELMDB) {
+               switchdev_port_obj_del(port_dev, &mdb.obj);
diff --git a/queue-4.12/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch b/queue-4.12/cxgb4-fix-bug-on-interrupt-deallocating-path-of-uld.patch
new file mode 100644 (file)
index 0000000..9bfad7c
--- /dev/null
@@ -0,0 +1,162 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
+Date: Mon, 10 Jul 2017 10:55:46 -0300
+Subject: cxgb4: fix BUG() on interrupt deallocating path of ULD
+
+From: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
+
+
+[ Upstream commit 6a146f3a5894b751cef16feb3d7903e45e3c445c ]
+
+Since the introduction of ULD (Upper-Layer Drivers), the MSI-X
+deallocating path changed in cxgb4: the driver frees the interrupts
+of ULD when unregistering it or on shutdown PCI handler.
+
+Problem is that if a MSI-X is not freed before deallocated in the PCI
+layer, it will trigger a BUG() due to still "alive" interrupt being
+tentatively quiesced.
+
+The below trace was observed when doing a simple unbind of Chelsio's
+adapter PCI function, like:
+  "echo 001e:80:00.4 > /sys/bus/pci/drivers/cxgb4/unbind"
+
+Trace:
+
+  kernel BUG at drivers/pci/msi.c:352!
+  Oops: Exception in kernel mode, sig: 5 [#1]
+  ...
+  NIP [c0000000005a5e60] free_msi_irqs+0xa0/0x250
+  LR [c0000000005a5e50] free_msi_irqs+0x90/0x250
+  Call Trace:
+  [c0000000005a5e50] free_msi_irqs+0x90/0x250 (unreliable)
+  [c0000000005a72c4] pci_disable_msix+0x124/0x180
+  [d000000011e06708] disable_msi+0x88/0xb0 [cxgb4]
+  [d000000011e06948] free_some_resources+0xa8/0x160 [cxgb4]
+  [d000000011e06d60] remove_one+0x170/0x3c0 [cxgb4]
+  [c00000000058a910] pci_device_remove+0x70/0x110
+  [c00000000064ef04] device_release_driver_internal+0x1f4/0x2c0
+  ...
+
+This patch fixes the issue by refactoring the shutdown path of ULD on
+cxgb4 driver, by properly freeing and disabling interrupts on PCI
+remove handler too.
+
+Fixes: 0fbc81b3ad51 ("Allocate resources dynamically for all cxgb4 ULD's")
+Reported-by: Harsha Thyagaraja <hathyaga@in.ibm.com>
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   16 ++++++---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c  |   42 ++++++++++++++----------
+ 2 files changed, 36 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -2055,12 +2055,12 @@ static void detach_ulds(struct adapter *
+       mutex_lock(&uld_mutex);
+       list_del(&adap->list_node);
++
+       for (i = 0; i < CXGB4_ULD_MAX; i++)
+-              if (adap->uld && adap->uld[i].handle) {
++              if (adap->uld && adap->uld[i].handle)
+                       adap->uld[i].state_change(adap->uld[i].handle,
+                                            CXGB4_STATE_DETACH);
+-                      adap->uld[i].handle = NULL;
+-              }
++
+       if (netevent_registered && list_empty(&adapter_list)) {
+               unregister_netevent_notifier(&cxgb4_netevent_nb);
+               netevent_registered = false;
+@@ -5086,8 +5086,10 @@ static void remove_one(struct pci_dev *p
+                */
+               destroy_workqueue(adapter->workq);
+-              if (is_uld(adapter))
++              if (is_uld(adapter)) {
+                       detach_ulds(adapter);
++                      t4_uld_clean_up(adapter);
++              }
+               disable_interrupts(adapter);
+@@ -5164,7 +5166,11 @@ static void shutdown_one(struct pci_dev
+                       if (adapter->port[i]->reg_state == NETREG_REGISTERED)
+                               cxgb_close(adapter->port[i]);
+-              t4_uld_clean_up(adapter);
++              if (is_uld(adapter)) {
++                      detach_ulds(adapter);
++                      t4_uld_clean_up(adapter);
++              }
++
+               disable_interrupts(adapter);
+               disable_msi(adapter);
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
+@@ -589,22 +589,37 @@ void t4_uld_mem_free(struct adapter *ada
+       kfree(adap->uld);
+ }
++/* This function should be called with uld_mutex taken. */
++static void cxgb4_shutdown_uld_adapter(struct adapter *adap, enum cxgb4_uld type)
++{
++      if (adap->uld[type].handle) {
++              adap->uld[type].handle = NULL;
++              adap->uld[type].add = NULL;
++              release_sge_txq_uld(adap, type);
++
++              if (adap->flags & FULL_INIT_DONE)
++                      quiesce_rx_uld(adap, type);
++
++              if (adap->flags & USING_MSIX)
++                      free_msix_queue_irqs_uld(adap, type);
++
++              free_sge_queues_uld(adap, type);
++              free_queues_uld(adap, type);
++      }
++}
++
+ void t4_uld_clean_up(struct adapter *adap)
+ {
+       unsigned int i;
+-      if (!adap->uld)
+-              return;
++      mutex_lock(&uld_mutex);
+       for (i = 0; i < CXGB4_ULD_MAX; i++) {
+               if (!adap->uld[i].handle)
+                       continue;
+-              if (adap->flags & FULL_INIT_DONE)
+-                      quiesce_rx_uld(adap, i);
+-              if (adap->flags & USING_MSIX)
+-                      free_msix_queue_irqs_uld(adap, i);
+-              free_sge_queues_uld(adap, i);
+-              free_queues_uld(adap, i);
++
++              cxgb4_shutdown_uld_adapter(adap, i);
+       }
++      mutex_unlock(&uld_mutex);
+ }
+ static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld)
+@@ -782,15 +797,8 @@ int cxgb4_unregister_uld(enum cxgb4_uld
+                       continue;
+               if (type == CXGB4_ULD_ISCSIT && is_t4(adap->params.chip))
+                       continue;
+-              adap->uld[type].handle = NULL;
+-              adap->uld[type].add = NULL;
+-              release_sge_txq_uld(adap, type);
+-              if (adap->flags & FULL_INIT_DONE)
+-                      quiesce_rx_uld(adap, type);
+-              if (adap->flags & USING_MSIX)
+-                      free_msix_queue_irqs_uld(adap, type);
+-              free_sge_queues_uld(adap, type);
+-              free_queues_uld(adap, type);
++
++              cxgb4_shutdown_uld_adapter(adap, type);
+       }
+       mutex_unlock(&uld_mutex);
diff --git a/queue-4.12/geneve-fix-hlist-corruption.patch b/queue-4.12/geneve-fix-hlist-corruption.patch
new file mode 100644 (file)
index 0000000..4f3f304
--- /dev/null
@@ -0,0 +1,132 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Jiri Benc <jbenc@redhat.com>
+Date: Sun, 2 Jul 2017 19:00:58 +0200
+Subject: geneve: fix hlist corruption
+
+From: Jiri Benc <jbenc@redhat.com>
+
+
+[ Upstream commit 4b4c21fad6ae6bd58ff1566f23b0f4f70fdc9a30 ]
+
+It's not a good idea to add the same hlist_node to two different hash lists.
+This leads to various hard to debug memory corruptions.
+
+Fixes: 8ed66f0e8235 ("geneve: implement support for IPv6-based tunnels")
+Cc: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Jiri Benc <jbenc@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/geneve.c |   48 ++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -45,9 +45,17 @@ struct geneve_net {
+ static unsigned int geneve_net_id;
++struct geneve_dev_node {
++      struct hlist_node hlist;
++      struct geneve_dev *geneve;
++};
++
+ /* Pseudo network device */
+ struct geneve_dev {
+-      struct hlist_node  hlist;       /* vni hash table */
++      struct geneve_dev_node hlist4;  /* vni hash table for IPv4 socket */
++#if IS_ENABLED(CONFIG_IPV6)
++      struct geneve_dev_node hlist6;  /* vni hash table for IPv6 socket */
++#endif
+       struct net         *net;        /* netns for packet i/o */
+       struct net_device  *dev;        /* netdev for geneve tunnel */
+       struct ip_tunnel_info info;
+@@ -123,16 +131,16 @@ static struct geneve_dev *geneve_lookup(
+                                       __be32 addr, u8 vni[])
+ {
+       struct hlist_head *vni_list_head;
+-      struct geneve_dev *geneve;
++      struct geneve_dev_node *node;
+       __u32 hash;
+       /* Find the device for this VNI */
+       hash = geneve_net_vni_hash(vni);
+       vni_list_head = &gs->vni_list[hash];
+-      hlist_for_each_entry_rcu(geneve, vni_list_head, hlist) {
+-              if (eq_tun_id_and_vni((u8 *)&geneve->info.key.tun_id, vni) &&
+-                  addr == geneve->info.key.u.ipv4.dst)
+-                      return geneve;
++      hlist_for_each_entry_rcu(node, vni_list_head, hlist) {
++              if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) &&
++                  addr == node->geneve->info.key.u.ipv4.dst)
++                      return node->geneve;
+       }
+       return NULL;
+ }
+@@ -142,16 +150,16 @@ static struct geneve_dev *geneve6_lookup
+                                        struct in6_addr addr6, u8 vni[])
+ {
+       struct hlist_head *vni_list_head;
+-      struct geneve_dev *geneve;
++      struct geneve_dev_node *node;
+       __u32 hash;
+       /* Find the device for this VNI */
+       hash = geneve_net_vni_hash(vni);
+       vni_list_head = &gs->vni_list[hash];
+-      hlist_for_each_entry_rcu(geneve, vni_list_head, hlist) {
+-              if (eq_tun_id_and_vni((u8 *)&geneve->info.key.tun_id, vni) &&
+-                  ipv6_addr_equal(&addr6, &geneve->info.key.u.ipv6.dst))
+-                      return geneve;
++      hlist_for_each_entry_rcu(node, vni_list_head, hlist) {
++              if (eq_tun_id_and_vni((u8 *)&node->geneve->info.key.tun_id, vni) &&
++                  ipv6_addr_equal(&addr6, &node->geneve->info.key.u.ipv6.dst))
++                      return node->geneve;
+       }
+       return NULL;
+ }
+@@ -579,6 +587,7 @@ static int geneve_sock_add(struct geneve
+ {
+       struct net *net = geneve->net;
+       struct geneve_net *gn = net_generic(net, geneve_net_id);
++      struct geneve_dev_node *node;
+       struct geneve_sock *gs;
+       __u8 vni[3];
+       __u32 hash;
+@@ -597,15 +606,20 @@ static int geneve_sock_add(struct geneve
+ out:
+       gs->collect_md = geneve->collect_md;
+ #if IS_ENABLED(CONFIG_IPV6)
+-      if (ipv6)
++      if (ipv6) {
+               rcu_assign_pointer(geneve->sock6, gs);
+-      else
++              node = &geneve->hlist6;
++      } else
+ #endif
++      {
+               rcu_assign_pointer(geneve->sock4, gs);
++              node = &geneve->hlist4;
++      }
++      node->geneve = geneve;
+       tunnel_id_to_vni(geneve->info.key.tun_id, vni);
+       hash = geneve_net_vni_hash(vni);
+-      hlist_add_head_rcu(&geneve->hlist, &gs->vni_list[hash]);
++      hlist_add_head_rcu(&node->hlist, &gs->vni_list[hash]);
+       return 0;
+ }
+@@ -632,8 +646,10 @@ static int geneve_stop(struct net_device
+ {
+       struct geneve_dev *geneve = netdev_priv(dev);
+-      if (!hlist_unhashed(&geneve->hlist))
+-              hlist_del_rcu(&geneve->hlist);
++      hlist_del_init_rcu(&geneve->hlist4.hlist);
++#if IS_ENABLED(CONFIG_IPV6)
++      hlist_del_init_rcu(&geneve->hlist6.hlist);
++#endif
+       geneve_sock_release(geneve);
+       return 0;
+ }
diff --git a/queue-4.12/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/queue-4.12/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
new file mode 100644 (file)
index 0000000..fc3a3d1
--- /dev/null
@@ -0,0 +1,76 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Thu, 29 Jun 2017 16:56:54 +0200
+Subject: ipv6: dad: don't remove dynamic addresses if link is down
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+
+[ Upstream commit ec8add2a4c9df723c94a863b8fcd6d93c472deed ]
+
+Currently, when the link for $DEV is down, this command succeeds but the
+address is removed immediately by DAD (1):
+
+    ip addr add 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+In the same situation, this will succeed and not remove the address (2):
+
+    ip addr add 1111::12/64 dev $DEV
+    ip addr change 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+The comment in addrconf_dad_begin() when !IF_READY makes it look like
+this is the intended behavior, but doesn't explain why:
+
+     * If the device is not ready:
+     * - keep it tentative if it is a permanent address.
+     * - otherwise, kill it.
+
+We clearly cannot prevent userspace from doing (2), but we can make (1)
+work consistently with (2).
+
+addrconf_dad_stop() is only called in two cases: if DAD failed, or to
+skip DAD when the link is down. In that second case, the fix is to avoid
+deleting the address, like we already do for permanent addresses.
+
+Fixes: 3c21edbd1137 ("[IPV6]: Defer IPv6 device initialization until the link becomes ready.")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/addrconf.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1912,15 +1912,7 @@ static void addrconf_dad_stop(struct ine
+       if (dad_failed)
+               ifp->flags |= IFA_F_DADFAILED;
+-      if (ifp->flags&IFA_F_PERMANENT) {
+-              spin_lock_bh(&ifp->lock);
+-              addrconf_del_dad_work(ifp);
+-              ifp->flags |= IFA_F_TENTATIVE;
+-              spin_unlock_bh(&ifp->lock);
+-              if (dad_failed)
+-                      ipv6_ifa_notify(0, ifp);
+-              in6_ifa_put(ifp);
+-      } else if (ifp->flags&IFA_F_TEMPORARY) {
++      if (ifp->flags&IFA_F_TEMPORARY) {
+               struct inet6_ifaddr *ifpub;
+               spin_lock_bh(&ifp->lock);
+               ifpub = ifp->ifpub;
+@@ -1933,6 +1925,14 @@ static void addrconf_dad_stop(struct ine
+                       spin_unlock_bh(&ifp->lock);
+               }
+               ipv6_del_addr(ifp);
++      } else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) {
++              spin_lock_bh(&ifp->lock);
++              addrconf_del_dad_work(ifp);
++              ifp->flags |= IFA_F_TENTATIVE;
++              spin_unlock_bh(&ifp->lock);
++              if (dad_failed)
++                      ipv6_ifa_notify(0, ifp);
++              in6_ifa_put(ifp);
+       } else {
+               ipv6_del_addr(ifp);
+       }
diff --git a/queue-4.12/liquidio-fix-bug-in-soft-reset-failure-detection.patch b/queue-4.12/liquidio-fix-bug-in-soft-reset-failure-detection.patch
new file mode 100644 (file)
index 0000000..10e4415
--- /dev/null
@@ -0,0 +1,51 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Derek Chickles <derek.chickles@cavium.com>
+Date: Wed, 5 Jul 2017 11:59:27 -0700
+Subject: liquidio: fix bug in soft reset failure detection
+
+From: Derek Chickles <derek.chickles@cavium.com>
+
+
+[ Upstream commit 05a6b4cae8c0cc1680c9dd33a97a49a13c0f01bc ]
+
+The code that detects a failed soft reset of Octeon is comparing the wrong
+value against the reset value of the Octeon SLI_SCRATCH_1 register,
+resulting in an inability to detect a soft reset failure.  Fix it by using
+the correct value in the comparison, which is any non-zero value.
+
+Fixes: f21fb3ed364b ("Add support of Cavium Liquidio ethernet adapters")
+Fixes: c0eab5b3580a ("liquidio: CN23XX firmware download")
+Signed-off-by: Derek Chickles <derek.chickles@cavium.com>
+Signed-off-by: Satanand Burla <satananda.burla@cavium.com>
+Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@cavium.com>
+Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
+Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c |    2 +-
+ drivers/net/ethernet/cavium/liquidio/cn66xx_device.c    |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
++++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+@@ -221,7 +221,7 @@ static int cn23xx_pf_soft_reset(struct o
+       /* Wait for 100ms as Octeon resets. */
+       mdelay(100);
+-      if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1) == 0x1234ULL) {
++      if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1)) {
+               dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Soft reset failed\n",
+                       oct->octeon_id);
+               return 1;
+--- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
++++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
+@@ -44,7 +44,7 @@ int lio_cn6xxx_soft_reset(struct octeon_
+       /* Wait for 10ms as Octeon resets. */
+       mdelay(100);
+-      if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1) == 0x1234ULL) {
++      if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1)) {
+               dev_err(&oct->pci_dev->dev, "Soft reset failed\n");
+               return 1;
+       }
diff --git a/queue-4.12/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch b/queue-4.12/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch
new file mode 100644 (file)
index 0000000..be79831
--- /dev/null
@@ -0,0 +1,174 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Alban Browaeys <alban.browaeys@gmail.com>
+Date: Mon, 3 Jul 2017 03:20:13 +0200
+Subject: net: core: Fix slab-out-of-bounds in netdev_stats_to_stats64
+
+From: Alban Browaeys <alban.browaeys@gmail.com>
+
+
+[ Upstream commit 9af9959e142c274f4a30fefb71d97d2b028b337f ]
+
+commit 9256645af098 ("net/core: relax BUILD_BUG_ON in
+netdev_stats_to_stats64") made an attempt to read beyond
+the size of the source a possibility.
+
+Fix to only copy src size to dest. As dest might be bigger than src.
+
+ ==================================================================
+ BUG: KASAN: slab-out-of-bounds in netdev_stats_to_stats64+0xe/0x30 at addr ffff8801be248b20
+ Read of size 192 by task VBoxNetAdpCtl/6734
+ CPU: 1 PID: 6734 Comm: VBoxNetAdpCtl Tainted: G           O    4.11.4prahal+intel+ #118
+ Hardware name: LENOVO 20CDCTO1WW/20CDCTO1WW, BIOS GQET52WW (1.32 ) 05/04/2017
+ Call Trace:
+  dump_stack+0x63/0x86
+  kasan_object_err+0x1c/0x70
+  kasan_report+0x270/0x520
+  ? netdev_stats_to_stats64+0xe/0x30
+  ? sched_clock_cpu+0x1b/0x190
+  ? __module_address+0x3e/0x3b0
+  ? unwind_next_frame+0x1ea/0xb00
+  check_memory_region+0x13c/0x1a0
+  memcpy+0x23/0x50
+  netdev_stats_to_stats64+0xe/0x30
+  dev_get_stats+0x1b9/0x230
+  rtnl_fill_stats+0x44/0xc00
+  ? nla_put+0xc6/0x130
+  rtnl_fill_ifinfo+0xe9e/0x3700
+  ? rtnl_fill_vfinfo+0xde0/0xde0
+  ? sched_clock+0x9/0x10
+  ? sched_clock+0x9/0x10
+  ? sched_clock_local+0x120/0x130
+  ? __module_address+0x3e/0x3b0
+  ? unwind_next_frame+0x1ea/0xb00
+  ? sched_clock+0x9/0x10
+  ? sched_clock+0x9/0x10
+  ? sched_clock_cpu+0x1b/0x190
+  ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? depot_save_stack+0x1d8/0x4a0
+  ? depot_save_stack+0x34f/0x4a0
+  ? depot_save_stack+0x34f/0x4a0
+  ? save_stack+0xb1/0xd0
+  ? save_stack_trace+0x16/0x20
+  ? save_stack+0x46/0xd0
+  ? kasan_slab_alloc+0x12/0x20
+  ? __kmalloc_node_track_caller+0x10d/0x350
+  ? __kmalloc_reserve.isra.36+0x2c/0xc0
+  ? __alloc_skb+0xd0/0x560
+  ? rtmsg_ifinfo_build_skb+0x61/0x120
+  ? rtmsg_ifinfo.part.25+0x16/0xb0
+  ? rtmsg_ifinfo+0x47/0x70
+  ? register_netdev+0x15/0x30
+  ? vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp]
+  ? vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? do_vfs_ioctl+0x17f/0xff0
+  ? SyS_ioctl+0x74/0x80
+  ? do_syscall_64+0x182/0x390
+  ? __alloc_skb+0xd0/0x560
+  ? __alloc_skb+0xd0/0x560
+  ? save_stack_trace+0x16/0x20
+  ? init_object+0x64/0xa0
+  ? ___slab_alloc+0x1ae/0x5c0
+  ? ___slab_alloc+0x1ae/0x5c0
+  ? __alloc_skb+0xd0/0x560
+  ? sched_clock+0x9/0x10
+  ? kasan_unpoison_shadow+0x35/0x50
+  ? kasan_kmalloc+0xad/0xe0
+  ? __kmalloc_node_track_caller+0x246/0x350
+  ? __alloc_skb+0xd0/0x560
+  ? kasan_unpoison_shadow+0x35/0x50
+  ? memset+0x31/0x40
+  ? __alloc_skb+0x31f/0x560
+  ? napi_consume_skb+0x320/0x320
+  ? br_get_link_af_size_filtered+0xb7/0x120 [bridge]
+  ? if_nlmsg_size+0x440/0x630
+  rtmsg_ifinfo_build_skb+0x83/0x120
+  rtmsg_ifinfo.part.25+0x16/0xb0
+  rtmsg_ifinfo+0x47/0x70
+  register_netdevice+0xa2b/0xe50
+  ? __kmalloc+0x171/0x2d0
+  ? netdev_change_features+0x80/0x80
+  register_netdev+0x15/0x30
+  vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp]
+  vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  ? vboxNetAdpComposeMACAddress+0x1d0/0x1d0 [vboxnetadp]
+  ? kasan_check_write+0x14/0x20
+  VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? VBoxNetAdpLinuxOpen+0x20/0x20 [vboxnetadp]
+  ? lock_acquire+0x11c/0x270
+  ? __audit_syscall_entry+0x2fb/0x660
+  do_vfs_ioctl+0x17f/0xff0
+  ? __audit_syscall_entry+0x2fb/0x660
+  ? ioctl_preallocate+0x1d0/0x1d0
+  ? __audit_syscall_entry+0x2fb/0x660
+  ? kmem_cache_free+0xb2/0x250
+  ? syscall_trace_enter+0x537/0xd00
+  ? exit_to_usermode_loop+0x100/0x100
+  SyS_ioctl+0x74/0x80
+  ? do_sys_open+0x350/0x350
+  ? do_vfs_ioctl+0xff0/0xff0
+  do_syscall_64+0x182/0x390
+  entry_SYSCALL64_slow_path+0x25/0x25
+ RIP: 0033:0x7f7e39a1ae07
+ RSP: 002b:00007ffc6f04c6d8 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
+ RAX: ffffffffffffffda RBX: 00007ffc6f04c730 RCX: 00007f7e39a1ae07
+ RDX: 00007ffc6f04c730 RSI: 00000000c0207601 RDI: 0000000000000007
+ RBP: 00007ffc6f04c700 R08: 00007ffc6f04c780 R09: 0000000000000008
+ R10: 0000000000000541 R11: 0000000000000206 R12: 0000000000000007
+ R13: 00000000c0207601 R14: 00007ffc6f04c730 R15: 0000000000000012
+ Object at ffff8801be248008, in cache kmalloc-4096 size: 4096
+ Allocated:
+ PID = 6734
+  save_stack_trace+0x16/0x20
+  save_stack+0x46/0xd0
+  kasan_kmalloc+0xad/0xe0
+  __kmalloc+0x171/0x2d0
+  alloc_netdev_mqs+0x8a7/0xbe0
+  vboxNetAdpOsCreate+0x65/0x1c0 [vboxnetadp]
+  vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  do_vfs_ioctl+0x17f/0xff0
+  SyS_ioctl+0x74/0x80
+  do_syscall_64+0x182/0x390
+  return_from_SYSCALL_64+0x0/0x6a
+ Freed:
+ PID = 5600
+  save_stack_trace+0x16/0x20
+  save_stack+0x46/0xd0
+  kasan_slab_free+0x73/0xc0
+  kfree+0xe4/0x220
+  kvfree+0x25/0x30
+  single_release+0x74/0xb0
+  __fput+0x265/0x6b0
+  ____fput+0x9/0x10
+  task_work_run+0xd5/0x150
+  exit_to_usermode_loop+0xe2/0x100
+  do_syscall_64+0x26c/0x390
+  return_from_SYSCALL_64+0x0/0x6a
+ Memory state around the buggy address:
+  ffff8801be248a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  ffff8801be248b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ >ffff8801be248b80: 00 00 00 00 00 00 00 00 00 00 00 07 fc fc fc fc
+                                                     ^
+  ffff8801be248c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+  ffff8801be248c80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ==================================================================
+
+Signed-off-by: Alban Browaeys <alban.browaeys@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -7751,7 +7751,7 @@ void netdev_stats_to_stats64(struct rtnl
+ {
+ #if BITS_PER_LONG == 64
+       BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
+-      memcpy(stats64, netdev_stats, sizeof(*stats64));
++      memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
+       /* zero out counters that only exist in rtnl_link_stats64 */
+       memset((char *)stats64 + sizeof(*netdev_stats), 0,
+              sizeof(*stats64) - sizeof(*netdev_stats));
diff --git a/queue-4.12/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch b/queue-4.12/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
new file mode 100644 (file)
index 0000000..8bf8348
--- /dev/null
@@ -0,0 +1,92 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: David Ahern <dsahern@gmail.com>
+Date: Wed, 5 Jul 2017 14:41:46 -0600
+Subject: net: ipv6: Compare lwstate in detecting duplicate nexthops
+
+From: David Ahern <dsahern@gmail.com>
+
+
+[ Upstream commit f06b7549b79e29a672336d4e134524373fb7a232 ]
+
+Lennert reported a failure to add different mpls encaps in a multipath
+route:
+
+  $ ip -6 route add 1234::/16 \
+        nexthop encap mpls 10 via fe80::1 dev ens3 \
+        nexthop encap mpls 20 via fe80::1 dev ens3
+  RTNETLINK answers: File exists
+
+The problem is that the duplicate nexthop detection does not compare
+lwtunnel configuration. Add it.
+
+Fixes: 19e42e451506 ("ipv6: support for fib route lwtunnel encap attributes")
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Reported-by: João Taveira Araújo <joao.taveira@gmail.com>
+Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Tested-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip6_route.h |    8 ++++++++
+ net/ipv6/ip6_fib.c      |    5 +----
+ net/ipv6/route.c        |    8 +-------
+ 3 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -22,6 +22,7 @@ struct route_info {
+ #include <net/flow.h>
+ #include <net/ip6_fib.h>
+ #include <net/sock.h>
++#include <net/lwtunnel.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
+ #include <linux/route.h>
+@@ -233,4 +234,11 @@ static inline struct in6_addr *rt6_nexth
+               return daddr;
+ }
++static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
++{
++      return a->dst.dev == b->dst.dev &&
++             a->rt6i_idev == b->rt6i_idev &&
++             ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
++             !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
++}
+ #endif
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -784,10 +784,7 @@ static int fib6_add_rt2node(struct fib6_
+                               goto next_iter;
+                       }
+-                      if (iter->dst.dev == rt->dst.dev &&
+-                          iter->rt6i_idev == rt->rt6i_idev &&
+-                          ipv6_addr_equal(&iter->rt6i_gateway,
+-                                          &rt->rt6i_gateway)) {
++                      if (rt6_duplicate_nexthop(iter, rt)) {
+                               if (rt->rt6i_nsiblings)
+                                       rt->rt6i_nsiblings = 0;
+                               if (!(iter->rt6i_flags & RTF_EXPIRES))
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -3048,17 +3048,11 @@ static int ip6_route_info_append(struct
+                                struct rt6_info *rt, struct fib6_config *r_cfg)
+ {
+       struct rt6_nh *nh;
+-      struct rt6_info *rtnh;
+       int err = -EEXIST;
+       list_for_each_entry(nh, rt6_nh_list, next) {
+               /* check if rt6_info already exists */
+-              rtnh = nh->rt6_info;
+-
+-              if (rtnh->dst.dev == rt->dst.dev &&
+-                  rtnh->rt6i_idev == rt->rt6i_idev &&
+-                  ipv6_addr_equal(&rtnh->rt6i_gateway,
+-                                  &rt->rt6i_gateway))
++              if (rt6_duplicate_nexthop(nh->rt6_info, rt))
+                       return err;
+       }
diff --git a/queue-4.12/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch b/queue-4.12/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
new file mode 100644 (file)
index 0000000..06fb21a
--- /dev/null
@@ -0,0 +1,97 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Mohamad Haj Yahia <mohamad@mellanox.com>
+Date: Thu, 30 Mar 2017 17:09:00 +0300
+Subject: net/mlx5: Cancel delayed recovery work when unloading the driver
+
+From: Mohamad Haj Yahia <mohamad@mellanox.com>
+
+
+[ Upstream commit 2a0165a034ac024b60cca49c61e46f4afa2e4d98 ]
+
+Draining the health workqueue will ignore future health works including
+the one that report hardware failure and thus we can't enter error state
+Instead cancel the recovery flow and make sure only recovery flow won't
+be scheduled.
+
+Fixes: 5e44fca50470 ('net/mlx5: Only cancel recovery work when cleaning up device')
+Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com>
+Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/health.c |   15 ++++++++++++++-
+ drivers/net/ethernet/mellanox/mlx5/core/main.c   |    2 +-
+ include/linux/mlx5/driver.h                      |    1 +
+ 3 files changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -67,6 +67,7 @@ enum {
+ enum {
+       MLX5_DROP_NEW_HEALTH_WORK,
++      MLX5_DROP_NEW_RECOVERY_WORK,
+ };
+ static u8 get_nic_state(struct mlx5_core_dev *dev)
+@@ -193,7 +194,7 @@ static void health_care(struct work_stru
+       mlx5_handle_bad_state(dev);
+       spin_lock(&health->wq_lock);
+-      if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags))
++      if (!test_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags))
+               schedule_delayed_work(&health->recover_work, recover_delay);
+       else
+               dev_err(&dev->pdev->dev,
+@@ -313,6 +314,7 @@ void mlx5_start_health_poll(struct mlx5_
+       init_timer(&health->timer);
+       health->sick = 0;
+       clear_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
++      clear_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+       health->health = &dev->iseg->health;
+       health->health_counter = &dev->iseg->health_counter;
+@@ -335,11 +337,22 @@ void mlx5_drain_health_wq(struct mlx5_co
+       spin_lock(&health->wq_lock);
+       set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
++      set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+       spin_unlock(&health->wq_lock);
+       cancel_delayed_work_sync(&health->recover_work);
+       cancel_work_sync(&health->work);
+ }
++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
++{
++      struct mlx5_core_health *health = &dev->priv.health;
++
++      spin_lock(&health->wq_lock);
++      set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
++      spin_unlock(&health->wq_lock);
++      cancel_delayed_work_sync(&dev->priv.health.recover_work);
++}
++
+ void mlx5_health_cleanup(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_core_health *health = &dev->priv.health;
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1228,7 +1228,7 @@ static int mlx5_unload_one(struct mlx5_c
+       int err = 0;
+       if (cleanup)
+-              mlx5_drain_health_wq(dev);
++              mlx5_drain_health_recovery(dev);
+       mutex_lock(&dev->intf_state_mutex);
+       if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -925,6 +925,7 @@ int mlx5_health_init(struct mlx5_core_de
+ void mlx5_start_health_poll(struct mlx5_core_dev *dev);
+ void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
+ void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
+ int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
+                       struct mlx5_buf *buf, int node);
+ int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf);
diff --git a/queue-4.12/net-mlx5-fix-driver-load-error-flow-when-firmware-is-stuck.patch b/queue-4.12/net-mlx5-fix-driver-load-error-flow-when-firmware-is-stuck.patch
new file mode 100644 (file)
index 0000000..41e5331
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Gal Pressman <galp@mellanox.com>
+Date: Mon, 19 Jun 2017 18:25:59 +0300
+Subject: net/mlx5: Fix driver load error flow when firmware is stuck
+
+From: Gal Pressman <galp@mellanox.com>
+
+
+[ Upstream commit 8ce59b16b4b6eacedaec1f7b652b4781cdbfe15f ]
+
+When wait for firmware init fails, previous code would mistakenly
+return success and cause inconsistency in the driver state.
+
+Fixes: 6c780a0267b8 ("net/mlx5: Wait for FW readiness before initializing command interface")
+Signed-off-by: Gal Pressman <galp@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1020,7 +1020,7 @@ static int mlx5_load_one(struct mlx5_cor
+       if (err) {
+               dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
+                       FW_PRE_INIT_TIMEOUT_MILI);
+-              goto out;
++              goto out_err;
+       }
+       err = mlx5_cmd_init(dev);
diff --git a/queue-4.12/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch b/queue-4.12/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch
new file mode 100644 (file)
index 0000000..81141ad
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Gal Pressman <galp@mellanox.com>
+Date: Sun, 25 Jun 2017 16:46:25 +0300
+Subject: net/mlx5e: Fix TX carrier errors report in get stats ndo
+
+From: Gal Pressman <galp@mellanox.com>
+
+
+[ Upstream commit 8ff93de7668bd81bc8efa819d1184ebd48fae72d ]
+
+Symbol error during carrier counter from PPCNT was mistakenly reported as
+TX carrier errors in get_stats ndo, although it's an RX counter.
+
+Fixes: 269e6b3af3bf ("net/mlx5e: Report additional error statistics in get stats ndo")
+Signed-off-by: Gal Pressman <galp@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -3053,8 +3053,6 @@ mlx5e_get_stats(struct net_device *dev,
+               PPORT_802_3_GET(pstats, a_frame_check_sequence_errors);
+       stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors);
+       stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards);
+-      stats->tx_carrier_errors =
+-              PPORT_802_3_GET(pstats, a_symbol_error_during_carrier);
+       stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
+                          stats->rx_frame_errors;
+       stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
diff --git a/queue-4.12/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch b/queue-4.12/net-mlx5e-initialize-cee-s-getpermhwaddr-address-buffer-to-0xff.patch
new file mode 100644 (file)
index 0000000..819d520
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Huy Nguyen <huyn@mellanox.com>
+Date: Thu, 29 Jun 2017 16:50:01 -0500
+Subject: net/mlx5e: Initialize CEE's getpermhwaddr address buffer to 0xff
+
+From: Huy Nguyen <huyn@mellanox.com>
+
+
+[ Upstream commit d968f0f2e4404152f37ed2384b4a2269dd2dae5a ]
+
+Latest change in open-lldp code uses bytes 6-11 of perm_addr buffer
+as the Ethernet source address for the host TLV packet.
+Since our driver does not fill these bytes, they stay at zero and
+the open-lldp code ends up sending the TLV packet with zero source
+address and the switch drops this packet.
+
+The fix is to initialize these bytes to 0xff. The open-lldp code
+considers 0xff:ff:ff:ff:ff:ff as the invalid address and falls back to
+use the host's mac address as the Ethernet source address.
+
+Fixes: 3a6a931dfb8e ("net/mlx5e: Support DCBX CEE API")
+Signed-off-by: Huy Nguyen <huyn@mellanox.com>
+Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+@@ -464,6 +464,8 @@ static void mlx5e_dcbnl_getpermhwaddr(st
+       if (!perm_addr)
+               return;
++      memset(perm_addr, 0xff, MAX_ADDR_LEN);
++
+       mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr);
+ }
diff --git a/queue-4.12/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch b/queue-4.12/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
new file mode 100644 (file)
index 0000000..aff7aa2
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Thu, 6 Jul 2017 08:15:06 -0700
+Subject: rds: tcp: use sock_create_lite() to create the accept socket
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+
+[ Upstream commit 0933a578cd55b02dc80f219dc8f2efb17ec61c9a ]
+
+There are two problems with calling sock_create_kern() from
+rds_tcp_accept_one()
+1. it sets up a new_sock->sk that is wasteful, because this ->sk
+   is going to get replaced by inet_accept() in the subsequent ->accept()
+2. The new_sock->sk is a leaked reference in sock_graft() which
+   expects to find a null parent->sk
+
+Avoid these problems by calling sock_create_lite().
+
+Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rds/tcp_listen.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rds/tcp_listen.c
++++ b/net/rds/tcp_listen.c
+@@ -125,7 +125,7 @@ int rds_tcp_accept_one(struct socket *so
+       if (!sock) /* module unload or netns delete in progress */
+               return -ENETUNREACH;
+-      ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family,
++      ret = sock_create_lite(sock->sk->sk_family,
+                              sock->sk->sk_type, sock->sk->sk_protocol,
+                              &new_sock);
+       if (ret)
diff --git a/queue-4.12/sfc-don-t-read-beyond-unicast-address-list.patch b/queue-4.12/sfc-don-t-read-beyond-unicast-address-list.patch
new file mode 100644 (file)
index 0000000..7e334a3
--- /dev/null
@@ -0,0 +1,63 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Bert Kenward <bkenward@solarflare.com>
+Date: Wed, 12 Jul 2017 17:19:41 +0100
+Subject: sfc: don't read beyond unicast address list
+
+From: Bert Kenward <bkenward@solarflare.com>
+
+
+[ Upstream commit c70d68150f71b84cea6997a53493e17bf18a54db ]
+
+If we have more than 32 unicast MAC addresses assigned to an interface
+we will read beyond the end of the address table in the driver when
+adding filters. The next 256 entries store multicast addresses, so we
+will end up attempting to insert duplicate filters, which is mostly
+harmless. If we add more than 288 unicast addresses we will then read
+past the multicast address table, which is likely to be more exciting.
+
+Fixes: 12fb0da45c9a ("sfc: clean fallbacks between promisc/normal in efx_ef10_filter_sync_rx_mode")
+Signed-off-by: Bert Kenward <bkenward@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/ef10.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -5034,12 +5034,9 @@ static void efx_ef10_filter_uc_addr_list
+       struct efx_ef10_filter_table *table = efx->filter_state;
+       struct net_device *net_dev = efx->net_dev;
+       struct netdev_hw_addr *uc;
+-      int addr_count;
+       unsigned int i;
+-      addr_count = netdev_uc_count(net_dev);
+       table->uc_promisc = !!(net_dev->flags & IFF_PROMISC);
+-      table->dev_uc_count = 1 + addr_count;
+       ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr);
+       i = 1;
+       netdev_for_each_uc_addr(uc, net_dev) {
+@@ -5050,6 +5047,8 @@ static void efx_ef10_filter_uc_addr_list
+               ether_addr_copy(table->dev_uc_list[i].addr, uc->addr);
+               i++;
+       }
++
++      table->dev_uc_count = i;
+ }
+ static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx)
+@@ -5057,12 +5056,11 @@ static void efx_ef10_filter_mc_addr_list
+       struct efx_ef10_filter_table *table = efx->filter_state;
+       struct net_device *net_dev = efx->net_dev;
+       struct netdev_hw_addr *mc;
+-      unsigned int i, addr_count;
++      unsigned int i;
+       table->mc_overflow = false;
+       table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI));
+-      addr_count = netdev_mc_count(net_dev);
+       i = 0;
+       netdev_for_each_mc_addr(mc, net_dev) {
+               if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {
diff --git a/queue-4.12/staging-android-uapi-drop-definitions-of-removed-ion_ioc_-free-share-ioctls.patch b/queue-4.12/staging-android-uapi-drop-definitions-of-removed-ion_ioc_-free-share-ioctls.patch
new file mode 100644 (file)
index 0000000..b3f960e
--- /dev/null
@@ -0,0 +1,48 @@
+From f7a320ffebe2bdce3a189ecb531a401c653f754f Mon Sep 17 00:00:00 2001
+From: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
+Date: Tue, 30 May 2017 17:11:35 +0300
+Subject: staging: android: uapi: drop definitions of removed ION_IOC_{FREE,SHARE} ioctls
+
+From: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
+
+commit f7a320ffebe2bdce3a189ecb531a401c653f754f upstream.
+
+This problem was found by strace ioctl list generator.
+
+Fixes: 15c6098cfec5 ("staging: android: ion: Remove ion_handle and ion_client")
+Signed-off-by: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
+Acked-by: Laura Abbott <labbott@redhat.com>
+Cc: "Dmitry V. Levin" <ldv@altlinux.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/android/uapi/ion.h |   18 ------------------
+ 1 file changed, 18 deletions(-)
+
+--- a/drivers/staging/android/uapi/ion.h
++++ b/drivers/staging/android/uapi/ion.h
+@@ -131,24 +131,6 @@ struct ion_heap_query {
+                                     struct ion_allocation_data)
+ /**
+- * DOC: ION_IOC_FREE - free memory
+- *
+- * Takes an ion_handle_data struct and frees the handle.
+- */
+-#define ION_IOC_FREE          _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
+-
+-/**
+- * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
+- *
+- * Takes an ion_fd_data struct with the handle field populated with a valid
+- * opaque handle.  Returns the struct with the fd field set to a file
+- * descriptor open in the current address space.  This file descriptor
+- * can then be passed to another process.  The corresponding opaque handle can
+- * be retrieved via ION_IOC_IMPORT.
+- */
+-#define ION_IOC_SHARE         _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
+-
+-/**
+  * DOC: ION_IOC_HEAP_QUERY - information about available heaps
+  *
+  * Takes an ion_heap_query structure and populates information about
diff --git a/queue-4.12/tap-convert-a-mutex-to-a-spinlock.patch b/queue-4.12/tap-convert-a-mutex-to-a-spinlock.patch
new file mode 100644 (file)
index 0000000..48c5b09
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: WANG Cong <xiyou.wangcong@gmail.com>
+Date: Mon, 10 Jul 2017 10:05:50 -0700
+Subject: tap: convert a mutex to a spinlock
+
+From: WANG Cong <xiyou.wangcong@gmail.com>
+
+
+[ Upstream commit ffa423fb3251f8737303ffc3b0659e86e501808e ]
+
+We are not allowed to block on the RCU reader side, so can't
+just hold the mutex as before. As a quick fix, convert it to
+a spinlock.
+
+Fixes: d9f1f61c0801 ("tap: Extending tap device create/destroy APIs")
+Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: Sainath Grandhi <sainath.grandhi@intel.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/tap.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -106,7 +106,7 @@ struct major_info {
+       struct rcu_head rcu;
+       dev_t major;
+       struct idr minor_idr;
+-      struct mutex minor_lock;
++      spinlock_t minor_lock;
+       const char *device_name;
+       struct list_head next;
+ };
+@@ -416,15 +416,15 @@ int tap_get_minor(dev_t major, struct ta
+               goto unlock;
+       }
+-      mutex_lock(&tap_major->minor_lock);
+-      retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL);
++      spin_lock(&tap_major->minor_lock);
++      retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_ATOMIC);
+       if (retval >= 0) {
+               tap->minor = retval;
+       } else if (retval == -ENOSPC) {
+               netdev_err(tap->dev, "Too many tap devices\n");
+               retval = -EINVAL;
+       }
+-      mutex_unlock(&tap_major->minor_lock);
++      spin_unlock(&tap_major->minor_lock);
+ unlock:
+       rcu_read_unlock();
+@@ -442,12 +442,12 @@ void tap_free_minor(dev_t major, struct
+               goto unlock;
+       }
+-      mutex_lock(&tap_major->minor_lock);
++      spin_lock(&tap_major->minor_lock);
+       if (tap->minor) {
+               idr_remove(&tap_major->minor_idr, tap->minor);
+               tap->minor = 0;
+       }
+-      mutex_unlock(&tap_major->minor_lock);
++      spin_unlock(&tap_major->minor_lock);
+ unlock:
+       rcu_read_unlock();
+@@ -467,13 +467,13 @@ static struct tap_dev *dev_get_by_tap_fi
+               goto unlock;
+       }
+-      mutex_lock(&tap_major->minor_lock);
++      spin_lock(&tap_major->minor_lock);
+       tap = idr_find(&tap_major->minor_idr, minor);
+       if (tap) {
+               dev = tap->dev;
+               dev_hold(dev);
+       }
+-      mutex_unlock(&tap_major->minor_lock);
++      spin_unlock(&tap_major->minor_lock);
+ unlock:
+       rcu_read_unlock();
+@@ -1227,7 +1227,7 @@ static int tap_list_add(dev_t major, con
+       tap_major->major = MAJOR(major);
+       idr_init(&tap_major->minor_idr);
+-      mutex_init(&tap_major->minor_lock);
++      spin_lock_init(&tap_major->minor_lock);
+       tap_major->device_name = device_name;
diff --git a/queue-4.12/virtio-net-fix-leaking-of-ctx-array.patch b/queue-4.12/virtio-net-fix-leaking-of-ctx-array.patch
new file mode 100644 (file)
index 0000000..622324f
--- /dev/null
@@ -0,0 +1,29 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 7 Jul 2017 19:56:09 +0800
+Subject: virtio-net: fix leaking of ctx array
+
+From: Jason Wang <jasowang@redhat.com>
+
+
+[ Upstream commit 55281621b6047d2ffb934a0b984ab0cdb1ad1d76 ]
+
+Fixes: commit d45b897b11ea ("virtio_net: allow specifying context for rx")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -2221,6 +2221,7 @@ static int virtnet_find_vqs(struct virtn
+       kfree(names);
+       kfree(callbacks);
+       kfree(vqs);
++      kfree(ctx);
+       return 0;
diff --git a/queue-4.12/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch b/queue-4.12/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
new file mode 100644 (file)
index 0000000..64b42f9
--- /dev/null
@@ -0,0 +1,117 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Thu, 6 Jul 2017 15:24:40 +0300
+Subject: vrf: fix bug_on triggered by rx when destroying a vrf
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+
+[ Upstream commit f630c38ef0d785101363a8992bbd4f302180f86f ]
+
+When destroying a VRF device we cleanup the slaves in its ndo_uninit()
+function, but that causes packets to be switched (skb->dev == vrf being
+destroyed) even though we're pass the point where the VRF should be
+receiving any packets while it is being dismantled. This causes a BUG_ON
+to trigger if we have raw sockets (trace below).
+The reason is that the inetdev of the VRF has been destroyed but we're
+still sending packets up the stack with it, so let's free the slaves in
+the dellink callback as David Ahern suggested.
+
+Note that this fix doesn't prevent packets from going up when the VRF
+device is admin down.
+
+[   35.631371] ------------[ cut here ]------------
+[   35.631603] kernel BUG at net/ipv4/fib_frontend.c:285!
+[   35.631854] invalid opcode: 0000 [#1] SMP
+[   35.631977] Modules linked in:
+[   35.632081] CPU: 2 PID: 22 Comm: ksoftirqd/2 Not tainted 4.12.0-rc7+ #45
+[   35.632247] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
+[   35.632477] task: ffff88005ad68000 task.stack: ffff88005ad64000
+[   35.632632] RIP: 0010:fib_compute_spec_dst+0xfc/0x1ee
+[   35.632769] RSP: 0018:ffff88005ad67978 EFLAGS: 00010202
+[   35.632910] RAX: 0000000000000001 RBX: ffff880059a7f200 RCX: 0000000000000000
+[   35.633084] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff82274af0
+[   35.633256] RBP: ffff88005ad679f8 R08: 000000000001ef70 R09: 0000000000000046
+[   35.633430] R10: ffff88005ad679f8 R11: ffff880037731cb0 R12: 0000000000000001
+[   35.633603] R13: ffff8800599e3000 R14: 0000000000000000 R15: ffff8800599cb852
+[   35.634114] FS:  0000000000000000(0000) GS:ffff88005d900000(0000) knlGS:0000000000000000
+[   35.634306] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   35.634456] CR2: 00007f3563227095 CR3: 000000000201d000 CR4: 00000000000406e0
+[   35.634632] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[   35.634865] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[   35.635055] Call Trace:
+[   35.635271]  ? __lock_acquire+0xf0d/0x1117
+[   35.635522]  ipv4_pktinfo_prepare+0x82/0x151
+[   35.635831]  raw_rcv_skb+0x17/0x3c
+[   35.636062]  raw_rcv+0xe5/0xf7
+[   35.636287]  raw_local_deliver+0x169/0x1d9
+[   35.636534]  ip_local_deliver_finish+0x87/0x1c4
+[   35.636820]  ip_local_deliver+0x63/0x7f
+[   35.637058]  ip_rcv_finish+0x340/0x3a1
+[   35.637295]  ip_rcv+0x314/0x34a
+[   35.637525]  __netif_receive_skb_core+0x49f/0x7c5
+[   35.637780]  ? lock_acquire+0x13f/0x1d7
+[   35.638018]  ? lock_acquire+0x15e/0x1d7
+[   35.638259]  __netif_receive_skb+0x1e/0x94
+[   35.638502]  ? __netif_receive_skb+0x1e/0x94
+[   35.638748]  netif_receive_skb_internal+0x74/0x300
+[   35.639002]  ? dev_gro_receive+0x2ed/0x411
+[   35.639246]  ? lock_is_held_type+0xc4/0xd2
+[   35.639491]  napi_gro_receive+0x105/0x1a0
+[   35.639736]  receive_buf+0xc32/0xc74
+[   35.639965]  ? detach_buf+0x67/0x153
+[   35.640201]  ? virtqueue_get_buf_ctx+0x120/0x176
+[   35.640453]  virtnet_poll+0x128/0x1c5
+[   35.640690]  net_rx_action+0x103/0x343
+[   35.640932]  __do_softirq+0x1c7/0x4b7
+[   35.641171]  run_ksoftirqd+0x23/0x5c
+[   35.641403]  smpboot_thread_fn+0x24f/0x26d
+[   35.641646]  ? sort_range+0x22/0x22
+[   35.641878]  kthread+0x129/0x131
+[   35.642104]  ? __list_add+0x31/0x31
+[   35.642335]  ? __list_add+0x31/0x31
+[   35.642568]  ret_from_fork+0x2a/0x40
+[   35.642804] Code: 05 bd 87 a3 00 01 e8 1f ef 98 ff 4d 85 f6 48 c7 c7 f0 4a 27 82 41 0f 94 c4 31 c9 31 d2 41 0f b6 f4 e8 04 71 a1 ff 45 84 e4 74 02 <0f> 0b 0f b7 93 c4 00 00 00 4d 8b a5 80 05 00 00 48 03 93 d0 00
+[   35.644342] RIP: fib_compute_spec_dst+0xfc/0x1ee RSP: ffff88005ad67978
+
+Fixes: 193125dbd8eb ("net: Introduce VRF device driver")
+Reported-by: Chris Cormier <chriscormier@cumulusnetworks.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Acked-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vrf.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -926,15 +926,10 @@ static int vrf_del_slave(struct net_devi
+ static void vrf_dev_uninit(struct net_device *dev)
+ {
+       struct net_vrf *vrf = netdev_priv(dev);
+-      struct net_device *port_dev;
+-      struct list_head *iter;
+       vrf_rtable_release(dev, vrf);
+       vrf_rt6_release(dev, vrf);
+-      netdev_for_each_lower_dev(dev, port_dev, iter)
+-              vrf_del_slave(dev, port_dev);
+-
+       free_percpu(dev->dstats);
+       dev->dstats = NULL;
+ }
+@@ -1389,6 +1384,12 @@ static int vrf_validate(struct nlattr *t
+ static void vrf_dellink(struct net_device *dev, struct list_head *head)
+ {
++      struct net_device *port_dev;
++      struct list_head *iter;
++
++      netdev_for_each_lower_dev(dev, port_dev, iter)
++              vrf_del_slave(dev, port_dev);
++
+       unregister_netdevice_queue(dev, head);
+ }
diff --git a/queue-4.12/vxlan-fix-hlist-corruption.patch b/queue-4.12/vxlan-fix-hlist-corruption.patch
new file mode 100644 (file)
index 0000000..10050de
--- /dev/null
@@ -0,0 +1,119 @@
+From foo@baz Mon Jul 17 18:46:41 CEST 2017
+From: Jiri Benc <jbenc@redhat.com>
+Date: Sun, 2 Jul 2017 19:00:57 +0200
+Subject: vxlan: fix hlist corruption
+
+From: Jiri Benc <jbenc@redhat.com>
+
+
+[ Upstream commit 69e766612c4bcb79e19cebed9eed61d4222c1d47 ]
+
+It's not a good idea to add the same hlist_node to two different hash lists.
+This leads to various hard to debug memory corruptions.
+
+Fixes: b1be00a6c39f ("vxlan: support both IPv4 and IPv6 sockets in a single vxlan device")
+Signed-off-by: Jiri Benc <jbenc@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c |   30 ++++++++++++++++++++----------
+ include/net/vxlan.h |   10 +++++++++-
+ 2 files changed, 29 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -228,15 +228,15 @@ static struct vxlan_sock *vxlan_find_soc
+ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
+ {
+-      struct vxlan_dev *vxlan;
++      struct vxlan_dev_node *node;
+       /* For flow based devices, map all packets to VNI 0 */
+       if (vs->flags & VXLAN_F_COLLECT_METADATA)
+               vni = 0;
+-      hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
+-              if (vxlan->default_dst.remote_vni == vni)
+-                      return vxlan;
++      hlist_for_each_entry_rcu(node, vni_head(vs, vni), hlist) {
++              if (node->vxlan->default_dst.remote_vni == vni)
++                      return node->vxlan;
+       }
+       return NULL;
+@@ -2365,17 +2365,22 @@ static void vxlan_vs_del_dev(struct vxla
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       spin_lock(&vn->sock_lock);
+-      hlist_del_init_rcu(&vxlan->hlist);
++      hlist_del_init_rcu(&vxlan->hlist4.hlist);
++#if IS_ENABLED(CONFIG_IPV6)
++      hlist_del_init_rcu(&vxlan->hlist6.hlist);
++#endif
+       spin_unlock(&vn->sock_lock);
+ }
+-static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
++static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan,
++                           struct vxlan_dev_node *node)
+ {
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       __be32 vni = vxlan->default_dst.remote_vni;
++      node->vxlan = vxlan;
+       spin_lock(&vn->sock_lock);
+-      hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni));
++      hlist_add_head_rcu(&node->hlist, vni_head(vs, vni));
+       spin_unlock(&vn->sock_lock);
+ }
+@@ -2819,6 +2824,7 @@ static int __vxlan_sock_add(struct vxlan
+ {
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       struct vxlan_sock *vs = NULL;
++      struct vxlan_dev_node *node;
+       if (!vxlan->cfg.no_share) {
+               spin_lock(&vn->sock_lock);
+@@ -2836,12 +2842,16 @@ static int __vxlan_sock_add(struct vxlan
+       if (IS_ERR(vs))
+               return PTR_ERR(vs);
+ #if IS_ENABLED(CONFIG_IPV6)
+-      if (ipv6)
++      if (ipv6) {
+               rcu_assign_pointer(vxlan->vn6_sock, vs);
+-      else
++              node = &vxlan->hlist6;
++      } else
+ #endif
++      {
+               rcu_assign_pointer(vxlan->vn4_sock, vs);
+-      vxlan_vs_add_dev(vs, vxlan);
++              node = &vxlan->hlist4;
++      }
++      vxlan_vs_add_dev(vs, vxlan, node);
+       return 0;
+ }
+--- a/include/net/vxlan.h
++++ b/include/net/vxlan.h
+@@ -221,9 +221,17 @@ struct vxlan_config {
+       bool                    no_share;
+ };
++struct vxlan_dev_node {
++      struct hlist_node hlist;
++      struct vxlan_dev *vxlan;
++};
++
+ /* Pseudo network device */
+ struct vxlan_dev {
+-      struct hlist_node hlist;        /* vni hash table */
++      struct vxlan_dev_node hlist4;   /* vni hash table for IPv4 socket */
++#if IS_ENABLED(CONFIG_IPV6)
++      struct vxlan_dev_node hlist6;   /* vni hash table for IPv6 socket */
++#endif
+       struct list_head  next;         /* vxlan's per namespace list */
+       struct vxlan_sock __rcu *vn4_sock;      /* listening socket for IPv4 */
+ #if IS_ENABLED(CONFIG_IPV6)