]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Mar 2013 21:16:22 +0000 (14:16 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Mar 2013 21:16:22 +0000 (14:16 -0700)
added patches:
batman-adv-verify-tt-len-does-not-exceed-packet-len.patch
bnx2x-add-missing-napi-deletion-in-error-path.patch
bnx2x-fix-occasional-statistics-off-by-4gb-error.patch
bonding-don-t-call-update_speed_duplex-under-spinlocks.patch
bridge-reserve-space-for-ifla_brport_fast_leave.patch
drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch
inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch
ipv4-fix-definition-of-fib_table_hashsz.patch
net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch
netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch
net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch
net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch
revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch
rtnetlink-mask-the-rta_type-when-range-checking.patch
sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch
sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch
sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch
sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch
sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch
sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch
sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch
skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch
tcp-dont-handle-mtu-reduction-on-listen-socket.patch
tcp-fix-skb_availroom.patch
tg3-5715-does-not-link-up-when-autoneg-off.patch
vhost-net-fix-heads-usage-of-ubuf_info.patch

27 files changed:
queue-3.8/batman-adv-verify-tt-len-does-not-exceed-packet-len.patch [new file with mode: 0644]
queue-3.8/bnx2x-add-missing-napi-deletion-in-error-path.patch [new file with mode: 0644]
queue-3.8/bnx2x-fix-occasional-statistics-off-by-4gb-error.patch [new file with mode: 0644]
queue-3.8/bonding-don-t-call-update_speed_duplex-under-spinlocks.patch [new file with mode: 0644]
queue-3.8/bridge-reserve-space-for-ifla_brport_fast_leave.patch [new file with mode: 0644]
queue-3.8/drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch [new file with mode: 0644]
queue-3.8/inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch [new file with mode: 0644]
queue-3.8/ipv4-fix-definition-of-fib_table_hashsz.patch [new file with mode: 0644]
queue-3.8/net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch [new file with mode: 0644]
queue-3.8/net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch [new file with mode: 0644]
queue-3.8/net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch [new file with mode: 0644]
queue-3.8/netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch [new file with mode: 0644]
queue-3.8/revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch [new file with mode: 0644]
queue-3.8/rtnetlink-mask-the-rta_type-when-range-checking.patch [new file with mode: 0644]
queue-3.8/sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch [new file with mode: 0644]
queue-3.8/sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch [new file with mode: 0644]
queue-3.8/series
queue-3.8/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch [new file with mode: 0644]
queue-3.8/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch [new file with mode: 0644]
queue-3.8/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch [new file with mode: 0644]
queue-3.8/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch [new file with mode: 0644]
queue-3.8/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch [new file with mode: 0644]
queue-3.8/skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch [new file with mode: 0644]
queue-3.8/tcp-dont-handle-mtu-reduction-on-listen-socket.patch [new file with mode: 0644]
queue-3.8/tcp-fix-skb_availroom.patch [new file with mode: 0644]
queue-3.8/tg3-5715-does-not-link-up-when-autoneg-off.patch [new file with mode: 0644]
queue-3.8/vhost-net-fix-heads-usage-of-ubuf_info.patch [new file with mode: 0644]

diff --git a/queue-3.8/batman-adv-verify-tt-len-does-not-exceed-packet-len.patch b/queue-3.8/batman-adv-verify-tt-len-does-not-exceed-packet-len.patch
new file mode 100644 (file)
index 0000000..64dd11d
--- /dev/null
@@ -0,0 +1,44 @@
+From dfc8b938216b524800a183791072032a0390c2d1 Mon Sep 17 00:00:00 2001
+From: Marek Lindner <lindner_marek@yahoo.de>
+Date: Mon, 4 Mar 2013 10:39:49 +0800
+Subject: batman-adv: verify tt len does not exceed packet len
+
+
+From: Marek Lindner <lindner_marek@yahoo.de>
+
+[ Upstream commit b47506d91259c29b9c75c404737eb6525556f9b4 ]
+
+batadv_iv_ogm_process() accesses the packet using the tt_num_changes
+attribute regardless of the real packet len (assuming the length check
+was done before). Therefore a length check is needed to avoid reading
+random memory.
+
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_iv_ogm.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -1298,7 +1298,8 @@ static int batadv_iv_ogm_receive(struct
+       batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
+       /* unpack the aggregated packets and process them one by one */
+-      do {
++      while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
++                                       batadv_ogm_packet->tt_num_changes)) {
+               tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
+               batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
+@@ -1309,8 +1310,7 @@ static int batadv_iv_ogm_receive(struct
+               packet_pos = packet_buff + buff_pos;
+               batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
+-      } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
+-                                         batadv_ogm_packet->tt_num_changes));
++      }
+       kfree_skb(skb);
+       return NET_RX_SUCCESS;
diff --git a/queue-3.8/bnx2x-add-missing-napi-deletion-in-error-path.patch b/queue-3.8/bnx2x-add-missing-napi-deletion-in-error-path.patch
new file mode 100644 (file)
index 0000000..bde2bc2
--- /dev/null
@@ -0,0 +1,34 @@
+From 294dbeb4c43c2efcf7ebc70b2fdaa6069460b58b Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Fri, 15 Mar 2013 05:27:54 +0000
+Subject: bnx2x: add missing napi deletion in error path
+
+
+From: Michal Schmidt <mschmidt@redhat.com>
+
+[ Upstream commit 722c6f585088a2c392b4c5d01b87a584bb8fb73f ]
+
+If the hardware initialization fails in bnx2x_nic_load() after adding
+napi objects, they would not be deleted. A subsequent attempt to unload
+the bnx2x module detects a corruption in the napi list.
+
+Add the missing napi deletion to the error path.
+
+Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
+Acked-by: Dmitry Kravkov <dmitry@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -2523,6 +2523,7 @@ load_error2:
+       bp->port.pmf = 0;
+ load_error1:
+       bnx2x_napi_disable(bp);
++      bnx2x_del_all_napi(bp);
+       /* clear pf_load status, as it was already set */
+       bnx2x_clear_pf_load(bp);
+ load_error0:
diff --git a/queue-3.8/bnx2x-fix-occasional-statistics-off-by-4gb-error.patch b/queue-3.8/bnx2x-fix-occasional-statistics-off-by-4gb-error.patch
new file mode 100644 (file)
index 0000000..52e0724
--- /dev/null
@@ -0,0 +1,41 @@
+From 7b910fac0e53f21942f700796a655418408987ef Mon Sep 17 00:00:00 2001
+From: Maciej Żenczykowski <maze@google.com>
+Date: Fri, 15 Mar 2013 11:56:17 +0000
+Subject: bnx2x: fix occasional statistics off-by-4GB error
+
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit b009aac12cd0fe34293c68af8ac48b85be3bd858 ]
+
+The UPDATE_QSTAT function introduced on February 15, 2012
+in commit 1355b704b9ba "bnx2x: consistent statistics after
+internal driver reload" incorrectly fails to handle overflow
+during addition of the lower 32-bit field of a stat.
+
+This bug is present since 3.4-rc1 and should thus be considered
+a candidate for stable 3.4+ releases.
+
+Google-Bug-Id: 8374428
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Cc: Mintz Yuval <yuvalmin@broadcom.com>
+Acked-by: Eilon Greenstein <eilong@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
+@@ -456,8 +456,9 @@ struct bnx2x_fw_port_stats_old {
+ #define UPDATE_QSTAT(s, t) \
+       do { \
+-              qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \
+               qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
++              qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \
++                      + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \
+       } while (0)
+ #define UPDATE_QSTAT_OLD(f) \
diff --git a/queue-3.8/bonding-don-t-call-update_speed_duplex-under-spinlocks.patch b/queue-3.8/bonding-don-t-call-update_speed_duplex-under-spinlocks.patch
new file mode 100644 (file)
index 0000000..4502e9a
--- /dev/null
@@ -0,0 +1,57 @@
+From 47c5adc4e53aefc315c53fc7fbeb31443fc53ccf Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Tue, 12 Mar 2013 06:31:32 +0000
+Subject: bonding: don't call update_speed_duplex() under spinlocks
+
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit 876254ae2758d50dcb08c7bd00caf6a806571178 ]
+
+bond_update_speed_duplex() might sleep while calling underlying slave's
+routines. Move it out of atomic context in bond_enslave() and remove it
+from bond_miimon_commit() - it was introduced by commit 546add79, however
+when the slave interfaces go up/change state it's their responsibility to
+fire NETDEV_UP/NETDEV_CHANGE events so that bonding can properly update
+their speed.
+
+I've tested it on all combinations of ifup/ifdown, autoneg/speed/duplex
+changes, remote-controlled and local, on (not) MII-based cards. All changes
+are visible.
+
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1728,6 +1728,8 @@ int bond_enslave(struct net_device *bond
+       bond_compute_features(bond);
++      bond_update_speed_duplex(new_slave);
++
+       read_lock(&bond->lock);
+       new_slave->last_arp_rx = jiffies -
+@@ -1780,8 +1782,6 @@ int bond_enslave(struct net_device *bond
+               new_slave->link == BOND_LINK_DOWN ? "DOWN" :
+                       (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
+-      bond_update_speed_duplex(new_slave);
+-
+       if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
+               /* if there is a primary slave, remember it */
+               if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
+@@ -2463,8 +2463,6 @@ static void bond_miimon_commit(struct bo
+                               bond_set_backup_slave(slave);
+                       }
+-                      bond_update_speed_duplex(slave);
+-
+                       pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
+                               bond->dev->name, slave->dev->name,
+                               slave->speed, slave->duplex ? "full" : "half");
diff --git a/queue-3.8/bridge-reserve-space-for-ifla_brport_fast_leave.patch b/queue-3.8/bridge-reserve-space-for-ifla_brport_fast_leave.patch
new file mode 100644 (file)
index 0000000..e4149f9
--- /dev/null
@@ -0,0 +1,38 @@
+From dd483fea98c665ceda802000ec080df9ddc7a3e0 Mon Sep 17 00:00:00 2001
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Mon, 11 Mar 2013 13:52:17 +0000
+Subject: bridge: reserve space for IFLA_BRPORT_FAST_LEAVE
+
+
+From: stephen hemminger <stephen@networkplumber.org>
+
+[ Upstream commit 3da889b616164bde76a37350cf28e0d17a94e979 ]
+
+The bridge multicast fast leave feature was added sufficient space
+was not reserved in the netlink message. This means the flag may be
+lost in netlink events and results of queries.
+
+Found by observation while looking up some netlink stuff for discussion with Vlad.
+Problem introduced by commit c2d3babfafbb9f6629cfb47139758e59a5eb0d80
+Author: David S. Miller <davem@davemloft.net>
+Date:   Wed Dec 5 16:24:45 2012 -0500
+
+    bridge: implement multicast fast leave
+
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_netlink.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -28,6 +28,7 @@ static inline size_t br_port_info_size(v
+               + nla_total_size(1)     /* IFLA_BRPORT_MODE */
+               + nla_total_size(1)     /* IFLA_BRPORT_GUARD */
+               + nla_total_size(1)     /* IFLA_BRPORT_PROTECT */
++              + nla_total_size(1)     /* IFLA_BRPORT_FAST_LEAVE */
+               + 0;
+ }
diff --git a/queue-3.8/drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch b/queue-3.8/drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch
new file mode 100644 (file)
index 0000000..1fe48a1
--- /dev/null
@@ -0,0 +1,52 @@
+From 1341f0cf6c27b37c1d67a1a4990883760667efbe Mon Sep 17 00:00:00 2001
+From: Julia Lawall <Julia.Lawall@lip6.fr>
+Date: Mon, 21 Jan 2013 03:02:48 +0000
+Subject: drivers/net/ethernet/sfc/ptp.c: adjust duplicate test
+
+
+From: Julia Lawall <Julia.Lawall@lip6.fr>
+
+[ Upstream commit 56567c6f8751c633581ca7c8e1cf08eed503f5ea ]
+
+Delete successive tests to the same location.  rc was previously tested and
+not subsequently updated.  efx_phc_adjtime can return an error code, so the
+call is updated so that is tested instead.
+
+A simplified version of the semantic match that finds this problem is as
+follows: (http://coccinelle.lip6.fr/)
+
+// <smpl>
+@s exists@
+local idexpression y;
+expression x,e;
+@@
+
+*if ( \(x == NULL\|IS_ERR(x)\|y != 0\) )
+ { ... when forall
+   return ...; }
+... when != \(y = e\|y += e\|y -= e\|y |= e\|y &= e\|y++\|y--\|&y\)
+    when != \(XT_GETPAGE(...,y)\|WMI_CMD_BUF(...)\)
+*if ( \(x == NULL\|IS_ERR(x)\|y != 0\) )
+ { ... when forall
+   return ...; }
+// </smpl>
+
+Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
+Acked-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/ptp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -1439,7 +1439,7 @@ static int efx_phc_settime(struct ptp_cl
+       delta = timespec_sub(*e_ts, time_now);
+-      efx_phc_adjtime(ptp, timespec_to_ns(&delta));
++      rc = efx_phc_adjtime(ptp, timespec_to_ns(&delta));
+       if (rc != 0)
+               return rc;
diff --git a/queue-3.8/inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch b/queue-3.8/inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch
new file mode 100644 (file)
index 0000000..a81ac92
--- /dev/null
@@ -0,0 +1,182 @@
+From d4d3c7d9249ba373627a09c4e9469cfe46c343a6 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Fri, 15 Mar 2013 11:32:30 +0000
+Subject: inet: limit length of fragment queue hash table bucket lists
+
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 5a3da1fe9561828d0ca7eca664b16ec2b9bf0055 ]
+
+This patch introduces a constant limit of the fragment queue hash
+table bucket list lengths. Currently the limit 128 is choosen somewhat
+arbitrary and just ensures that we can fill up the fragment cache with
+empty packets up to the default ip_frag_high_thresh limits. It should
+just protect from list iteration eating considerable amounts of cpu.
+
+If we reach the maximum length in one hash bucket a warning is printed.
+This is implemented on the caller side of inet_frag_find to distinguish
+between the different users of inet_fragment.c.
+
+I dropped the out of memory warning in the ipv4 fragment lookup path,
+because we already get a warning by the slab allocator.
+
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: Jesper Dangaard Brouer <jbrouer@redhat.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/inet_frag.h                 |    9 +++++++++
+ net/ipv4/inet_fragment.c                |   20 +++++++++++++++++++-
+ net/ipv4/ip_fragment.c                  |   11 ++++-------
+ net/ipv6/netfilter/nf_conntrack_reasm.c |   12 ++++++------
+ net/ipv6/reassembly.c                   |    8 ++++++--
+ 5 files changed, 44 insertions(+), 16 deletions(-)
+
+--- a/include/net/inet_frag.h
++++ b/include/net/inet_frag.h
+@@ -35,6 +35,13 @@ struct inet_frag_queue {
+ #define INETFRAGS_HASHSZ              64
++/* averaged:
++ * max_depth = default ipfrag_high_thresh / INETFRAGS_HASHSZ /
++ *           rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or
++ *           struct frag_queue))
++ */
++#define INETFRAGS_MAXDEPTH            128
++
+ struct inet_frags {
+       struct hlist_head       hash[INETFRAGS_HASHSZ];
+       rwlock_t                lock;
+@@ -65,6 +72,8 @@ int inet_frag_evictor(struct netns_frags
+ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
+               struct inet_frags *f, void *key, unsigned int hash)
+       __releases(&f->lock);
++void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
++                                 const char *prefix);
+ static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
+ {
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -21,6 +21,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/slab.h>
++#include <net/sock.h>
+ #include <net/inet_frag.h>
+ static void inet_frag_secret_rebuild(unsigned long dummy)
+@@ -276,6 +277,7 @@ struct inet_frag_queue *inet_frag_find(s
+ {
+       struct inet_frag_queue *q;
+       struct hlist_node *n;
++      int depth = 0;
+       hlist_for_each_entry(q, n, &f->hash[hash], list) {
+               if (q->net == nf && f->match(q, key)) {
+@@ -283,9 +285,25 @@ struct inet_frag_queue *inet_frag_find(s
+                       read_unlock(&f->lock);
+                       return q;
+               }
++              depth++;
+       }
+       read_unlock(&f->lock);
+-      return inet_frag_create(nf, f, key);
++      if (depth <= INETFRAGS_MAXDEPTH)
++              return inet_frag_create(nf, f, key);
++      else
++              return ERR_PTR(-ENOBUFS);
+ }
+ EXPORT_SYMBOL(inet_frag_find);
++
++void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
++                                 const char *prefix)
++{
++      static const char msg[] = "inet_frag_find: Fragment hash bucket"
++              " list length grew over limit " __stringify(INETFRAGS_MAXDEPTH)
++              ". Dropping fragment.\n";
++
++      if (PTR_ERR(q) == -ENOBUFS)
++              LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg);
++}
++EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -299,14 +299,11 @@ static inline struct ipq *ip_find(struct
+       hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
+       q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
+-      if (q == NULL)
+-              goto out_nomem;
+-
++      if (IS_ERR_OR_NULL(q)) {
++              inet_frag_maybe_warn_overflow(q, pr_fmt());
++              return NULL;
++      }
+       return container_of(q, struct ipq, q);
+-
+-out_nomem:
+-      LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
+-      return NULL;
+ }
+ /* Is the fragment too far ahead to be part of ipq? */
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -14,6 +14,8 @@
+  * 2 of the License, or (at your option) any later version.
+  */
++#define pr_fmt(fmt) "IPv6-nf: " fmt
++
+ #include <linux/errno.h>
+ #include <linux/types.h>
+ #include <linux/string.h>
+@@ -180,13 +182,11 @@ static inline struct frag_queue *fq_find
+       q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
+       local_bh_enable();
+-      if (q == NULL)
+-              goto oom;
+-
++      if (IS_ERR_OR_NULL(q)) {
++              inet_frag_maybe_warn_overflow(q, pr_fmt());
++              return NULL;
++      }
+       return container_of(q, struct frag_queue, q);
+-
+-oom:
+-      return NULL;
+ }
+--- a/net/ipv6/reassembly.c
++++ b/net/ipv6/reassembly.c
+@@ -26,6 +26,9 @@
+  *    YOSHIFUJI,H. @USAGI     Always remove fragment header to
+  *                            calculate ICV correctly.
+  */
++
++#define pr_fmt(fmt) "IPv6: " fmt
++
+ #include <linux/errno.h>
+ #include <linux/types.h>
+ #include <linux/string.h>
+@@ -197,9 +200,10 @@ fq_find(struct net *net, __be32 id, cons
+       hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
+       q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
+-      if (q == NULL)
++      if (IS_ERR_OR_NULL(q)) {
++              inet_frag_maybe_warn_overflow(q, pr_fmt());
+               return NULL;
+-
++      }
+       return container_of(q, struct frag_queue, q);
+ }
diff --git a/queue-3.8/ipv4-fix-definition-of-fib_table_hashsz.patch b/queue-3.8/ipv4-fix-definition-of-fib_table_hashsz.patch
new file mode 100644 (file)
index 0000000..8b7ff04
--- /dev/null
@@ -0,0 +1,61 @@
+From 0e7e63e4b65a06692d85f68a4111f7610e184eba Mon Sep 17 00:00:00 2001
+From: "Denis V. Lunev" <den@openvz.org>
+Date: Wed, 13 Mar 2013 00:24:15 +0000
+Subject: ipv4: fix definition of FIB_TABLE_HASHSZ
+
+
+From: "Denis V. Lunev" <den@openvz.org>
+
+[ Upstream commit 5b9e12dbf92b441b37136ea71dac59f05f2673a9 ]
+
+a long time ago by the commit
+
+  commit 93456b6d7753def8760b423ac6b986eb9d5a4a95
+  Author: Denis V. Lunev <den@openvz.org>
+  Date:   Thu Jan 10 03:23:38 2008 -0800
+
+    [IPV4]: Unify access to the routing tables.
+
+the defenition of FIB_HASH_TABLE size has obtained wrong dependency:
+it should depend upon CONFIG_IP_MULTIPLE_TABLES (as was in the original
+code) but it was depended from CONFIG_IP_ROUTE_MULTIPATH
+
+This patch returns the situation to the original state.
+
+The problem was spotted by Tingwei Liu.
+
+Signed-off-by: Denis V. Lunev <den@openvz.org>
+CC: Tingwei Liu <tingw.liu@gmail.com>
+CC: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip_fib.h |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/include/net/ip_fib.h
++++ b/include/net/ip_fib.h
+@@ -152,18 +152,16 @@ struct fib_result_nl {
+ };
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH
+-
+ #define FIB_RES_NH(res)               ((res).fi->fib_nh[(res).nh_sel])
+-
+-#define FIB_TABLE_HASHSZ 2
+-
+ #else /* CONFIG_IP_ROUTE_MULTIPATH */
+-
+ #define FIB_RES_NH(res)               ((res).fi->fib_nh[0])
++#endif /* CONFIG_IP_ROUTE_MULTIPATH */
++#ifdef CONFIG_IP_MULTIPLE_TABLES
+ #define FIB_TABLE_HASHSZ 256
+-
+-#endif /* CONFIG_IP_ROUTE_MULTIPATH */
++#else
++#define FIB_TABLE_HASHSZ 2
++#endif
+ extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
diff --git a/queue-3.8/net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch b/queue-3.8/net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch
new file mode 100644 (file)
index 0000000..14ae0f5
--- /dev/null
@@ -0,0 +1,146 @@
+From 10a12e57640403f617cc2bb138b9574c6317cc4a Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn@mork.no>
+Date: Thu, 14 Mar 2013 01:05:13 +0000
+Subject: net: cdc_ncm, cdc_mbim: allow user to prefer NCM for backwards compatibility
+
+
+From: Bjørn Mork <bjorn@mork.no>
+
+[ Upstream commit 1e8bbe6cd02fc300c88bd48244ce61ad9c7d1776 ]
+
+commit bd329e1 ("net: cdc_ncm: do not bind to NCM compatible MBIM devices")
+introduced a new policy, preferring MBIM for dual NCM/MBIM functions if
+the cdc_mbim driver was enabled.  This caused a regression for users
+wanting to use NCM.
+
+Devices implementing NCM backwards compatibility according to section
+3.2 of the MBIM v1.0 specification allow either NCM or MBIM on a single
+USB function, using different altsettings.  The cdc_ncm and cdc_mbim
+drivers will both probe such functions, and must agree on a common
+policy for selecting either MBIM or NCM.  Until now, this policy has
+been set at build time based on CONFIG_USB_NET_CDC_MBIM.
+
+Use a module parameter to set the system policy at runtime, allowing the
+user to prefer NCM on systems with the cdc_mbim driver.
+
+Cc: Greg Suarez <gsuarez@smithmicro.com>
+Cc: Alexey Orishko <alexey.orishko@stericsson.com>
+Reported-by: Geir Haatveit <nospam@haatveit.nu>
+Reported-by: Tommi Kyntola <kynde@ts.ray.fi>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=54791
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_mbim.c  |   11 ---------
+ drivers/net/usb/cdc_ncm.c   |   49 ++++++++++++++++++++++++++++----------------
+ include/linux/usb/cdc_ncm.h |    1 
+ 3 files changed, 34 insertions(+), 27 deletions(-)
+
+--- a/drivers/net/usb/cdc_mbim.c
++++ b/drivers/net/usb/cdc_mbim.c
+@@ -68,18 +68,9 @@ static int cdc_mbim_bind(struct usbnet *
+       struct cdc_ncm_ctx *ctx;
+       struct usb_driver *subdriver = ERR_PTR(-ENODEV);
+       int ret = -ENODEV;
+-      u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM;
++      u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf);
+       struct cdc_mbim_state *info = (void *)&dev->data;
+-      /* see if interface supports MBIM alternate setting */
+-      if (intf->num_altsetting == 2) {
+-              if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+-                      usb_set_interface(dev->udev,
+-                                        intf->cur_altsetting->desc.bInterfaceNumber,
+-                                        CDC_NCM_COMM_ALTSETTING_MBIM);
+-              data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
+-      }
+-
+       /* Probably NCM, defer for cdc_ncm_bind */
+       if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+               goto err;
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -55,6 +55,14 @@
+ #define       DRIVER_VERSION                          "14-Mar-2012"
++#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
++static bool prefer_mbim = true;
++#else
++static bool prefer_mbim;
++#endif
++module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
++
+ static void cdc_ncm_txpath_bh(unsigned long param);
+ static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
+ static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
+@@ -550,9 +558,12 @@ void cdc_ncm_unbind(struct usbnet *dev,
+ }
+ EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
+-static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
++/* Select the MBIM altsetting iff it is preferred and available,
++ * returning the number of the corresponding data interface altsetting
++ */
++u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
+ {
+-      int ret;
++      struct usb_host_interface *alt;
+       /* The MBIM spec defines a NCM compatible default altsetting,
+        * which we may have matched:
+@@ -568,23 +579,27 @@ static int cdc_ncm_bind(struct usbnet *d
+        *   endpoint descriptors, shall be constructed according to
+        *   the rules given in section 6 (USB Device Model) of this
+        *   specification."
+-       *
+-       * Do not bind to such interfaces, allowing cdc_mbim to handle
+-       * them
+        */
+-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
+-      if ((intf->num_altsetting == 2) &&
+-          !usb_set_interface(dev->udev,
+-                             intf->cur_altsetting->desc.bInterfaceNumber,
+-                             CDC_NCM_COMM_ALTSETTING_MBIM)) {
+-              if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+-                      return -ENODEV;
+-              else
+-                      usb_set_interface(dev->udev,
+-                                        intf->cur_altsetting->desc.bInterfaceNumber,
+-                                        CDC_NCM_COMM_ALTSETTING_NCM);
++      if (prefer_mbim && intf->num_altsetting == 2) {
++              alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM);
++              if (alt && cdc_ncm_comm_intf_is_mbim(alt) &&
++                  !usb_set_interface(dev->udev,
++                                     intf->cur_altsetting->desc.bInterfaceNumber,
++                                     CDC_NCM_COMM_ALTSETTING_MBIM))
++                      return CDC_NCM_DATA_ALTSETTING_MBIM;
+       }
+-#endif
++      return CDC_NCM_DATA_ALTSETTING_NCM;
++}
++EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);
++
++static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
++{
++      int ret;
++
++      /* MBIM backwards compatible function? */
++      cdc_ncm_select_altsetting(dev, intf);
++      if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
++              return -ENODEV;
+       /* NCM data altsetting is always 1 */
+       ret = cdc_ncm_bind_common(dev, intf, 1);
+--- a/include/linux/usb/cdc_ncm.h
++++ b/include/linux/usb/cdc_ncm.h
+@@ -127,6 +127,7 @@ struct cdc_ncm_ctx {
+       u16 connected;
+ };
++extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf);
+ extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting);
+ extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
+ extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign);
diff --git a/queue-3.8/net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch b/queue-3.8/net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch
new file mode 100644 (file)
index 0000000..b5a4e7b
--- /dev/null
@@ -0,0 +1,65 @@
+From c0803b42e711d49661bb1cc8e16b27de1d468fcc Mon Sep 17 00:00:00 2001
+From: David Ward <david.ward@ll.mit.edu>
+Date: Mon, 11 Mar 2013 10:43:39 +0000
+Subject: net/ipv4: Ensure that location of timestamp option is stored
+
+
+From: David Ward <david.ward@ll.mit.edu>
+
+[ Upstream commit 4660c7f498c07c43173142ea95145e9dac5a6d14 ]
+
+This is needed in order to detect if the timestamp option appears
+more than once in a packet, to remove the option if the packet is
+fragmented, etc. My previous change neglected to store the option
+location when the router addresses were prespecified and Pointer >
+Length. But now the option location is also stored when Flag is an
+unrecognized value, to ensure these option handling behaviors are
+still performed.
+
+Signed-off-by: David Ward <david.ward@ll.mit.edu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_options.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/net/ipv4/ip_options.c
++++ b/net/ipv4/ip_options.c
+@@ -370,7 +370,6 @@ int ip_options_compile(struct net *net,
+                               }
+                               switch (optptr[3]&0xF) {
+                                     case IPOPT_TS_TSONLY:
+-                                      opt->ts = optptr - iph;
+                                       if (skb)
+                                               timeptr = &optptr[optptr[2]-1];
+                                       opt->ts_needtime = 1;
+@@ -381,7 +380,6 @@ int ip_options_compile(struct net *net,
+                                               pp_ptr = optptr + 2;
+                                               goto error;
+                                       }
+-                                      opt->ts = optptr - iph;
+                                       if (rt)  {
+                                               spec_dst_fill(&spec_dst, skb);
+                                               memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
+@@ -396,7 +394,6 @@ int ip_options_compile(struct net *net,
+                                               pp_ptr = optptr + 2;
+                                               goto error;
+                                       }
+-                                      opt->ts = optptr - iph;
+                                       {
+                                               __be32 addr;
+                                               memcpy(&addr, &optptr[optptr[2]-1], 4);
+@@ -429,12 +426,12 @@ int ip_options_compile(struct net *net,
+                                       pp_ptr = optptr + 3;
+                                       goto error;
+                               }
+-                              opt->ts = optptr - iph;
+                               if (skb) {
+                                       optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
+                                       opt->is_changed = 1;
+                               }
+                       }
++                      opt->ts = optptr - iph;
+                       break;
+                     case IPOPT_RA:
+                       if (optlen < 4) {
diff --git a/queue-3.8/net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch b/queue-3.8/net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch
new file mode 100644 (file)
index 0000000..e1acde6
--- /dev/null
@@ -0,0 +1,129 @@
+From 414280879d7c2222b06519744c03a6d2f8f2d2f4 Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn@mork.no>
+Date: Wed, 13 Mar 2013 02:25:17 +0000
+Subject: net: qmi_wwan: set correct altsetting for Gobi 1K devices
+
+
+From: Bjørn Mork <bjorn@mork.no>
+
+[ Upstream commit b701f16dd490d3f346724050f17d60beda094998 ]
+
+commit bd877e4 ("net: qmi_wwan: use a single bind function for
+all device types") made Gobi 1K devices fail probing.
+
+Using the number of endpoints in the default altsetting to decide
+whether the function use one or two interfaces is wrong.  Other
+altsettings may provide more endpoints.
+
+With Gobi 1K devices, USB interface #3's altsetting is 0 by default, but
+altsetting 0 only provides one interrupt endpoint and is not sufficent
+for QMI.  Altsetting 1 provides all 3 endpoints required for qmi_wwan
+and works with QMI. Gobi 1K layout for intf#3 is:
+
+    Interface Descriptor:  255/255/255
+      bInterfaceNumber        3
+      bAlternateSetting       0
+      Endpoint Descriptor:  Interrupt IN
+    Interface Descriptor:  255/255/255
+      bInterfaceNumber        3
+      bAlternateSetting       1
+      Endpoint Descriptor:  Interrupt IN
+      Endpoint Descriptor:  Bulk IN
+      Endpoint Descriptor:  Bulk OUT
+
+Prior to commit bd877e4, we would call usbnet_get_endpoints
+before giving up finding enough endpoints. Removing the early
+endpoint number test and the strict functional descriptor
+requirement allow qmi_wwan_bind to continue until
+usbnet_get_endpoints has made the final attempt to collect
+endpoints.  This restores the behaviour from before commit
+bd877e4 without losing the added benefit of using a single bind
+function.
+
+The driver has always required a CDC Union functional descriptor
+for two-interface functions. Using the existence of this
+descriptor to detect two-interface functions is the logically
+correct method.
+
+Reported-by: Dan Williams <dcbw@redhat.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Tested-by: Dan Williams <dcbw@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |   49 ++++++++++++++-------------------------------
+ 1 file changed, 16 insertions(+), 33 deletions(-)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -139,16 +139,9 @@ static int qmi_wwan_bind(struct usbnet *
+       BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
+-      /* control and data is shared? */
+-      if (intf->cur_altsetting->desc.bNumEndpoints == 3) {
+-              info->control = intf;
+-              info->data = intf;
+-              goto shared;
+-      }
+-
+-      /* else require a single interrupt status endpoint on control intf */
+-      if (intf->cur_altsetting->desc.bNumEndpoints != 1)
+-              goto err;
++      /* set up initial state */
++      info->control = intf;
++      info->data = intf;
+       /* and a number of CDC descriptors */
+       while (len > 3) {
+@@ -207,25 +200,14 @@ next_desc:
+               buf += h->bLength;
+       }
+-      /* did we find all the required ones? */
+-      if (!(found & (1 << USB_CDC_HEADER_TYPE)) ||
+-          !(found & (1 << USB_CDC_UNION_TYPE))) {
+-              dev_err(&intf->dev, "CDC functional descriptors missing\n");
+-              goto err;
+-      }
+-
+-      /* verify CDC Union */
+-      if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) {
+-              dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0);
+-              goto err;
+-      }
+-
+-      /* need to save these for unbind */
+-      info->control = intf;
+-      info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
+-      if (!info->data) {
+-              dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0);
+-              goto err;
++      /* Use separate control and data interfaces if we found a CDC Union */
++      if (cdc_union) {
++              info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
++              if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) {
++                      dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n",
++                              cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0);
++                      goto err;
++              }
+       }
+       /* errors aren't fatal - we can live with the dynamic address */
+@@ -235,11 +217,12 @@ next_desc:
+       }
+       /* claim data interface and set it up */
+-      status = usb_driver_claim_interface(driver, info->data, dev);
+-      if (status < 0)
+-              goto err;
++      if (info->control != info->data) {
++              status = usb_driver_claim_interface(driver, info->data, dev);
++              if (status < 0)
++                      goto err;
++      }
+-shared:
+       status = qmi_wwan_register_subdriver(dev);
+       if (status < 0 && info->control != info->data) {
+               usb_set_intfdata(info->data, NULL);
diff --git a/queue-3.8/netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch b/queue-3.8/netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch
new file mode 100644 (file)
index 0000000..b04c991
--- /dev/null
@@ -0,0 +1,58 @@
+From 27510f26c7b4b94b94b5ebd516763e948d546d3a Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Mon, 11 Mar 2013 00:21:48 +0000
+Subject: netconsole: don't call __netpoll_cleanup() while atomic
+
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit 3f315bef23075ea8a98a6fe4221a83b83456d970 ]
+
+__netpoll_cleanup() is called in netconsole_netdev_event() while holding a
+spinlock. Release/acquire the spinlock before/after it and restart the
+loop. Also, disable the netconsole completely, because we won't have chance
+after the restart of the loop, and might end up in a situation where
+nt->enabled == 1 and nt->np.dev == NULL.
+
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/netconsole.c |   15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/netconsole.c
++++ b/drivers/net/netconsole.c
+@@ -630,6 +630,7 @@ static int netconsole_netdev_event(struc
+               goto done;
+       spin_lock_irqsave(&target_list_lock, flags);
++restart:
+       list_for_each_entry(nt, &target_list, list) {
+               netconsole_target_get(nt);
+               if (nt->np.dev == dev) {
+@@ -642,15 +643,17 @@ static int netconsole_netdev_event(struc
+                       case NETDEV_UNREGISTER:
+                               /*
+                                * rtnl_lock already held
++                               * we might sleep in __netpoll_cleanup()
+                                */
+-                              if (nt->np.dev) {
+-                                      __netpoll_cleanup(&nt->np);
+-                                      dev_put(nt->np.dev);
+-                                      nt->np.dev = NULL;
+-                              }
++                              spin_unlock_irqrestore(&target_list_lock, flags);
++                              __netpoll_cleanup(&nt->np);
++                              spin_lock_irqsave(&target_list_lock, flags);
++                              dev_put(nt->np.dev);
++                              nt->np.dev = NULL;
+                               nt->enabled = 0;
+                               stopped = true;
+-                              break;
++                              netconsole_target_put(nt);
++                              goto restart;
+                       }
+               }
+               netconsole_target_put(nt);
diff --git a/queue-3.8/revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch b/queue-3.8/revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch
new file mode 100644 (file)
index 0000000..86110e9
--- /dev/null
@@ -0,0 +1,42 @@
+From 9c4b1c9f8df04914afe6c1c51c9745cb8f951adc Mon Sep 17 00:00:00 2001
+From: Timo Teräs <timo.teras@iki.fi>
+Date: Wed, 13 Mar 2013 02:37:49 +0000
+Subject: Revert "ip_gre: make ipgre_tunnel_xmit() not parse network header as IP unconditionally"
+
+
+From: Timo Teräs <timo.teras@iki.fi>
+
+[ Upstream commit 8c6216d7f118a128678270824b6a1286a63863ca ]
+
+This reverts commit 412ed94744d16806fbec3bd250fd94e71cde5a1f.
+
+The commit is wrong as tiph points to the outer IPv4 header which is
+installed at ipgre_header() and not the inner one which is protocol dependant.
+
+This commit broke succesfully opennhrp which use PF_PACKET socket with
+ETH_P_NHRP protocol. Additionally ssl_addr is set to the link-layer
+IPv4 address. This address is written by ipgre_header() to the skb
+earlier, and this is the IPv4 header tiph should point to - regardless
+of the inner protocol payload.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_gre.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -761,10 +761,7 @@ static netdev_tx_t ipgre_tunnel_xmit(str
+       if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
+               gre_hlen = 0;
+-              if (skb->protocol == htons(ETH_P_IP))
+-                      tiph = (const struct iphdr *)skb->data;
+-              else
+-                      tiph = &tunnel->parms.iph;
++              tiph = (const struct iphdr *)skb->data;
+       } else {
+               gre_hlen = tunnel->hlen;
+               tiph = &tunnel->parms.iph;
diff --git a/queue-3.8/rtnetlink-mask-the-rta_type-when-range-checking.patch b/queue-3.8/rtnetlink-mask-the-rta_type-when-range-checking.patch
new file mode 100644 (file)
index 0000000..89e58a0
--- /dev/null
@@ -0,0 +1,34 @@
+From 8e19bd050e8d9290964fa9b758fede105579ede9 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vyasevic@redhat.com>
+Date: Wed, 13 Mar 2013 04:18:58 +0000
+Subject: rtnetlink: Mask the rta_type when range checking
+
+
+From: Vlad Yasevich <vyasevic@redhat.com>
+
+[ Upstream commit a5b8db91442fce9c9713fcd656c3698f1adde1d6 ]
+
+Range/validity checks on rta_type in rtnetlink_rcv_msg() do
+not account for flags that may be set.  This causes the function
+to return -EINVAL when flags are set on the type (for example
+NLA_F_NESTED).
+
+Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
+Acked-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/rtnetlink.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -2539,7 +2539,7 @@ static int rtnetlink_rcv_msg(struct sk_b
+               struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
+               while (RTA_OK(attr, attrlen)) {
+-                      unsigned int flavor = attr->rta_type;
++                      unsigned int flavor = attr->rta_type & NLA_TYPE_MASK;
+                       if (flavor) {
+                               if (flavor > rta_max[sz_idx])
+                                       return -EINVAL;
diff --git a/queue-3.8/sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch b/queue-3.8/sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch
new file mode 100644 (file)
index 0000000..059a44b
--- /dev/null
@@ -0,0 +1,36 @@
+From 1dd112ced7c4ef8f5e8a511d557af56e7c03b9bc Mon Sep 17 00:00:00 2001
+From: Xufeng Zhang <xufeng.zhang@windriver.com>
+Date: Thu, 7 Mar 2013 21:39:37 +0000
+Subject: sctp: don't break the loop while meeting the active_path so as to find the matched transport
+
+
+From: Xufeng Zhang <xufeng.zhang@windriver.com>
+
+[ Upstream commit 2317f449af30073cfa6ec8352e4a65a89e357bdd ]
+
+sctp_assoc_lookup_tsn() function searchs which transport a certain TSN
+was sent on, if not found in the active_path transport, then go search
+all the other transports in the peer's transport_addr_list, however, we
+should continue to the next entry rather than break the loop when meet
+the active_path transport.
+
+Signed-off-by: Xufeng Zhang <xufeng.zhang@windriver.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Acked-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/associola.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/associola.c
++++ b/net/sctp/associola.c
+@@ -1080,7 +1080,7 @@ struct sctp_transport *sctp_assoc_lookup
+                       transports) {
+               if (transport == active)
+-                      break;
++                      continue;
+               list_for_each_entry(chunk, &transport->transmitted,
+                               transmitted_list) {
+                       if (key == chunk->subh.data_hdr->tsn) {
diff --git a/queue-3.8/sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch b/queue-3.8/sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch
new file mode 100644 (file)
index 0000000..6bba029
--- /dev/null
@@ -0,0 +1,47 @@
+From a15def48d4ca2744b0f60d75f849297e660dba66 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vyasevich@gmail.com>
+Date: Tue, 12 Mar 2013 15:53:23 +0000
+Subject: sctp: Use correct sideffect command in duplicate cookie handling
+
+
+From: Vlad Yasevich <vyasevich@gmail.com>
+
+[ Upstream commit f2815633504b442ca0b0605c16bf3d88a3a0fcea ]
+
+When SCTP is done processing a duplicate cookie chunk, it tries
+to delete a newly created association.  For that, it has to set
+the right association for the side-effect processing to work.
+However, when it uses the SCTP_CMD_NEW_ASOC command, that performs
+more work then really needed (like hashing the associationa and
+assigning it an id) and there is no point to do that only to
+delete the association as a next step.  In fact, it also creates
+an impossible condition where an association may be found by
+the getsockopt() call, and that association is empty.  This
+causes a crash in some sctp getsockopts.
+
+The solution is rather simple.  We simply use SCTP_CMD_SET_ASOC
+command that doesn't have all the overhead and does exactly
+what we need.
+
+Reported-by: Karl Heiss <kheiss@gmail.com>
+Tested-by: Karl Heiss <kheiss@gmail.com>
+CC: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/sm_statefuns.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -2082,7 +2082,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupc
+       }
+       /* Delete the tempory new association. */
+-      sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
++      sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
+       sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
+       /* Restore association pointer to provide SCTP command interpeter
index d71ad4f3e5da2cebd6eb0a7391cbbb8acfeab13c..3a9178930ff76aaf5b32c5fd88a30f4d53bd4e95 100644 (file)
@@ -1,2 +1,28 @@
 usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch
 sunsu-fix-panic-in-case-of-nonexistent-port-at-console-ttysy-cmdline-option.patch
+net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch
+bridge-reserve-space-for-ifla_brport_fast_leave.patch
+netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch
+batman-adv-verify-tt-len-does-not-exceed-packet-len.patch
+bonding-don-t-call-update_speed_duplex-under-spinlocks.patch
+tg3-5715-does-not-link-up-when-autoneg-off.patch
+sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch
+sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch
+ipv4-fix-definition-of-fib_table_hashsz.patch
+net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch
+tcp-fix-skb_availroom.patch
+skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch
+revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch
+rtnetlink-mask-the-rta_type-when-range-checking.patch
+net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch
+bnx2x-add-missing-napi-deletion-in-error-path.patch
+vhost-net-fix-heads-usage-of-ubuf_info.patch
+bnx2x-fix-occasional-statistics-off-by-4gb-error.patch
+tcp-dont-handle-mtu-reduction-on-listen-socket.patch
+inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch
+drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch
+sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch
+sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch
+sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch
+sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch
+sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch
diff --git a/queue-3.8/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch b/queue-3.8/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch
new file mode 100644 (file)
index 0000000..2c610c4
--- /dev/null
@@ -0,0 +1,89 @@
+From f7f9a46f71e6995fb60d2ed8fabecdd9bbda1eee Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Mon, 28 Jan 2013 19:01:06 +0000
+Subject: sfc: Detach net device when stopping queues for reconfiguration
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit 29c69a4882641285a854d6d03ca5adbba68c0034 ]
+
+We must only ever stop TX queues when they are full or the net device
+is not 'ready' so far as the net core, and specifically the watchdog,
+is concerned.  Otherwise, the watchdog may fire *immediately* if no
+packets have been added to the queue in the last 5 seconds.
+
+The device is ready if all the following are true:
+
+(a) It has a qdisc
+(b) It is marked present
+(c) It is running
+(d) The link is reported up
+
+(a) and (c) are normally true, and must not be changed by a driver.
+(d) is under our control, but fake link changes may disturb userland.
+This leaves (b).  We already mark the device absent during reset
+and self-test, but we need to do the same during MTU changes and ring
+reallocation.  We don't need to do this when the device is brought
+down because then (c) is already false.
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/efx.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -779,6 +779,7 @@ efx_realloc_channels(struct efx_nic *efx
+                                               tx_queue->txd.entries);
+       }
++      efx_device_detach_sync(efx);
+       efx_stop_all(efx);
+       efx_stop_interrupts(efx, true);
+@@ -832,6 +833,7 @@ out:
+       efx_start_interrupts(efx, true);
+       efx_start_all(efx);
++      netif_device_attach(efx->net_dev);
+       return rc;
+ rollback:
+@@ -1641,8 +1643,12 @@ static void efx_stop_all(struct efx_nic
+       /* Flush efx_mac_work(), refill_workqueue, monitor_work */
+       efx_flush_all(efx);
+-      /* Stop the kernel transmit interface late, so the watchdog
+-       * timer isn't ticking over the flush */
++      /* Stop the kernel transmit interface.  This is only valid if
++       * the device is stopped or detached; otherwise the watchdog
++       * may fire immediately.
++       */
++      WARN_ON(netif_running(efx->net_dev) &&
++              netif_device_present(efx->net_dev));
+       netif_tx_disable(efx->net_dev);
+       efx_stop_datapath(efx);
+@@ -1963,16 +1969,18 @@ static int efx_change_mtu(struct net_dev
+       if (new_mtu > EFX_MAX_MTU)
+               return -EINVAL;
+-      efx_stop_all(efx);
+-
+       netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
++      efx_device_detach_sync(efx);
++      efx_stop_all(efx);
++
+       mutex_lock(&efx->mac_lock);
+       net_dev->mtu = new_mtu;
+       efx->type->reconfigure_mac(efx);
+       mutex_unlock(&efx->mac_lock);
+       efx_start_all(efx);
++      netif_device_attach(efx->net_dev);
+       return 0;
+ }
diff --git a/queue-3.8/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch b/queue-3.8/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch
new file mode 100644 (file)
index 0000000..f08b67f
--- /dev/null
@@ -0,0 +1,38 @@
+From df50fed6fcae20d5523e9482d90af7094f6297d0 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Tue, 5 Mar 2013 01:03:47 +0000
+Subject: sfc: Disable soft interrupt handling during efx_device_detach_sync()
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit 35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad ]
+
+efx_device_detach_sync() locks all TX queues before marking the device
+detached and thus disabling further TX scheduling.  But it can still
+be interrupted by TX completions which then result in TX scheduling in
+soft interrupt context.  This will deadlock when it tries to acquire
+a TX queue lock that efx_device_detach_sync() already acquired.
+
+To avoid deadlock, we must use netif_tx_{,un}lock_bh().
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/efx.h |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/efx.h
++++ b/drivers/net/ethernet/sfc/efx.h
+@@ -171,9 +171,9 @@ static inline void efx_device_detach_syn
+        * TX scheduler is stopped when we're done and before
+        * netif_device_present() becomes false.
+        */
+-      netif_tx_lock(dev);
++      netif_tx_lock_bh(dev);
+       netif_device_detach(dev);
+-      netif_tx_unlock(dev);
++      netif_tx_unlock_bh(dev);
+ }
+ #endif /* EFX_EFX_H */
diff --git a/queue-3.8/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch b/queue-3.8/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch
new file mode 100644 (file)
index 0000000..d06cf4e
--- /dev/null
@@ -0,0 +1,91 @@
+From be254a1f0e75d7cbe7d0fae5b3424bc4849f772a Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Thu, 10 Jan 2013 23:51:54 +0000
+Subject: sfc: Fix efx_rx_buf_offset() in the presence of swiotlb
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commits b590ace09d51cd39744e0f7662c5e4a0d1b5d952 and
+  c73e787a8db9117d59b5180baf83203a42ecadca ]
+
+We assume that the mapping between DMA and virtual addresses is done
+on whole pages, so we can find the page offset of an RX buffer using
+the lower bits of the DMA address.  However, swiotlb maps in units of
+2K, breaking this assumption.
+
+Add an explicit page_offset field to struct efx_rx_buffer.
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/net_driver.h |    4 +++-
+ drivers/net/ethernet/sfc/rx.c         |   10 +++++-----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/net_driver.h
++++ b/drivers/net/ethernet/sfc/net_driver.h
+@@ -210,6 +210,7 @@ struct efx_tx_queue {
+  *    Will be %NULL if the buffer slot is currently free.
+  * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE.
+  *    Will be %NULL if the buffer slot is currently free.
++ * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE.
+  * @len: Buffer length, in bytes.
+  * @flags: Flags for buffer and packet state.
+  */
+@@ -219,7 +220,8 @@ struct efx_rx_buffer {
+               struct sk_buff *skb;
+               struct page *page;
+       } u;
+-      unsigned int len;
++      u16 page_offset;
++      u16 len;
+       u16 flags;
+ };
+ #define EFX_RX_BUF_PAGE               0x0001
+--- a/drivers/net/ethernet/sfc/rx.c
++++ b/drivers/net/ethernet/sfc/rx.c
+@@ -90,11 +90,7 @@ static unsigned int rx_refill_threshold;
+ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
+                                            struct efx_rx_buffer *buf)
+ {
+-      /* Offset is always within one page, so we don't need to consider
+-       * the page order.
+-       */
+-      return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) +
+-              efx->type->rx_buffer_hash_size;
++      return buf->page_offset + efx->type->rx_buffer_hash_size;
+ }
+ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
+ {
+@@ -187,6 +183,7 @@ static int efx_init_rx_buffers_page(stru
+       struct efx_nic *efx = rx_queue->efx;
+       struct efx_rx_buffer *rx_buf;
+       struct page *page;
++      unsigned int page_offset;
+       struct efx_rx_page_state *state;
+       dma_addr_t dma_addr;
+       unsigned index, count;
+@@ -211,12 +208,14 @@ static int efx_init_rx_buffers_page(stru
+               state->dma_addr = dma_addr;
+               dma_addr += sizeof(struct efx_rx_page_state);
++              page_offset = sizeof(struct efx_rx_page_state);
+       split:
+               index = rx_queue->added_count & rx_queue->ptr_mask;
+               rx_buf = efx_rx_buffer(rx_queue, index);
+               rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
+               rx_buf->u.page = page;
++              rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
+               rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
+               rx_buf->flags = EFX_RX_BUF_PAGE;
+               ++rx_queue->added_count;
+@@ -227,6 +226,7 @@ static int efx_init_rx_buffers_page(stru
+                       /* Use the second half of the page */
+                       get_page(page);
+                       dma_addr += (PAGE_SIZE >> 1);
++                      page_offset += (PAGE_SIZE >> 1);
+                       ++count;
+                       goto split;
+               }
diff --git a/queue-3.8/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch b/queue-3.8/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch
new file mode 100644 (file)
index 0000000..843e4c2
--- /dev/null
@@ -0,0 +1,37 @@
+From 447751edc8935bca63f3004fd0c21cda48bb5268 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Wed, 27 Feb 2013 16:50:38 +0000
+Subject: sfc: Only use TX push if a single descriptor is to be written
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit fae8563b25f73dc584a07bcda7a82750ff4f7672 ]
+
+Using TX push when notifying the NIC of multiple new descriptors in
+the ring will very occasionally cause the TX DMA engine to re-use an
+old descriptor.  This can result in a duplicated or partly duplicated
+packet (new headers with old data), or an IOMMU page fault.  This does
+not happen when the pushed descriptor is the only one written.
+
+TX push also provides little latency benefit when a packet requires
+more than one descriptor.
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/nic.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/sfc/nic.c
++++ b/drivers/net/ethernet/sfc/nic.c
+@@ -376,7 +376,8 @@ efx_may_push_tx_desc(struct efx_tx_queue
+               return false;
+       tx_queue->empty_read_count = 0;
+-      return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
++      return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0
++              && tx_queue->write_count - write_count == 1;
+ }
+ /* For each entry inserted into the software descriptor ring, create a
diff --git a/queue-3.8/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch b/queue-3.8/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch
new file mode 100644 (file)
index 0000000..b632871
--- /dev/null
@@ -0,0 +1,70 @@
+From 0ea6a742ceb04ede6504f1428220d3348c02f60f Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Thu, 20 Dec 2012 18:48:20 +0000
+Subject: sfc: Properly sync RX DMA buffer when it is not the last in the page
+
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit 3a68f19d7afb80f548d016effbc6ed52643a8085 ]
+
+We may currently allocate two RX DMA buffers to a page, and only unmap
+the page when the second is completed.  We do not sync the first RX
+buffer to be completed; this can result in packet loss or corruption
+if the last RX buffer completed in a NAPI poll is the first in a page
+and is not DMA-coherent.  (In the middle of a NAPI poll, we will
+handle the following RX completion and unmap the page *before* looking
+at the content of the first buffer.)
+
+Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/rx.c |   15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/rx.c
++++ b/drivers/net/ethernet/sfc/rx.c
+@@ -236,7 +236,8 @@ static int efx_init_rx_buffers_page(stru
+ }
+ static void efx_unmap_rx_buffer(struct efx_nic *efx,
+-                              struct efx_rx_buffer *rx_buf)
++                              struct efx_rx_buffer *rx_buf,
++                              unsigned int used_len)
+ {
+       if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
+               struct efx_rx_page_state *state;
+@@ -247,6 +248,10 @@ static void efx_unmap_rx_buffer(struct e
+                                      state->dma_addr,
+                                      efx_rx_buf_size(efx),
+                                      DMA_FROM_DEVICE);
++              } else if (used_len) {
++                      dma_sync_single_for_cpu(&efx->pci_dev->dev,
++                                              rx_buf->dma_addr, used_len,
++                                              DMA_FROM_DEVICE);
+               }
+       } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
+               dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr,
+@@ -269,7 +274,7 @@ static void efx_free_rx_buffer(struct ef
+ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
+                              struct efx_rx_buffer *rx_buf)
+ {
+-      efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
++      efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0);
+       efx_free_rx_buffer(rx_queue->efx, rx_buf);
+ }
+@@ -535,10 +540,10 @@ void efx_rx_packet(struct efx_rx_queue *
+               goto out;
+       }
+-      /* Release card resources - assumes all RX buffers consumed in-order
+-       * per RX queue
++      /* Release and/or sync DMA mapping - assumes all RX buffers
++       * consumed in-order per RX queue
+        */
+-      efx_unmap_rx_buffer(efx, rx_buf);
++      efx_unmap_rx_buffer(efx, rx_buf, len);
+       /* Prefetch nice and early so data will (hopefully) be in cache by
+        * the time we look at it.
diff --git a/queue-3.8/skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch b/queue-3.8/skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch
new file mode 100644 (file)
index 0000000..cb61502
--- /dev/null
@@ -0,0 +1,75 @@
+From 9faf2676b769388ac40a096c27b59fe5bee033b8 Mon Sep 17 00:00:00 2001
+From: Pavel Emelyanov <xemul@parallels.com>
+Date: Thu, 14 Mar 2013 03:29:40 +0000
+Subject: skb: Propagate pfmemalloc on skb from head page only
+
+
+From: Pavel Emelyanov <xemul@parallels.com>
+
+[ Upstream commit cca7af3889bfa343d33d5e657a38d876abd10e58 ]
+
+Hi.
+
+I'm trying to send big chunks of memory from application address space via
+TCP socket using vmsplice + splice like this
+
+   mem = mmap(128Mb);
+   vmsplice(pipe[1], mem); /* splice memory into pipe */
+   splice(pipe[0], tcp_socket); /* send it into network */
+
+When I'm lucky and a huge page splices into the pipe and then into the socket
+_and_ client and server ends of the TCP connection are on the same host,
+communicating via lo, the whole connection gets stuck! The sending queue
+becomes full and app stops writing/splicing more into it, but the receiving
+queue remains empty, and that's why.
+
+The __skb_fill_page_desc observes a tail page of a huge page and erroneously
+propagates its page->pfmemalloc value onto socket (the pfmemalloc on tail pages
+contain garbage). Then this skb->pfmemalloc leaks through lo and due to the
+
+    tcp_v4_rcv
+    sk_filter
+        if (skb->pfmemalloc && !sock_flag(sk, SOCK_MEMALLOC)) /* true */
+            return -ENOMEM
+        goto release_and_discard;
+
+no packets reach the socket. Even TCP re-transmits are dropped by this, as skb
+cloning clones the pfmemalloc flag as well.
+
+That said, here's the proper page->pfmemalloc propagation onto socket: we
+must check the huge-page's head page only, other pages' pfmemalloc and mapping
+values do not contain what is expected in this place. However, I'm not sure
+whether this fix is _complete_, since pfmemalloc propagation via lo also
+oesn't look great.
+
+Both, bit propagation from page to skb and this check in sk_filter, were
+introduced by c48a11c7 (netvm: propagate page->pfmemalloc to skb), in v3.5 so
+Mel and stable@ are in Cc.
+
+Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skbuff.h |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1269,11 +1269,13 @@ static inline void __skb_fill_page_desc(
+        * do not lose pfmemalloc information as the pages would not be
+        * allocated using __GFP_MEMALLOC.
+        */
+-      if (page->pfmemalloc && !page->mapping)
+-              skb->pfmemalloc = true;
+       frag->page.p              = page;
+       frag->page_offset         = off;
+       skb_frag_size_set(frag, size);
++
++      page = compound_head(page);
++      if (page->pfmemalloc && !page->mapping)
++              skb->pfmemalloc = true;
+ }
+ /**
diff --git a/queue-3.8/tcp-dont-handle-mtu-reduction-on-listen-socket.patch b/queue-3.8/tcp-dont-handle-mtu-reduction-on-listen-socket.patch
new file mode 100644 (file)
index 0000000..d22f626
--- /dev/null
@@ -0,0 +1,84 @@
+From c250387a8e1fb7181357c9f8cd6ed02230ec3e9e Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 18 Mar 2013 07:01:28 +0000
+Subject: tcp: dont handle MTU reduction on LISTEN socket
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0d4f0608619de59fd8169dd8e72aadc28d80e715 ]
+
+When an ICMP ICMP_FRAG_NEEDED (or ICMPV6_PKT_TOOBIG) message finds a
+LISTEN socket, and this socket is currently owned by the user, we
+set TCP_MTU_REDUCED_DEFERRED flag in listener tsq_flags.
+
+This is bad because if we clone the parent before it had a chance to
+clear the flag, the child inherits the tsq_flags value, and next
+tcp_release_cb() on the child will decrement sk_refcnt.
+
+Result is that we might free a live TCP socket, as reported by
+Dormando.
+
+IPv4: Attempt to release TCP socket in state 1
+
+Fix this issue by testing sk_state against TCP_LISTEN early, so that we
+set TCP_MTU_REDUCED_DEFERRED on appropriate sockets (not a LISTEN one)
+
+This bug was introduced in commit 563d34d05786
+(tcp: dont drop MTU reduction indications)
+
+Reported-by: dormando <dormando@rydia.net>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_ipv4.c |   14 +++++++-------
+ net/ipv6/tcp_ipv6.c |    7 +++++++
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -274,13 +274,6 @@ static void tcp_v4_mtu_reduced(struct so
+       struct inet_sock *inet = inet_sk(sk);
+       u32 mtu = tcp_sk(sk)->mtu_info;
+-      /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
+-       * send out by Linux are always <576bytes so they should go through
+-       * unfragmented).
+-       */
+-      if (sk->sk_state == TCP_LISTEN)
+-              return;
+-
+       dst = inet_csk_update_pmtu(sk, mtu);
+       if (!dst)
+               return;
+@@ -408,6 +401,13 @@ void tcp_v4_err(struct sk_buff *icmp_skb
+                       goto out;
+               if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
++                      /* We are not interested in TCP_LISTEN and open_requests
++                       * (SYN-ACKs send out by Linux are always <576bytes so
++                       * they should go through unfragmented).
++                       */
++                      if (sk->sk_state == TCP_LISTEN)
++                              goto out;
++
+                       tp->mtu_info = info;
+                       if (!sock_owned_by_user(sk)) {
+                               tcp_v4_mtu_reduced(sk);
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -389,6 +389,13 @@ static void tcp_v6_err(struct sk_buff *s
+       }
+       if (type == ICMPV6_PKT_TOOBIG) {
++              /* We are not interested in TCP_LISTEN and open_requests
++               * (SYN-ACKs send out by Linux are always <576bytes so
++               * they should go through unfragmented).
++               */
++              if (sk->sk_state == TCP_LISTEN)
++                      goto out;
++
+               tp->mtu_info = ntohl(info);
+               if (!sock_owned_by_user(sk))
+                       tcp_v6_mtu_reduced(sk);
diff --git a/queue-3.8/tcp-fix-skb_availroom.patch b/queue-3.8/tcp-fix-skb_availroom.patch
new file mode 100644 (file)
index 0000000..1c6344f
--- /dev/null
@@ -0,0 +1,78 @@
+From 2cbf892200d0d5bdc8e97ca8cfe6277c6f2a8ee2 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 14 Mar 2013 05:40:32 +0000
+Subject: tcp: fix skb_availroom()
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 16fad69cfe4adbbfa813de516757b87bcae36d93 ]
+
+Chrome OS team reported a crash on a Pixel ChromeBook in TCP stack :
+
+https://code.google.com/p/chromium/issues/detail?id=182056
+
+commit a21d45726acac (tcp: avoid order-1 allocations on wifi and tx
+path) did a poor choice adding an 'avail_size' field to skb, while
+what we really needed was a 'reserved_tailroom' one.
+
+It would have avoided commit 22b4a4f22da (tcp: fix retransmit of
+partially acked frames) and this commit.
+
+Crash occurs because skb_split() is not aware of the 'avail_size'
+management (and should not be aware)
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Mukesh Agrawal <quiche@chromium.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skbuff.h |    7 +++++--
+ net/ipv4/tcp.c         |    2 +-
+ net/ipv4/tcp_output.c  |    1 -
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -491,7 +491,7 @@ struct sk_buff {
+       union {
+               __u32           mark;
+               __u32           dropcount;
+-              __u32           avail_size;
++              __u32           reserved_tailroom;
+       };
+       sk_buff_data_t          inner_transport_header;
+@@ -1428,7 +1428,10 @@ static inline int skb_tailroom(const str
+  */
+ static inline int skb_availroom(const struct sk_buff *skb)
+ {
+-      return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
++      if (skb_is_nonlinear(skb))
++              return 0;
++
++      return skb->end - skb->tail - skb->reserved_tailroom;
+ }
+ /**
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -773,7 +773,7 @@ struct sk_buff *sk_stream_alloc_skb(stru
+                        * Make sure that we have exactly size bytes
+                        * available to the caller, no more, no less.
+                        */
+-                      skb->avail_size = size;
++                      skb->reserved_tailroom = skb->end - skb->tail - size;
+                       return skb;
+               }
+               __kfree_skb(skb);
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1298,7 +1298,6 @@ static void __pskb_trim_head(struct sk_b
+       eat = min_t(int, len, skb_headlen(skb));
+       if (eat) {
+               __skb_pull(skb, eat);
+-              skb->avail_size -= eat;
+               len -= eat;
+               if (!len)
+                       return;
diff --git a/queue-3.8/tg3-5715-does-not-link-up-when-autoneg-off.patch b/queue-3.8/tg3-5715-does-not-link-up-when-autoneg-off.patch
new file mode 100644 (file)
index 0000000..ee4f76c
--- /dev/null
@@ -0,0 +1,49 @@
+From 2dc8507fe1064bfc04e1aa80dac3938fa78c3e6e Mon Sep 17 00:00:00 2001
+From: Nithin Sujir <nsujir@broadcom.com>
+Date: Tue, 12 Mar 2013 15:32:48 +0000
+Subject: tg3: 5715 does not link up when autoneg off
+
+
+From: Nithin Sujir <nsujir@broadcom.com>
+
+[ Upstream commit 7c6cdead7cc9a99650d15497aae47d7472217eb1 ]
+
+Commit d13ba512cbba7de5d55d7a3b2aae7d83c8921457 ("tg3: Remove
+SPEED_UNKNOWN checks") cleaned up the autoneg advertisement by
+removing some dead code. One effect of this change was that the
+advertisement register would not be updated if autoneg is turned off.
+
+This exposed a bug on the 5715 device w.r.t linking. The 5715 defaults
+to advertise only 10Mb Full duplex. But with autoneg disabled, it needs
+the configured speed enabled in the advertisement register to link up.
+
+This patch adds the work around to advertise all speeds on the 5715 when
+autoneg is disabled.
+
+Reported-by: Marcin Miotk <marcinmiotk81@gmail.com>
+Reviewed-by: Benjamin Li <benli@broadcom.com>
+Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
+Signed-off-by: Michael Chan <mchan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/tg3.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -4093,6 +4093,14 @@ static void tg3_phy_copper_begin(struct
+               tp->link_config.active_speed = tp->link_config.speed;
+               tp->link_config.active_duplex = tp->link_config.duplex;
++              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
++                      /* With autoneg disabled, 5715 only links up when the
++                       * advertisement register has the configured speed
++                       * enabled.
++                       */
++                      tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL);
++              }
++
+               bmcr = 0;
+               switch (tp->link_config.speed) {
+               default:
diff --git a/queue-3.8/vhost-net-fix-heads-usage-of-ubuf_info.patch b/queue-3.8/vhost-net-fix-heads-usage-of-ubuf_info.patch
new file mode 100644 (file)
index 0000000..e9e91f4
--- /dev/null
@@ -0,0 +1,36 @@
+From fbec7a71b74231de6efb567e5cb4e37e89d75f84 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Sun, 17 Mar 2013 02:46:09 +0000
+Subject: vhost/net: fix heads usage of ubuf_info
+
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+[ Upstream commit 46aa92d1ba162b4b3d6b7102440e459d4e4ee255 ]
+
+ubuf info allocator uses guest controlled head as an index,
+so a malicious guest could put the same head entry in the ring twice,
+and we will get two callbacks on the same value.
+To fix use upend_idx which is guaranteed to be unique.
+
+Reported-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Cc: stable@kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/net.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/vhost/net.c
++++ b/drivers/vhost/net.c
+@@ -339,7 +339,8 @@ static void handle_tx(struct vhost_net *
+                               msg.msg_controllen = 0;
+                               ubufs = NULL;
+                       } else {
+-                              struct ubuf_info *ubuf = &vq->ubuf_info[head];
++                              struct ubuf_info *ubuf;
++                              ubuf = vq->ubuf_info + vq->upend_idx;
+                               vq->heads[vq->upend_idx].len =
+                                       VHOST_DMA_IN_PROGRESS;