From d6e9c606b7171c5e2d87e0856ccd5b632ed43de1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Mar 2013 14:16:22 -0700 Subject: [PATCH] 3.8-stable patches 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 --- ...fy-tt-len-does-not-exceed-packet-len.patch | 44 +++++ ...-missing-napi-deletion-in-error-path.patch | 34 ++++ ...casional-statistics-off-by-4gb-error.patch | 41 ++++ ...-update_speed_duplex-under-spinlocks.patch | 57 ++++++ ...rve-space-for-ifla_brport_fast_leave.patch | 38 ++++ ...rnet-sfc-ptp.c-adjust-duplicate-test.patch | 52 +++++ ...agment-queue-hash-table-bucket-lists.patch | 182 ++++++++++++++++++ ...4-fix-definition-of-fib_table_hashsz.patch | 61 ++++++ ...efer-ncm-for-backwards-compatibility.patch | 146 ++++++++++++++ ...cation-of-timestamp-option-is-stored.patch | 65 +++++++ ...rrect-altsetting-for-gobi-1k-devices.patch | 129 +++++++++++++ ...-call-__netpoll_cleanup-while-atomic.patch | 58 ++++++ ...network-header-as-ip-unconditionally.patch | 42 ++++ ...ask-the-rta_type-when-range-checking.patch | 34 ++++ ...-so-as-to-find-the-matched-transport.patch | 36 ++++ ...command-in-duplicate-cookie-handling.patch | 47 +++++ queue-3.8/series | 26 +++ ...-stopping-queues-for-reconfiguration.patch | 89 +++++++++ ...ndling-during-efx_device_detach_sync.patch | 38 ++++ ...uf_offset-in-the-presence-of-swiotlb.patch | 91 +++++++++ ...a-single-descriptor-is-to-be-written.patch | 37 ++++ ...-when-it-is-not-the-last-in-the-page.patch | 70 +++++++ ...fmemalloc-on-skb-from-head-page-only.patch | 75 ++++++++ ...andle-mtu-reduction-on-listen-socket.patch | 84 ++++++++ queue-3.8/tcp-fix-skb_availroom.patch | 78 ++++++++ ...15-does-not-link-up-when-autoneg-off.patch | 49 +++++ ...ost-net-fix-heads-usage-of-ubuf_info.patch | 36 ++++ 27 files changed, 1739 insertions(+) create mode 100644 queue-3.8/batman-adv-verify-tt-len-does-not-exceed-packet-len.patch create mode 100644 queue-3.8/bnx2x-add-missing-napi-deletion-in-error-path.patch create mode 100644 queue-3.8/bnx2x-fix-occasional-statistics-off-by-4gb-error.patch create mode 100644 queue-3.8/bonding-don-t-call-update_speed_duplex-under-spinlocks.patch create mode 100644 queue-3.8/bridge-reserve-space-for-ifla_brport_fast_leave.patch create mode 100644 queue-3.8/drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch create mode 100644 queue-3.8/inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch create mode 100644 queue-3.8/ipv4-fix-definition-of-fib_table_hashsz.patch create mode 100644 queue-3.8/net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch create mode 100644 queue-3.8/net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch create mode 100644 queue-3.8/net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch create mode 100644 queue-3.8/netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch create mode 100644 queue-3.8/revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch create mode 100644 queue-3.8/rtnetlink-mask-the-rta_type-when-range-checking.patch create mode 100644 queue-3.8/sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch create mode 100644 queue-3.8/sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch create mode 100644 queue-3.8/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch create mode 100644 queue-3.8/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch create mode 100644 queue-3.8/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch create mode 100644 queue-3.8/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch create mode 100644 queue-3.8/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch create mode 100644 queue-3.8/skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch create mode 100644 queue-3.8/tcp-dont-handle-mtu-reduction-on-listen-socket.patch create mode 100644 queue-3.8/tcp-fix-skb_availroom.patch create mode 100644 queue-3.8/tg3-5715-does-not-link-up-when-autoneg-off.patch create mode 100644 queue-3.8/vhost-net-fix-heads-usage-of-ubuf_info.patch 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 index 00000000000..64dd11d490e --- /dev/null +++ b/queue-3.8/batman-adv-verify-tt-len-does-not-exceed-packet-len.patch @@ -0,0 +1,44 @@ +From dfc8b938216b524800a183791072032a0390c2d1 Mon Sep 17 00:00:00 2001 +From: Marek Lindner +Date: Mon, 4 Mar 2013 10:39:49 +0800 +Subject: batman-adv: verify tt len does not exceed packet len + + +From: Marek Lindner + +[ 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 +Signed-off-by: Antonio Quartulli +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..bde2bc2e458 --- /dev/null +++ b/queue-3.8/bnx2x-add-missing-napi-deletion-in-error-path.patch @@ -0,0 +1,34 @@ +From 294dbeb4c43c2efcf7ebc70b2fdaa6069460b58b Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 15 Mar 2013 05:27:54 +0000 +Subject: bnx2x: add missing napi deletion in error path + + +From: Michal Schmidt + +[ 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 +Acked-by: Dmitry Kravkov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..52e07242366 --- /dev/null +++ b/queue-3.8/bnx2x-fix-occasional-statistics-off-by-4gb-error.patch @@ -0,0 +1,41 @@ +From 7b910fac0e53f21942f700796a655418408987ef Mon Sep 17 00:00:00 2001 +From: Maciej Żenczykowski +Date: Fri, 15 Mar 2013 11:56:17 +0000 +Subject: bnx2x: fix occasional statistics off-by-4GB error + + +From: Maciej Żenczykowski + +[ 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 +Cc: Mintz Yuval +Acked-by: Eilon Greenstein +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..4502e9afb93 --- /dev/null +++ b/queue-3.8/bonding-don-t-call-update_speed_duplex-under-spinlocks.patch @@ -0,0 +1,57 @@ +From 47c5adc4e53aefc315c53fc7fbeb31443fc53ccf Mon Sep 17 00:00:00 2001 +From: Veaceslav Falico +Date: Tue, 12 Mar 2013 06:31:32 +0000 +Subject: bonding: don't call update_speed_duplex() under spinlocks + + +From: Veaceslav Falico + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e4149f97137 --- /dev/null +++ b/queue-3.8/bridge-reserve-space-for-ifla_brport_fast_leave.patch @@ -0,0 +1,38 @@ +From dd483fea98c665ceda802000ec080df9ddc7a3e0 Mon Sep 17 00:00:00 2001 +From: stephen hemminger +Date: Mon, 11 Mar 2013 13:52:17 +0000 +Subject: bridge: reserve space for IFLA_BRPORT_FAST_LEAVE + + +From: stephen hemminger + +[ 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 +Date: Wed Dec 5 16:24:45 2012 -0500 + + bridge: implement multicast fast leave + +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1fe48a1ad1d --- /dev/null +++ b/queue-3.8/drivers-net-ethernet-sfc-ptp.c-adjust-duplicate-test.patch @@ -0,0 +1,52 @@ +From 1341f0cf6c27b37c1d67a1a4990883760667efbe Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Mon, 21 Jan 2013 03:02:48 +0000 +Subject: drivers/net/ethernet/sfc/ptp.c: adjust duplicate test + + +From: Julia Lawall + +[ 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/) + +// +@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 ...; } +// + +Signed-off-by: Julia Lawall +Acked-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..a81ac92828d --- /dev/null +++ b/queue-3.8/inet-limit-length-of-fragment-queue-hash-table-bucket-lists.patch @@ -0,0 +1,182 @@ +From d4d3c7d9249ba373627a09c4e9469cfe46c343a6 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Fri, 15 Mar 2013 11:32:30 +0000 +Subject: inet: limit length of fragment queue hash table bucket lists + + +From: Hannes Frederic Sowa + +[ 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 +Cc: Jesper Dangaard Brouer +Signed-off-by: Hannes Frederic Sowa +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + ++#include + #include + + 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 + #include + #include +@@ -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 + #include + #include +@@ -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 index 00000000000..8b7ff04d4c7 --- /dev/null +++ b/queue-3.8/ipv4-fix-definition-of-fib_table_hashsz.patch @@ -0,0 +1,61 @@ +From 0e7e63e4b65a06692d85f68a4111f7610e184eba Mon Sep 17 00:00:00 2001 +From: "Denis V. Lunev" +Date: Wed, 13 Mar 2013 00:24:15 +0000 +Subject: ipv4: fix definition of FIB_TABLE_HASHSZ + + +From: "Denis V. Lunev" + +[ Upstream commit 5b9e12dbf92b441b37136ea71dac59f05f2673a9 ] + +a long time ago by the commit + + commit 93456b6d7753def8760b423ac6b986eb9d5a4a95 + Author: Denis V. Lunev + 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 +CC: Tingwei Liu +CC: Alexey Kuznetsov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..14ae0f53249 --- /dev/null +++ b/queue-3.8/net-cdc_ncm-cdc_mbim-allow-user-to-prefer-ncm-for-backwards-compatibility.patch @@ -0,0 +1,146 @@ +From 10a12e57640403f617cc2bb138b9574c6317cc4a Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +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 + +[ 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 +Cc: Alexey Orishko +Reported-by: Geir Haatveit +Reported-by: Tommi Kyntola +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=54791 +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b5a4e7b32d2 --- /dev/null +++ b/queue-3.8/net-ipv4-ensure-that-location-of-timestamp-option-is-stored.patch @@ -0,0 +1,65 @@ +From c0803b42e711d49661bb1cc8e16b27de1d468fcc Mon Sep 17 00:00:00 2001 +From: David Ward +Date: Mon, 11 Mar 2013 10:43:39 +0000 +Subject: net/ipv4: Ensure that location of timestamp option is stored + + +From: David Ward + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e1acde6ed12 --- /dev/null +++ b/queue-3.8/net-qmi_wwan-set-correct-altsetting-for-gobi-1k-devices.patch @@ -0,0 +1,129 @@ +From 414280879d7c2222b06519744c03a6d2f8f2d2f4 Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +Date: Wed, 13 Mar 2013 02:25:17 +0000 +Subject: net: qmi_wwan: set correct altsetting for Gobi 1K devices + + +From: Bjørn Mork + +[ 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 +Signed-off-by: Bjørn Mork +Tested-by: Dan Williams +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b04c99106c0 --- /dev/null +++ b/queue-3.8/netconsole-don-t-call-__netpoll_cleanup-while-atomic.patch @@ -0,0 +1,58 @@ +From 27510f26c7b4b94b94b5ebd516763e948d546d3a Mon Sep 17 00:00:00 2001 +From: Veaceslav Falico +Date: Mon, 11 Mar 2013 00:21:48 +0000 +Subject: netconsole: don't call __netpoll_cleanup() while atomic + + +From: Veaceslav Falico + +[ 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 +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..86110e9d309 --- /dev/null +++ b/queue-3.8/revert-ip_gre-make-ipgre_tunnel_xmit-not-parse-network-header-as-ip-unconditionally.patch @@ -0,0 +1,42 @@ +From 9c4b1c9f8df04914afe6c1c51c9745cb8f951adc Mon Sep 17 00:00:00 2001 +From: Timo Teräs +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 + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..89e58a0df6b --- /dev/null +++ b/queue-3.8/rtnetlink-mask-the-rta_type-when-range-checking.patch @@ -0,0 +1,34 @@ +From 8e19bd050e8d9290964fa9b758fede105579ede9 Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Wed, 13 Mar 2013 04:18:58 +0000 +Subject: rtnetlink: Mask the rta_type when range checking + + +From: Vlad Yasevich + +[ 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 +Acked-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..059a44b1bf0 --- /dev/null +++ b/queue-3.8/sctp-don-t-break-the-loop-while-meeting-the-active_path-so-as-to-find-the-matched-transport.patch @@ -0,0 +1,36 @@ +From 1dd112ced7c4ef8f5e8a511d557af56e7c03b9bc Mon Sep 17 00:00:00 2001 +From: Xufeng Zhang +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 + +[ 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 +Acked-by: Neil Horman +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..6bba029db86 --- /dev/null +++ b/queue-3.8/sctp-use-correct-sideffect-command-in-duplicate-cookie-handling.patch @@ -0,0 +1,47 @@ +From a15def48d4ca2744b0f60d75f849297e660dba66 Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Tue, 12 Mar 2013 15:53:23 +0000 +Subject: sctp: Use correct sideffect command in duplicate cookie handling + + +From: Vlad Yasevich + +[ 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 +Tested-by: Karl Heiss +CC: Neil Horman +Signed-off-by: Vlad Yasevich +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 diff --git a/queue-3.8/series b/queue-3.8/series index d71ad4f3e5d..3a9178930ff 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -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 index 00000000000..2c610c48e2f --- /dev/null +++ b/queue-3.8/sfc-detach-net-device-when-stopping-queues-for-reconfiguration.patch @@ -0,0 +1,89 @@ +From f7f9a46f71e6995fb60d2ed8fabecdd9bbda1eee Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Mon, 28 Jan 2013 19:01:06 +0000 +Subject: sfc: Detach net device when stopping queues for reconfiguration + + +From: Ben Hutchings + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f08b67f0983 --- /dev/null +++ b/queue-3.8/sfc-disable-soft-interrupt-handling-during-efx_device_detach_sync.patch @@ -0,0 +1,38 @@ +From df50fed6fcae20d5523e9482d90af7094f6297d0 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Tue, 5 Mar 2013 01:03:47 +0000 +Subject: sfc: Disable soft interrupt handling during efx_device_detach_sync() + + +From: Ben Hutchings + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..d06cf4e2b50 --- /dev/null +++ b/queue-3.8/sfc-fix-efx_rx_buf_offset-in-the-presence-of-swiotlb.patch @@ -0,0 +1,91 @@ +From be254a1f0e75d7cbe7d0fae5b3424bc4849f772a Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 10 Jan 2013 23:51:54 +0000 +Subject: sfc: Fix efx_rx_buf_offset() in the presence of swiotlb + + +From: Ben Hutchings + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..843e4c2e7e4 --- /dev/null +++ b/queue-3.8/sfc-only-use-tx-push-if-a-single-descriptor-is-to-be-written.patch @@ -0,0 +1,37 @@ +From 447751edc8935bca63f3004fd0c21cda48bb5268 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b6328714c88 --- /dev/null +++ b/queue-3.8/sfc-properly-sync-rx-dma-buffer-when-it-is-not-the-last-in-the-page.patch @@ -0,0 +1,70 @@ +From 0ea6a742ceb04ede6504f1428220d3348c02f60f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..cb615027442 --- /dev/null +++ b/queue-3.8/skb-propagate-pfmemalloc-on-skb-from-head-page-only.patch @@ -0,0 +1,75 @@ +From 9faf2676b769388ac40a096c27b59fe5bee033b8 Mon Sep 17 00:00:00 2001 +From: Pavel Emelyanov +Date: Thu, 14 Mar 2013 03:29:40 +0000 +Subject: skb: Propagate pfmemalloc on skb from head page only + + +From: Pavel Emelyanov + +[ 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 +Acked-by: Eric Dumazet +Acked-by: Mel Gorman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..d22f62688a1 --- /dev/null +++ b/queue-3.8/tcp-dont-handle-mtu-reduction-on-listen-socket.patch @@ -0,0 +1,84 @@ +From c250387a8e1fb7181357c9f8cd6ed02230ec3e9e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 18 Mar 2013 07:01:28 +0000 +Subject: tcp: dont handle MTU reduction on LISTEN socket + + +From: Eric Dumazet + +[ 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 +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1c6344f1bd9 --- /dev/null +++ b/queue-3.8/tcp-fix-skb_availroom.patch @@ -0,0 +1,78 @@ +From 2cbf892200d0d5bdc8e97ca8cfe6277c6f2a8ee2 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 14 Mar 2013 05:40:32 +0000 +Subject: tcp: fix skb_availroom() + + +From: Eric Dumazet + +[ 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 +Reported-by: Mukesh Agrawal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ee4f76c014a --- /dev/null +++ b/queue-3.8/tg3-5715-does-not-link-up-when-autoneg-off.patch @@ -0,0 +1,49 @@ +From 2dc8507fe1064bfc04e1aa80dac3938fa78c3e6e Mon Sep 17 00:00:00 2001 +From: Nithin Sujir +Date: Tue, 12 Mar 2013 15:32:48 +0000 +Subject: tg3: 5715 does not link up when autoneg off + + +From: Nithin Sujir + +[ 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 +Reviewed-by: Benjamin Li +Signed-off-by: Nithin Nayak Sujir +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e9e91f4e746 --- /dev/null +++ b/queue-3.8/vhost-net-fix-heads-usage-of-ubuf_info.patch @@ -0,0 +1,36 @@ +From fbec7a71b74231de6efb567e5cb4e37e89d75f84 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 17 Mar 2013 02:46:09 +0000 +Subject: vhost/net: fix heads usage of ubuf_info + + +From: "Michael S. Tsirkin" + +[ 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 +Signed-off-by: Michael S. Tsirkin +Cc: stable@kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; -- 2.47.3