]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 17:58:42 +0000 (09:58 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 17:58:42 +0000 (09:58 -0800)
added patches:
arc_emac-fix-potential-use-after-free.patch
arm-7923-1-mm-fix-dcache-flush-logic-for-compound-high-pages.patch
arm-fix-bad-mode-in-...-handler-message-for-undefined-instructions.patch
arm-fix-footbridge-clockevent-device.patch
bridge-use-spin_lock_bh-in-br_multicast_set_hash_max.patch
drivers-net-hamradio-integer-overflow-in-hdlcdrv_ioctl.patch
hamradio-yam-fix-info-leak-in-ioctl.patch
ip_gre-fix-msg_name-parsing-for-recvfrom-recvmsg.patch
ipv4-fix-tunneled-vm-traffic-over-hw-vxlan-gre-gso-nic.patch
ipv6-always-set-the-new-created-dst-s-from-in-ip6_rt_copy.patch
ipv6-fix-illegal-mac_header-comparison-on-32bit.patch
net-fec-fix-potential-use-after-free.patch
net-inet_diag-zero-out-uninitialized-idiag_-src-dst-fields.patch
net-llc-fix-use-after-free-in-llc_ui_recvmsg.patch
net-rose-restore-old-recvmsg-behavior.patch
net-unix-allow-bind-to-fail-on-mutex-lock.patch
net-unix-allow-set_peek_off-to-fail.patch
netpoll-fix-missing-txq-unlock-and-and-oops.patch
netvsc-don-t-flush-peers-notifying-work-during-setting-mtu.patch
rds-prevent-dereference-of-a-null-device.patch
sfc-add-length-checks-to-efx_xmit_with_hwtstamp-and-efx_ptp_is_ptp_tx.patch
sfc-maintain-current-frequency-adjustment-when-applying-a-time-offset.patch
sfc-poll-for-mcdi-completion-once-before-timeout-occurs.patch
sfc-ptp-moderate-log-message-on-event-queue-overflow.patch
sfc-rate-limit-log-message-for-ptp-packets-without-a-matching-timestamp-event.patch
sfc-refactor-efx_mcdi_poll-by-introducing-efx_mcdi_poll_once.patch
sfc-rx-buffer-allocation-takes-prefix-size-into-account-in-ip-header-alignment.patch
sfc-stop-re-start-ptp-when-stopping-starting-the-datapath.patch
tg3-initialize-reg_base_addr-at-pci-config-offset-120-to-0.patch
virtio-net-fix-refill-races-during-restore.patch
virtio-net-make-all-rx-paths-handle-errors.patch
virtio_net-don-t-leak-memory-or-block-when-too-many-frags.patch
virtio_net-fix-error-handling-for-mergeable-buffers.patch
vlan-fix-header-ops-passthru-when-doing-tx-vlan-offload.patch
vxlan-release-rt-when-found-circular-route.patch

36 files changed:
queue-3.12/arc_emac-fix-potential-use-after-free.patch [new file with mode: 0644]
queue-3.12/arm-7923-1-mm-fix-dcache-flush-logic-for-compound-high-pages.patch [new file with mode: 0644]
queue-3.12/arm-fix-bad-mode-in-...-handler-message-for-undefined-instructions.patch [new file with mode: 0644]
queue-3.12/arm-fix-footbridge-clockevent-device.patch [new file with mode: 0644]
queue-3.12/bridge-use-spin_lock_bh-in-br_multicast_set_hash_max.patch [new file with mode: 0644]
queue-3.12/drivers-net-hamradio-integer-overflow-in-hdlcdrv_ioctl.patch [new file with mode: 0644]
queue-3.12/hamradio-yam-fix-info-leak-in-ioctl.patch [new file with mode: 0644]
queue-3.12/ip_gre-fix-msg_name-parsing-for-recvfrom-recvmsg.patch [new file with mode: 0644]
queue-3.12/ipv4-fix-tunneled-vm-traffic-over-hw-vxlan-gre-gso-nic.patch [new file with mode: 0644]
queue-3.12/ipv6-always-set-the-new-created-dst-s-from-in-ip6_rt_copy.patch [new file with mode: 0644]
queue-3.12/ipv6-fix-illegal-mac_header-comparison-on-32bit.patch [new file with mode: 0644]
queue-3.12/net-fec-fix-potential-use-after-free.patch [new file with mode: 0644]
queue-3.12/net-inet_diag-zero-out-uninitialized-idiag_-src-dst-fields.patch [new file with mode: 0644]
queue-3.12/net-llc-fix-use-after-free-in-llc_ui_recvmsg.patch [new file with mode: 0644]
queue-3.12/net-rose-restore-old-recvmsg-behavior.patch [new file with mode: 0644]
queue-3.12/net-unix-allow-bind-to-fail-on-mutex-lock.patch [new file with mode: 0644]
queue-3.12/net-unix-allow-set_peek_off-to-fail.patch [new file with mode: 0644]
queue-3.12/netpoll-fix-missing-txq-unlock-and-and-oops.patch [new file with mode: 0644]
queue-3.12/netvsc-don-t-flush-peers-notifying-work-during-setting-mtu.patch [new file with mode: 0644]
queue-3.12/rds-prevent-dereference-of-a-null-device.patch [new file with mode: 0644]
queue-3.12/series
queue-3.12/sfc-add-length-checks-to-efx_xmit_with_hwtstamp-and-efx_ptp_is_ptp_tx.patch [new file with mode: 0644]
queue-3.12/sfc-maintain-current-frequency-adjustment-when-applying-a-time-offset.patch [new file with mode: 0644]
queue-3.12/sfc-poll-for-mcdi-completion-once-before-timeout-occurs.patch [new file with mode: 0644]
queue-3.12/sfc-ptp-moderate-log-message-on-event-queue-overflow.patch [new file with mode: 0644]
queue-3.12/sfc-rate-limit-log-message-for-ptp-packets-without-a-matching-timestamp-event.patch [new file with mode: 0644]
queue-3.12/sfc-refactor-efx_mcdi_poll-by-introducing-efx_mcdi_poll_once.patch [new file with mode: 0644]
queue-3.12/sfc-rx-buffer-allocation-takes-prefix-size-into-account-in-ip-header-alignment.patch [new file with mode: 0644]
queue-3.12/sfc-stop-re-start-ptp-when-stopping-starting-the-datapath.patch [new file with mode: 0644]
queue-3.12/tg3-initialize-reg_base_addr-at-pci-config-offset-120-to-0.patch [new file with mode: 0644]
queue-3.12/virtio-net-fix-refill-races-during-restore.patch [new file with mode: 0644]
queue-3.12/virtio-net-make-all-rx-paths-handle-errors.patch [new file with mode: 0644]
queue-3.12/virtio_net-don-t-leak-memory-or-block-when-too-many-frags.patch [new file with mode: 0644]
queue-3.12/virtio_net-fix-error-handling-for-mergeable-buffers.patch [new file with mode: 0644]
queue-3.12/vlan-fix-header-ops-passthru-when-doing-tx-vlan-offload.patch [new file with mode: 0644]
queue-3.12/vxlan-release-rt-when-found-circular-route.patch [new file with mode: 0644]

diff --git a/queue-3.12/arc_emac-fix-potential-use-after-free.patch b/queue-3.12/arc_emac-fix-potential-use-after-free.patch
new file mode 100644 (file)
index 0000000..3df3c3d
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Thu, 19 Dec 2013 18:10:40 -0800
+Subject: arc_emac: fix potential use after free
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 37ec274e9713eafc2ba6c4471420f06cb8f68ecf ]
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+
+skb_tx_timestamp(skb) should be called _before_ TX completion
+has a chance to trigger, otherwise it is too late and we access
+freed memory.
+
+Fixes: e4f2379db6c6 ("ethernet/arc/arc_emac - Add new driver")
+From: Eric Dumazet <edumazet@google.com>
+Cc: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/arc/emac_main.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/arc/emac_main.c
++++ b/drivers/net/ethernet/arc/emac_main.c
+@@ -565,6 +565,8 @@ static int arc_emac_tx(struct sk_buff *s
+       /* Make sure pointer to data buffer is set */
+       wmb();
++      skb_tx_timestamp(skb);
++
+       *info = cpu_to_le32(FOR_EMAC | FIRST_OR_LAST_MASK | len);
+       /* Increment index to point to the next BD */
+@@ -579,8 +581,6 @@ static int arc_emac_tx(struct sk_buff *s
+       arc_reg_set(priv, R_STATUS, TXPL_MASK);
+-      skb_tx_timestamp(skb);
+-
+       return NETDEV_TX_OK;
+ }
diff --git a/queue-3.12/arm-7923-1-mm-fix-dcache-flush-logic-for-compound-high-pages.patch b/queue-3.12/arm-7923-1-mm-fix-dcache-flush-logic-for-compound-high-pages.patch
new file mode 100644 (file)
index 0000000..57d6357
--- /dev/null
@@ -0,0 +1,50 @@
+From 2a7cfcbc0553365d75716f69ee7b704cac7c9248 Mon Sep 17 00:00:00 2001
+From: Steven Capper <steve.capper@linaro.org>
+Date: Mon, 16 Dec 2013 17:25:52 +0100
+Subject: ARM: 7923/1: mm: fix dcache flush logic for compound high pages
+
+From: Steven Capper <steve.capper@linaro.org>
+
+commit 2a7cfcbc0553365d75716f69ee7b704cac7c9248 upstream.
+
+When given a compound high page, __flush_dcache_page will only flush
+the first page of the compound page repeatedly rather than the entire
+set of constituent pages.
+
+This error was introduced by:
+   0b19f93 ARM: mm: Add support for flushing HugeTLB pages.
+
+This patch corrects the logic such that all constituent pages are now
+flushed.
+
+Signed-off-by: Steve Capper <steve.capper@linaro.org>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mm/flush.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/mm/flush.c
++++ b/arch/arm/mm/flush.c
+@@ -175,16 +175,16 @@ void __flush_dcache_page(struct address_
+               unsigned long i;
+               if (cache_is_vipt_nonaliasing()) {
+                       for (i = 0; i < (1 << compound_order(page)); i++) {
+-                              void *addr = kmap_atomic(page);
++                              void *addr = kmap_atomic(page + i);
+                               __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                               kunmap_atomic(addr);
+                       }
+               } else {
+                       for (i = 0; i < (1 << compound_order(page)); i++) {
+-                              void *addr = kmap_high_get(page);
++                              void *addr = kmap_high_get(page + i);
+                               if (addr) {
+                                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+-                                      kunmap_high(page);
++                                      kunmap_high(page + i);
+                               }
+                       }
+               }
diff --git a/queue-3.12/arm-fix-bad-mode-in-...-handler-message-for-undefined-instructions.patch b/queue-3.12/arm-fix-bad-mode-in-...-handler-message-for-undefined-instructions.patch
new file mode 100644 (file)
index 0000000..16c1a8f
--- /dev/null
@@ -0,0 +1,36 @@
+From 29c350bf28da333e41e30497b649fe335712a2ab Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Fri, 3 Jan 2014 15:01:39 +0000
+Subject: ARM: fix "bad mode in ... handler" message for undefined instructions
+
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+
+commit 29c350bf28da333e41e30497b649fe335712a2ab upstream.
+
+The array was missing the final entry for the undefined instruction
+exception handler; this commit adds it.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kernel/traps.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -35,7 +35,13 @@
+ #include <asm/tls.h>
+ #include <asm/system_misc.h>
+-static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
++static const char *handler[]= {
++      "prefetch abort",
++      "data abort",
++      "address exception",
++      "interrupt",
++      "undefined instruction",
++};
+ void *vectors_page;
diff --git a/queue-3.12/arm-fix-footbridge-clockevent-device.patch b/queue-3.12/arm-fix-footbridge-clockevent-device.patch
new file mode 100644 (file)
index 0000000..51dca5c
--- /dev/null
@@ -0,0 +1,39 @@
+From 4ff859fe1dc0da0f87bbdfff78f527898878fa4a Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sun, 29 Dec 2013 12:39:50 +0000
+Subject: ARM: fix footbridge clockevent device
+
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+
+commit 4ff859fe1dc0da0f87bbdfff78f527898878fa4a upstream.
+
+The clockevents code was being told that the footbridge clock event
+device ticks at 16x the rate which it actually does.  This leads to
+timekeeping problems since it allows the clocksource to wrap before
+the kernel notices.  Fix this by using the correct clock.
+
+Fixes: 4e8d76373c9fd ("ARM: footbridge: convert to clockevents/clocksource")
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-footbridge/dc21285-timer.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/mach-footbridge/dc21285-timer.c
++++ b/arch/arm/mach-footbridge/dc21285-timer.c
+@@ -96,11 +96,12 @@ static struct irqaction footbridge_timer
+ void __init footbridge_timer_init(void)
+ {
+       struct clock_event_device *ce = &ckevt_dc21285;
++      unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
+-      clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16);
++      clocksource_register_hz(&cksrc_dc21285, rate);
+       setup_irq(ce->irq, &footbridge_timer_irq);
+       ce->cpumask = cpumask_of(smp_processor_id());
+-      clockevents_config_and_register(ce, mem_fclk_21285, 0x4, 0xffffff);
++      clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
+ }
diff --git a/queue-3.12/bridge-use-spin_lock_bh-in-br_multicast_set_hash_max.patch b/queue-3.12/bridge-use-spin_lock_bh-in-br_multicast_set_hash_max.patch
new file mode 100644 (file)
index 0000000..93c7f9e
--- /dev/null
@@ -0,0 +1,63 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Curt Brune <curt@cumulusnetworks.com>
+Date: Mon, 6 Jan 2014 11:00:32 -0800
+Subject: bridge: use spin_lock_bh() in br_multicast_set_hash_max
+
+From: Curt Brune <curt@cumulusnetworks.com>
+
+[ Upstream commit fe0d692bbc645786bce1a98439e548ae619269f5 ]
+
+br_multicast_set_hash_max() is called from process context in
+net/bridge/br_sysfs_br.c by the sysfs store_hash_max() function.
+
+br_multicast_set_hash_max() calls spin_lock(&br->multicast_lock),
+which can deadlock the CPU if a softirq that also tries to take the
+same lock interrupts br_multicast_set_hash_max() while the lock is
+held .  This can happen quite easily when any of the bridge multicast
+timers expire, which try to take the same lock.
+
+The fix here is to use spin_lock_bh(), preventing other softirqs from
+executing on this CPU.
+
+Steps to reproduce:
+
+1. Create a bridge with several interfaces (I used 4).
+2. Set the "multicast query interval" to a low number, like 2.
+3. Enable the bridge as a multicast querier.
+4. Repeatedly set the bridge hash_max parameter via sysfs.
+
+  # brctl addbr br0
+  # brctl addif br0 eth1 eth2 eth3 eth4
+  # brctl setmcqi br0 2
+  # brctl setmcquerier br0 1
+
+  # while true ; do echo 4096 > /sys/class/net/br0/bridge/hash_max; done
+
+Signed-off-by: Curt Brune <curt@cumulusnetworks.com>
+Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_multicast.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -2004,7 +2004,7 @@ int br_multicast_set_hash_max(struct net
+       u32 old;
+       struct net_bridge_mdb_htable *mdb;
+-      spin_lock(&br->multicast_lock);
++      spin_lock_bh(&br->multicast_lock);
+       if (!netif_running(br->dev))
+               goto unlock;
+@@ -2036,7 +2036,7 @@ rollback:
+       }
+ unlock:
+-      spin_unlock(&br->multicast_lock);
++      spin_unlock_bh(&br->multicast_lock);
+       return err;
+ }
diff --git a/queue-3.12/drivers-net-hamradio-integer-overflow-in-hdlcdrv_ioctl.patch b/queue-3.12/drivers-net-hamradio-integer-overflow-in-hdlcdrv_ioctl.patch
new file mode 100644 (file)
index 0000000..6756dfc
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Wenliang Fan <fanwlexca@gmail.com>
+Date: Tue, 17 Dec 2013 11:25:28 +0800
+Subject: drivers/net/hamradio: Integer overflow in hdlcdrv_ioctl()
+
+From: Wenliang Fan <fanwlexca@gmail.com>
+
+[ Upstream commit e9db5c21d3646a6454fcd04938dd215ac3ab620a ]
+
+The local variable 'bi' comes from userspace. If userspace passed a
+large number to 'bi.data.calibrate', there would be an integer overflow
+in the following line:
+       s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
+
+Signed-off-by: Wenliang Fan <fanwlexca@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hamradio/hdlcdrv.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/hamradio/hdlcdrv.c
++++ b/drivers/net/hamradio/hdlcdrv.c
+@@ -571,6 +571,8 @@ static int hdlcdrv_ioctl(struct net_devi
+       case HDLCDRVCTL_CALIBRATE:
+               if(!capable(CAP_SYS_RAWIO))
+                       return -EPERM;
++              if (bi.data.calibrate > INT_MAX / s->par.bitrate)
++                      return -EINVAL;
+               s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
+               return 0;
diff --git a/queue-3.12/hamradio-yam-fix-info-leak-in-ioctl.patch b/queue-3.12/hamradio-yam-fix-info-leak-in-ioctl.patch
new file mode 100644 (file)
index 0000000..7a8eb82
--- /dev/null
@@ -0,0 +1,33 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: =?UTF-8?q?Salva=20Peir=C3=B3?= <speiro@ai2.upv.es>
+Date: Tue, 17 Dec 2013 10:06:30 +0100
+Subject: hamradio/yam: fix info leak in ioctl
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Salva Peiró <speiro@ai2.upv.es>
+
+[ Upstream commit 8e3fbf870481eb53b2d3a322d1fc395ad8b367ed ]
+
+The yam_ioctl() code fails to initialise the cmd field
+of the struct yamdrv_ioctl_cfg. Add an explicit memset(0)
+before filling the structure to avoid the 4-byte info leak.
+
+Signed-off-by: Salva Peiró <speiro@ai2.upv.es>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hamradio/yam.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/hamradio/yam.c
++++ b/drivers/net/hamradio/yam.c
+@@ -1057,6 +1057,7 @@ static int yam_ioctl(struct net_device *
+               break;
+       case SIOCYAMGCFG:
++              memset(&yi, 0, sizeof(yi));
+               yi.cfg.mask = 0xffffffff;
+               yi.cfg.iobase = yp->iobase;
+               yi.cfg.irq = yp->irq;
diff --git a/queue-3.12/ip_gre-fix-msg_name-parsing-for-recvfrom-recvmsg.patch b/queue-3.12/ip_gre-fix-msg_name-parsing-for-recvfrom-recvmsg.patch
new file mode 100644 (file)
index 0000000..e4547a5
--- /dev/null
@@ -0,0 +1,53 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Mon, 16 Dec 2013 11:02:09 +0200
+Subject: ip_gre: fix msg_name parsing for recvfrom/recvmsg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timo Teräs <timo.teras@iki.fi>
+
+[ Upstream commit 0e3da5bb8da45890b1dc413404e0f978ab71173e ]
+
+ipgre_header_parse() needs to parse the tunnel's ip header and it
+uses mac_header to locate the iphdr. This got broken when gre tunneling
+was refactored as mac_header is no longer updated to point to iphdr.
+Introduce skb_pop_mac_header() helper to do the mac_header assignment
+and use it in ipgre_rcv() to fix msg_name parsing.
+
+Bug introduced in commit c54419321455 (GRE: Refactor GRE tunneling code.)
+
+Cc: Pravin B Shelar <pshelar@nicira.com>
+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>
+---
+ include/linux/skbuff.h |    5 +++++
+ net/ipv4/ip_gre.c      |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1638,6 +1638,11 @@ static inline void skb_set_mac_header(st
+       skb->mac_header += offset;
+ }
++static inline void skb_pop_mac_header(struct sk_buff *skb)
++{
++      skb->mac_header = skb->network_header;
++}
++
+ static inline void skb_probe_transport_header(struct sk_buff *skb,
+                                             const int offset_hint)
+ {
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -217,6 +217,7 @@ static int ipgre_rcv(struct sk_buff *skb
+                                 iph->saddr, iph->daddr, tpi->key);
+       if (tunnel) {
++              skb_pop_mac_header(skb);
+               ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error);
+               return PACKET_RCVD;
+       }
diff --git a/queue-3.12/ipv4-fix-tunneled-vm-traffic-over-hw-vxlan-gre-gso-nic.patch b/queue-3.12/ipv4-fix-tunneled-vm-traffic-over-hw-vxlan-gre-gso-nic.patch
new file mode 100644 (file)
index 0000000..0f97081
--- /dev/null
@@ -0,0 +1,177 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Wei-Chun Chao <weichunc@plumgrid.com>
+Date: Thu, 26 Dec 2013 13:10:22 -0800
+Subject: ipv4: fix tunneled VM traffic over hw VXLAN/GRE GSO NIC
+
+From: Wei-Chun Chao <weichunc@plumgrid.com>
+
+[ Upstream commit 7a7ffbabf99445704be01bff5d7e360da908cf8e ]
+
+VM to VM GSO traffic is broken if it goes through VXLAN or GRE
+tunnel and the physical NIC on the host supports hardware VXLAN/GRE
+GSO offload (e.g. bnx2x and next-gen mlx4).
+
+Two issues -
+(VXLAN) VM traffic has SKB_GSO_DODGY and SKB_GSO_UDP_TUNNEL with
+SKB_GSO_TCP/UDP set depending on the inner protocol. GSO header
+integrity check fails in udp4_ufo_fragment if inner protocol is
+TCP. Also gso_segs is calculated incorrectly using skb->len that
+includes tunnel header. Fix: robust check should only be applied
+to the inner packet.
+
+(VXLAN & GRE) Once GSO header integrity check passes, NULL segs
+is returned and the original skb is sent to hardware. However the
+tunnel header is already pulled. Fix: tunnel header needs to be
+restored so that hardware can perform GSO properly on the original
+packet.
+
+Signed-off-by: Wei-Chun Chao <weichunc@plumgrid.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/netdevice.h |   13 +++++++++++++
+ net/ipv4/gre_offload.c    |   11 +++++++----
+ net/ipv4/udp.c            |    6 +++++-
+ net/ipv4/udp_offload.c    |   37 +++++++++++++++++++------------------
+ 4 files changed, 44 insertions(+), 23 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2954,6 +2954,19 @@ static inline void netif_set_gso_max_siz
+       dev->gso_max_size = size;
+ }
++static inline void skb_gso_error_unwind(struct sk_buff *skb, __be16 protocol,
++                                      int pulled_hlen, u16 mac_offset,
++                                      int mac_len)
++{
++      skb->protocol = protocol;
++      skb->encapsulation = 1;
++      skb_push(skb, pulled_hlen);
++      skb_reset_transport_header(skb);
++      skb->mac_header = mac_offset;
++      skb->network_header = skb->mac_header + mac_len;
++      skb->mac_len = mac_len;
++}
++
+ static inline bool netif_is_bond_master(struct net_device *dev)
+ {
+       return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING;
+--- a/net/ipv4/gre_offload.c
++++ b/net/ipv4/gre_offload.c
+@@ -28,6 +28,7 @@ static struct sk_buff *gre_gso_segment(s
+       netdev_features_t enc_features;
+       int ghl = GRE_HEADER_SECTION;
+       struct gre_base_hdr *greh;
++      u16 mac_offset = skb->mac_header;
+       int mac_len = skb->mac_len;
+       __be16 protocol = skb->protocol;
+       int tnl_hlen;
+@@ -57,13 +58,13 @@ static struct sk_buff *gre_gso_segment(s
+       } else
+               csum = false;
++      if (unlikely(!pskb_may_pull(skb, ghl)))
++              goto out;
++
+       /* setup inner skb. */
+       skb->protocol = greh->protocol;
+       skb->encapsulation = 0;
+-      if (unlikely(!pskb_may_pull(skb, ghl)))
+-              goto out;
+-
+       __skb_pull(skb, ghl);
+       skb_reset_mac_header(skb);
+       skb_set_network_header(skb, skb_inner_network_offset(skb));
+@@ -72,8 +73,10 @@ static struct sk_buff *gre_gso_segment(s
+       /* segment inner packet. */
+       enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
+       segs = skb_mac_gso_segment(skb, enc_features);
+-      if (!segs || IS_ERR(segs))
++      if (!segs || IS_ERR(segs)) {
++              skb_gso_error_unwind(skb, protocol, ghl, mac_offset, mac_len);
+               goto out;
++      }
+       skb = segs;
+       tnl_hlen = skb_tnl_header_len(skb);
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2294,6 +2294,7 @@ struct sk_buff *skb_udp_tunnel_segment(s
+                                      netdev_features_t features)
+ {
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
++      u16 mac_offset = skb->mac_header;
+       int mac_len = skb->mac_len;
+       int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
+       __be16 protocol = skb->protocol;
+@@ -2313,8 +2314,11 @@ struct sk_buff *skb_udp_tunnel_segment(s
+       /* segment inner packet. */
+       enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
+       segs = skb_mac_gso_segment(skb, enc_features);
+-      if (!segs || IS_ERR(segs))
++      if (!segs || IS_ERR(segs)) {
++              skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
++                                   mac_len);
+               goto out;
++      }
+       outer_hlen = skb_tnl_header_len(skb);
+       skb = segs;
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -41,6 +41,14 @@ static struct sk_buff *udp4_ufo_fragment
+ {
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       unsigned int mss;
++      int offset;
++      __wsum csum;
++
++      if (skb->encapsulation &&
++          skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
++              segs = skb_udp_tunnel_segment(skb, features);
++              goto out;
++      }
+       mss = skb_shinfo(skb)->gso_size;
+       if (unlikely(skb->len <= mss))
+@@ -62,27 +70,20 @@ static struct sk_buff *udp4_ufo_fragment
+               goto out;
+       }
++      /* Do software UFO. Complete and fill in the UDP checksum as
++       * HW cannot do checksum of UDP packets sent as multiple
++       * IP fragments.
++       */
++      offset = skb_checksum_start_offset(skb);
++      csum = skb_checksum(skb, offset, skb->len - offset, 0);
++      offset += skb->csum_offset;
++      *(__sum16 *)(skb->data + offset) = csum_fold(csum);
++      skb->ip_summed = CHECKSUM_NONE;
++
+       /* Fragment the skb. IP headers of the fragments are updated in
+        * inet_gso_segment()
+        */
+-      if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL)
+-              segs = skb_udp_tunnel_segment(skb, features);
+-      else {
+-              int offset;
+-              __wsum csum;
+-
+-              /* Do software UFO. Complete and fill in the UDP checksum as
+-               * HW cannot do checksum of UDP packets sent as multiple
+-               * IP fragments.
+-               */
+-              offset = skb_checksum_start_offset(skb);
+-              csum = skb_checksum(skb, offset, skb->len - offset, 0);
+-              offset += skb->csum_offset;
+-              *(__sum16 *)(skb->data + offset) = csum_fold(csum);
+-              skb->ip_summed = CHECKSUM_NONE;
+-
+-              segs = skb_segment(skb, features);
+-      }
++      segs = skb_segment(skb, features);
+ out:
+       return segs;
+ }
diff --git a/queue-3.12/ipv6-always-set-the-new-created-dst-s-from-in-ip6_rt_copy.patch b/queue-3.12/ipv6-always-set-the-new-created-dst-s-from-in-ip6_rt_copy.patch
new file mode 100644 (file)
index 0000000..227a2b1
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Thu, 19 Dec 2013 12:40:26 +0800
+Subject: ipv6: always set the new created dst's from in ip6_rt_copy
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ Upstream commit 24f5b855e17df7e355eacd6c4a12cc4d6a6c9ff0 ]
+
+ip6_rt_copy only sets dst.from if ort has flag RTF_ADDRCONF and RTF_DEFAULT.
+but the prefix routes which did get installed by hand locally can have an
+expiration, and no any flag combination which can ensure a potential from
+does never expire, so we should always set the new created dst's from.
+
+This also fixes the new created dst is always expired since the ort, which
+is created by RA, maybe has RTF_EXPIRES and RTF_ADDRCONF, but no RTF_DEFAULT.
+
+Suggested-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+CC: Gao feng <gaofeng@cn.fujitsu.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1910,9 +1910,7 @@ static struct rt6_info *ip6_rt_copy(stru
+               else
+                       rt->rt6i_gateway = *dest;
+               rt->rt6i_flags = ort->rt6i_flags;
+-              if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
+-                  (RTF_DEFAULT | RTF_ADDRCONF))
+-                      rt6_set_from(rt, ort);
++              rt6_set_from(rt, ort);
+               rt->rt6i_metric = 0;
+ #ifdef CONFIG_IPV6_SUBTREES
diff --git a/queue-3.12/ipv6-fix-illegal-mac_header-comparison-on-32bit.patch b/queue-3.12/ipv6-fix-illegal-mac_header-comparison-on-32bit.patch
new file mode 100644 (file)
index 0000000..da8fae6
--- /dev/null
@@ -0,0 +1,25 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Fri, 13 Dec 2013 15:12:27 +0100
+Subject: ipv6: fix illegal mac_header comparison on 32bit
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/udp_offload.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/udp_offload.c
++++ b/net/ipv6/udp_offload.c
+@@ -88,7 +88,7 @@ static struct sk_buff *udp6_ufo_fragment
+               /* Check if there is enough headroom to insert fragment header. */
+               tnl_hlen = skb_tnl_header_len(skb);
+-              if (skb->mac_header < (tnl_hlen + frag_hdr_sz)) {
++              if (skb_mac_header(skb) < skb->head + tnl_hlen + frag_hdr_sz) {
+                       if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
+                               goto out;
+               }
diff --git a/queue-3.12/net-fec-fix-potential-use-after-free.patch b/queue-3.12/net-fec-fix-potential-use-after-free.patch
new file mode 100644 (file)
index 0000000..15e0bc1
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 19 Dec 2013 10:53:02 -0800
+Subject: net: fec: fix potential use after free
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7a2a84518cfb263d2c4171b3d63671f88316adb2 ]
+
+skb_tx_timestamp(skb) should be called _before_ TX completion
+has a chance to trigger, otherwise it is too late and we access
+freed memory.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Fixes: de5fb0a05348 ("net: fec: put tx to napi poll function to fix dead lock")
+Cc: Frank Li <Frank.Li@freescale.com>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Acked-by: Frank Li <Frank.Li@freescale.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -425,6 +425,8 @@ fec_enet_start_xmit(struct sk_buff *skb,
+       /* If this was the last BD in the ring, start at the beginning again. */
+       bdp = fec_enet_get_nextdesc(bdp, fep);
++      skb_tx_timestamp(skb);
++
+       fep->cur_tx = bdp;
+       if (fep->cur_tx == fep->dirty_tx)
+@@ -433,8 +435,6 @@ fec_enet_start_xmit(struct sk_buff *skb,
+       /* Trigger transmission start */
+       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
+-      skb_tx_timestamp(skb);
+-
+       return NETDEV_TX_OK;
+ }
diff --git a/queue-3.12/net-inet_diag-zero-out-uninitialized-idiag_-src-dst-fields.patch b/queue-3.12/net-inet_diag-zero-out-uninitialized-idiag_-src-dst-fields.patch
new file mode 100644 (file)
index 0000000..b770ef8
--- /dev/null
@@ -0,0 +1,88 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Tue, 17 Dec 2013 00:38:39 +0100
+Subject: net: inet_diag: zero out uninitialized idiag_{src,dst} fields
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit b1aac815c0891fe4a55a6b0b715910142227700f ]
+
+Jakub reported while working with nlmon netlink sniffer that parts of
+the inet_diag_sockid are not initialized when r->idiag_family != AF_INET6.
+That is, fields of r->id.idiag_src[1 ... 3], r->id.idiag_dst[1 ... 3].
+
+In fact, it seems that we can leak 6 * sizeof(u32) byte of kernel [slab]
+memory through this. At least, in udp_dump_one(), we allocate a skb in ...
+
+  rep = nlmsg_new(sizeof(struct inet_diag_msg) + ..., GFP_KERNEL);
+
+... and then pass that to inet_sk_diag_fill() that puts the whole struct
+inet_diag_msg into the skb, where we only fill out r->id.idiag_src[0],
+r->id.idiag_dst[0] and leave the rest untouched:
+
+  r->id.idiag_src[0] = inet->inet_rcv_saddr;
+  r->id.idiag_dst[0] = inet->inet_daddr;
+
+struct inet_diag_msg embeds struct inet_diag_sockid that is correctly /
+fully filled out in IPv6 case, but for IPv4 not.
+
+So just zero them out by using plain memset (for this little amount of
+bytes it's probably not worth the extra check for idiag_family == AF_INET).
+
+Similarly, fix also other places where we fill that out.
+
+Reported-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_diag.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -106,6 +106,10 @@ int inet_sk_diag_fill(struct sock *sk, s
+       r->id.idiag_sport = inet->inet_sport;
+       r->id.idiag_dport = inet->inet_dport;
++
++      memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
++      memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
++
+       r->id.idiag_src[0] = inet->inet_rcv_saddr;
+       r->id.idiag_dst[0] = inet->inet_daddr;
+@@ -240,12 +244,19 @@ static int inet_twsk_diag_fill(struct in
+       r->idiag_family       = tw->tw_family;
+       r->idiag_retrans      = 0;
++
+       r->id.idiag_if        = tw->tw_bound_dev_if;
+       sock_diag_save_cookie(tw, r->id.idiag_cookie);
++
+       r->id.idiag_sport     = tw->tw_sport;
+       r->id.idiag_dport     = tw->tw_dport;
++
++      memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
++      memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
++
+       r->id.idiag_src[0]    = tw->tw_rcv_saddr;
+       r->id.idiag_dst[0]    = tw->tw_daddr;
++
+       r->idiag_state        = tw->tw_substate;
+       r->idiag_timer        = 3;
+       r->idiag_expires      = DIV_ROUND_UP(tmo * 1000, HZ);
+@@ -732,8 +743,13 @@ static int inet_diag_fill_req(struct sk_
+       r->id.idiag_sport = inet->inet_sport;
+       r->id.idiag_dport = ireq->rmt_port;
++
++      memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
++      memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
++
+       r->id.idiag_src[0] = ireq->loc_addr;
+       r->id.idiag_dst[0] = ireq->rmt_addr;
++
+       r->idiag_expires = jiffies_to_msecs(tmo);
+       r->idiag_rqueue = 0;
+       r->idiag_wqueue = 0;
diff --git a/queue-3.12/net-llc-fix-use-after-free-in-llc_ui_recvmsg.patch b/queue-3.12/net-llc-fix-use-after-free-in-llc_ui_recvmsg.patch
new file mode 100644 (file)
index 0000000..eb97845
--- /dev/null
@@ -0,0 +1,65 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Mon, 30 Dec 2013 23:40:50 +0100
+Subject: net: llc: fix use after free in llc_ui_recvmsg
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit 4d231b76eef6c4a6bd9c96769e191517765942cb ]
+
+While commit 30a584d944fb fixes datagram interface in LLC, a use
+after free bug has been introduced for SOCK_STREAM sockets that do
+not make use of MSG_PEEK.
+
+The flow is as follow ...
+
+  if (!(flags & MSG_PEEK)) {
+    ...
+    sk_eat_skb(sk, skb, false);
+    ...
+  }
+  ...
+  if (used + offset < skb->len)
+    continue;
+
+... where sk_eat_skb() calls __kfree_skb(). Therefore, cache
+original length and work on skb_len to check partial reads.
+
+Fixes: 30a584d944fb ("[LLX]: SOCK_DGRAM interface fixes")
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Cc: Stephen Hemminger <stephen@networkplumber.org>
+Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/llc/af_llc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -715,7 +715,7 @@ static int llc_ui_recvmsg(struct kiocb *
+       unsigned long cpu_flags;
+       size_t copied = 0;
+       u32 peek_seq = 0;
+-      u32 *seq;
++      u32 *seq, skb_len;
+       unsigned long used;
+       int target;     /* Read at least this many bytes */
+       long timeo;
+@@ -812,6 +812,7 @@ static int llc_ui_recvmsg(struct kiocb *
+               }
+               continue;
+       found_ok_skb:
++              skb_len = skb->len;
+               /* Ok so how much can we use? */
+               used = skb->len - offset;
+               if (len < used)
+@@ -844,7 +845,7 @@ static int llc_ui_recvmsg(struct kiocb *
+               }
+               /* Partial read */
+-              if (used + offset < skb->len)
++              if (used + offset < skb_len)
+                       continue;
+       } while (len > 0);
diff --git a/queue-3.12/net-rose-restore-old-recvmsg-behavior.patch b/queue-3.12/net-rose-restore-old-recvmsg-behavior.patch
new file mode 100644 (file)
index 0000000..7b3f186
--- /dev/null
@@ -0,0 +1,61 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Florian Westphal <fw@strlen.de>
+Date: Mon, 23 Dec 2013 00:32:31 +0100
+Subject: net: rose: restore old recvmsg behavior
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f81152e35001e91997ec74a7b4e040e6ab0acccf ]
+
+recvmsg handler in net/rose/af_rose.c performs size-check ->msg_namelen.
+
+After commit f3d3342602f8bcbf37d7c46641cb9bca7618eb1c
+(net: rework recvmsg handler msg_name and msg_namelen logic), we now
+always take the else branch due to namelen being initialized to 0.
+
+Digging in netdev-vger-cvs git repo shows that msg_namelen was
+initialized with a fixed-size since at least 1995, so the else branch
+was never taken.
+
+Compile tested only.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rose/af_rose.c |   16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -1253,6 +1253,7 @@ static int rose_recvmsg(struct kiocb *io
+       if (msg->msg_name) {
+               struct sockaddr_rose *srose;
++              struct full_sockaddr_rose *full_srose = msg->msg_name;
+               memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
+               srose = msg->msg_name;
+@@ -1260,18 +1261,9 @@ static int rose_recvmsg(struct kiocb *io
+               srose->srose_addr   = rose->dest_addr;
+               srose->srose_call   = rose->dest_call;
+               srose->srose_ndigis = rose->dest_ndigis;
+-              if (msg->msg_namelen >= sizeof(struct full_sockaddr_rose)) {
+-                      struct full_sockaddr_rose *full_srose = (struct full_sockaddr_rose *)msg->msg_name;
+-                      for (n = 0 ; n < rose->dest_ndigis ; n++)
+-                              full_srose->srose_digis[n] = rose->dest_digis[n];
+-                      msg->msg_namelen = sizeof(struct full_sockaddr_rose);
+-              } else {
+-                      if (rose->dest_ndigis >= 1) {
+-                              srose->srose_ndigis = 1;
+-                              srose->srose_digi = rose->dest_digis[0];
+-                      }
+-                      msg->msg_namelen = sizeof(struct sockaddr_rose);
+-              }
++              for (n = 0 ; n < rose->dest_ndigis ; n++)
++                      full_srose->srose_digis[n] = rose->dest_digis[n];
++              msg->msg_namelen = sizeof(struct full_sockaddr_rose);
+       }
+       skb_free_datagram(sk, skb);
diff --git a/queue-3.12/net-unix-allow-bind-to-fail-on-mutex-lock.patch b/queue-3.12/net-unix-allow-bind-to-fail-on-mutex-lock.patch
new file mode 100644 (file)
index 0000000..220f219
--- /dev/null
@@ -0,0 +1,47 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Fri, 13 Dec 2013 10:54:22 -0500
+Subject: net: unix: allow bind to fail on mutex lock
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+[ Upstream commit 37ab4fa7844a044dc21fde45e2a0fc2f3c3b6490 ]
+
+This is similar to the set_peek_off patch where calling bind while the
+socket is stuck in unix_dgram_recvmsg() will block and cause a hung task
+spew after a while.
+
+This is also the last place that did a straightforward mutex_lock(), so
+there shouldn't be any more of these patches.
+
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/unix/af_unix.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -718,7 +718,9 @@ static int unix_autobind(struct socket *
+       int err;
+       unsigned int retries = 0;
+-      mutex_lock(&u->readlock);
++      err = mutex_lock_interruptible(&u->readlock);
++      if (err)
++              return err;
+       err = 0;
+       if (u->addr)
+@@ -877,7 +879,9 @@ static int unix_bind(struct socket *sock
+               goto out;
+       addr_len = err;
+-      mutex_lock(&u->readlock);
++      err = mutex_lock_interruptible(&u->readlock);
++      if (err)
++              goto out;
+       err = -EINVAL;
+       if (u->addr)
diff --git a/queue-3.12/net-unix-allow-set_peek_off-to-fail.patch b/queue-3.12/net-unix-allow-set_peek_off-to-fail.patch
new file mode 100644 (file)
index 0000000..8e8a72c
--- /dev/null
@@ -0,0 +1,72 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Sat, 7 Dec 2013 17:26:27 -0500
+Subject: net: unix: allow set_peek_off to fail
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+[ Upstream commit 12663bfc97c8b3fdb292428105dd92d563164050 ]
+
+unix_dgram_recvmsg() will hold the readlock of the socket until recv
+is complete.
+
+In the same time, we may try to setsockopt(SO_PEEK_OFF) which will hang until
+unix_dgram_recvmsg() will complete (which can take a while) without allowing
+us to break out of it, triggering a hung task spew.
+
+Instead, allow set_peek_off to fail, this way userspace will not hang.
+
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Acked-by: Pavel Emelyanov <xemul@parallels.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/net.h |    2 +-
+ net/core/sock.c     |    2 +-
+ net/unix/af_unix.c  |    8 ++++++--
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -180,7 +180,7 @@ struct proto_ops {
+                                     int offset, size_t size, int flags);
+       ssize_t         (*splice_read)(struct socket *sock,  loff_t *ppos,
+                                      struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+-      void            (*set_peek_off)(struct sock *sk, int val);
++      int             (*set_peek_off)(struct sock *sk, int val);
+ };
+ #define DECLARE_SOCKADDR(type, dst, src)      \
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -888,7 +888,7 @@ set_rcvbuf:
+       case SO_PEEK_OFF:
+               if (sock->ops->set_peek_off)
+-                      sock->ops->set_peek_off(sk, val);
++                      ret = sock->ops->set_peek_off(sk, val);
+               else
+                       ret = -EOPNOTSUPP;
+               break;
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct
+ static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
+                                 struct msghdr *, size_t, int);
+-static void unix_set_peek_off(struct sock *sk, int val)
++static int unix_set_peek_off(struct sock *sk, int val)
+ {
+       struct unix_sock *u = unix_sk(sk);
+-      mutex_lock(&u->readlock);
++      if (mutex_lock_interruptible(&u->readlock))
++              return -EINTR;
++
+       sk->sk_peek_off = val;
+       mutex_unlock(&u->readlock);
++
++      return 0;
+ }
diff --git a/queue-3.12/netpoll-fix-missing-txq-unlock-and-and-oops.patch b/queue-3.12/netpoll-fix-missing-txq-unlock-and-and-oops.patch
new file mode 100644 (file)
index 0000000..13fd9d0
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: "David S. Miller" <davem@davemloft.net>
+Date: Thu, 2 Jan 2014 19:50:52 -0500
+Subject: netpoll: Fix missing TXQ unlock and and OOPS.
+
+From: "David S. Miller" <davem@davemloft.net>
+
+[ Upstream commit aca5f58f9ba803ec8c2e6bcf890db17589e8dfcc ]
+
+The VLAN tag handling code in netpoll_send_skb_on_dev() has two problems.
+
+1) It exits without unlocking the TXQ.
+
+2) It then tries to queue a NULL skb to npinfo->txq.
+
+Reported-by: Ahmed Tamrawi <atamrawi@iastate.edu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/netpoll.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -386,8 +386,14 @@ void netpoll_send_skb_on_dev(struct netp
+                                           !vlan_hw_offload_capable(netif_skb_features(skb),
+                                                                    skb->vlan_proto)) {
+                                               skb = __vlan_put_tag(skb, skb->vlan_proto, vlan_tx_tag_get(skb));
+-                                              if (unlikely(!skb))
+-                                                      break;
++                                              if (unlikely(!skb)) {
++                                                      /* This is actually a packet drop, but we
++                                                       * don't want the code at the end of this
++                                                       * function to try and re-queue a NULL skb.
++                                                       */
++                                                      status = NETDEV_TX_OK;
++                                                      goto unlock_txq;
++                                              }
+                                               skb->vlan_tci = 0;
+                                       }
+@@ -395,6 +401,7 @@ void netpoll_send_skb_on_dev(struct netp
+                                       if (status == NETDEV_TX_OK)
+                                               txq_trans_update(txq);
+                               }
++                      unlock_txq:
+                               __netif_tx_unlock(txq);
+                               if (status == NETDEV_TX_OK)
diff --git a/queue-3.12/netvsc-don-t-flush-peers-notifying-work-during-setting-mtu.patch b/queue-3.12/netvsc-don-t-flush-peers-notifying-work-during-setting-mtu.patch
new file mode 100644 (file)
index 0000000..384b4c8
--- /dev/null
@@ -0,0 +1,90 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 13 Dec 2013 17:21:27 +0800
+Subject: netvsc: don't flush peers notifying work during setting mtu
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 50dc875f2e6e2e04aed3b3033eb0ac99192d6d02 ]
+
+There's a possible deadlock if we flush the peers notifying work during setting
+mtu:
+
+[   22.991149] ======================================================
+[   22.991173] [ INFO: possible circular locking dependency detected ]
+[   22.991198] 3.10.0-54.0.1.el7.x86_64.debug #1 Not tainted
+[   22.991219] -------------------------------------------------------
+[   22.991243] ip/974 is trying to acquire lock:
+[   22.991261]  ((&(&net_device_ctx->dwork)->work)){+.+.+.}, at: [<ffffffff8108af95>] flush_work+0x5/0x2e0
+[   22.991307]
+but task is already holding lock:
+[   22.991330]  (rtnl_mutex){+.+.+.}, at: [<ffffffff81539deb>] rtnetlink_rcv+0x1b/0x40
+[   22.991367]
+which lock already depends on the new lock.
+
+[   22.991398]
+the existing dependency chain (in reverse order) is:
+[   22.991426]
+-> #1 (rtnl_mutex){+.+.+.}:
+[   22.991449]        [<ffffffff810dfdd9>] __lock_acquire+0xb19/0x1260
+[   22.991477]        [<ffffffff810e0d12>] lock_acquire+0xa2/0x1f0
+[   22.991501]        [<ffffffff81673659>] mutex_lock_nested+0x89/0x4f0
+[   22.991529]        [<ffffffff815392b7>] rtnl_lock+0x17/0x20
+[   22.991552]        [<ffffffff815230b2>] netdev_notify_peers+0x12/0x30
+[   22.991579]        [<ffffffffa0340212>] netvsc_send_garp+0x22/0x30 [hv_netvsc]
+[   22.991610]        [<ffffffff8108d251>] process_one_work+0x211/0x6e0
+[   22.991637]        [<ffffffff8108d83b>] worker_thread+0x11b/0x3a0
+[   22.991663]        [<ffffffff81095e5d>] kthread+0xed/0x100
+[   22.991686]        [<ffffffff81681c6c>] ret_from_fork+0x7c/0xb0
+[   22.991715]
+-> #0 ((&(&net_device_ctx->dwork)->work)){+.+.+.}:
+[   22.991715]        [<ffffffff810de817>] check_prevs_add+0x967/0x970
+[   22.991715]        [<ffffffff810dfdd9>] __lock_acquire+0xb19/0x1260
+[   22.991715]        [<ffffffff810e0d12>] lock_acquire+0xa2/0x1f0
+[   22.991715]        [<ffffffff8108afde>] flush_work+0x4e/0x2e0
+[   22.991715]        [<ffffffff8108e1b5>] __cancel_work_timer+0x95/0x130
+[   22.991715]        [<ffffffff8108e303>] cancel_delayed_work_sync+0x13/0x20
+[   22.991715]        [<ffffffffa03404e4>] netvsc_change_mtu+0x84/0x200 [hv_netvsc]
+[   22.991715]        [<ffffffff815233d4>] dev_set_mtu+0x34/0x80
+[   22.991715]        [<ffffffff8153bc2a>] do_setlink+0x23a/0xa00
+[   22.991715]        [<ffffffff8153d054>] rtnl_newlink+0x394/0x5e0
+[   22.991715]        [<ffffffff81539eac>] rtnetlink_rcv_msg+0x9c/0x260
+[   22.991715]        [<ffffffff8155cdd9>] netlink_rcv_skb+0xa9/0xc0
+[   22.991715]        [<ffffffff81539dfa>] rtnetlink_rcv+0x2a/0x40
+[   22.991715]        [<ffffffff8155c41d>] netlink_unicast+0xdd/0x190
+[   22.991715]        [<ffffffff8155c807>] netlink_sendmsg+0x337/0x750
+[   22.991715]        [<ffffffff8150d219>] sock_sendmsg+0x99/0xd0
+[   22.991715]        [<ffffffff8150d63e>] ___sys_sendmsg+0x39e/0x3b0
+[   22.991715]        [<ffffffff8150eba2>] __sys_sendmsg+0x42/0x80
+[   22.991715]        [<ffffffff8150ebf2>] SyS_sendmsg+0x12/0x20
+[   22.991715]        [<ffffffff81681d19>] system_call_fastpath+0x16/0x1b
+
+This is because we hold the rtnl_lock() before ndo_change_mtu() and try to flush
+the work in netvsc_change_mtu(), in the mean time, netdev_notify_peers() may be
+called from worker and also trying to hold the rtnl_lock. This will lead the
+flush won't succeed forever. Solve this by not canceling and flushing the work,
+this is safe because the transmission done by NETDEV_NOTIFY_PEERS was
+synchronized with the netif_tx_disable() called by netvsc_change_mtu().
+
+Reported-by: Yaju Cao <yacao@redhat.com>
+Tested-by: Yaju Cao <yacao@redhat.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hyperv/netvsc_drv.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -327,7 +327,6 @@ static int netvsc_change_mtu(struct net_
+               return -EINVAL;
+       nvdev->start_remove = true;
+-      cancel_delayed_work_sync(&ndevctx->dwork);
+       cancel_work_sync(&ndevctx->work);
+       netif_tx_disable(ndev);
+       rndis_filter_device_remove(hdev);
diff --git a/queue-3.12/rds-prevent-dereference-of-a-null-device.patch b/queue-3.12/rds-prevent-dereference-of-a-null-device.patch
new file mode 100644 (file)
index 0000000..e461e71
--- /dev/null
@@ -0,0 +1,77 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Wed, 18 Dec 2013 23:49:42 -0500
+Subject: rds: prevent dereference of a NULL device
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+[ Upstream commit c2349758acf1874e4c2b93fe41d072336f1a31d0 ]
+
+Binding might result in a NULL device, which is dereferenced
+causing this BUG:
+
+[ 1317.260548] BUG: unable to handle kernel NULL pointer dereference at 000000000000097
+4
+[ 1317.261847] IP: [<ffffffff84225f52>] rds_ib_laddr_check+0x82/0x110
+[ 1317.263315] PGD 418bcb067 PUD 3ceb21067 PMD 0
+[ 1317.263502] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
+[ 1317.264179] Dumping ftrace buffer:
+[ 1317.264774]    (ftrace buffer empty)
+[ 1317.265220] Modules linked in:
+[ 1317.265824] CPU: 4 PID: 836 Comm: trinity-child46 Tainted: G        W    3.13.0-rc4-
+next-20131218-sasha-00013-g2cebb9b-dirty #4159
+[ 1317.267415] task: ffff8803ddf33000 ti: ffff8803cd31a000 task.ti: ffff8803cd31a000
+[ 1317.268399] RIP: 0010:[<ffffffff84225f52>]  [<ffffffff84225f52>] rds_ib_laddr_check+
+0x82/0x110
+[ 1317.269670] RSP: 0000:ffff8803cd31bdf8  EFLAGS: 00010246
+[ 1317.270230] RAX: 0000000000000000 RBX: ffff88020b0dd388 RCX: 0000000000000000
+[ 1317.270230] RDX: ffffffff8439822e RSI: 00000000000c000a RDI: 0000000000000286
+[ 1317.270230] RBP: ffff8803cd31be38 R08: 0000000000000000 R09: 0000000000000000
+[ 1317.270230] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
+[ 1317.270230] R13: 0000000054086700 R14: 0000000000a25de0 R15: 0000000000000031
+[ 1317.270230] FS:  00007ff40251d700(0000) GS:ffff88022e200000(0000) knlGS:000000000000
+0000
+[ 1317.270230] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+[ 1317.270230] CR2: 0000000000000974 CR3: 00000003cd478000 CR4: 00000000000006e0
+[ 1317.270230] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 1317.270230] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000090602
+[ 1317.270230] Stack:
+[ 1317.270230]  0000000054086700 5408670000a25de0 5408670000000002 0000000000000000
+[ 1317.270230]  ffffffff84223542 00000000ea54c767 0000000000000000 ffffffff86d26160
+[ 1317.270230]  ffff8803cd31be68 ffffffff84223556 ffff8803cd31beb8 ffff8800c6765280
+[ 1317.270230] Call Trace:
+[ 1317.270230]  [<ffffffff84223542>] ? rds_trans_get_preferred+0x42/0xa0
+[ 1317.270230]  [<ffffffff84223556>] rds_trans_get_preferred+0x56/0xa0
+[ 1317.270230]  [<ffffffff8421c9c3>] rds_bind+0x73/0xf0
+[ 1317.270230]  [<ffffffff83e4ce62>] SYSC_bind+0x92/0xf0
+[ 1317.270230]  [<ffffffff812493f8>] ? context_tracking_user_exit+0xb8/0x1d0
+[ 1317.270230]  [<ffffffff8119313d>] ? trace_hardirqs_on+0xd/0x10
+[ 1317.270230]  [<ffffffff8107a852>] ? syscall_trace_enter+0x32/0x290
+[ 1317.270230]  [<ffffffff83e4cece>] SyS_bind+0xe/0x10
+[ 1317.270230]  [<ffffffff843a6ad0>] tracesys+0xdd/0xe2
+[ 1317.270230] Code: 00 8b 45 cc 48 8d 75 d0 48 c7 45 d8 00 00 00 00 66 c7 45 d0 02 00
+89 45 d4 48 89 df e8 78 49 76 ff 41 89 c4 85 c0 75 0c 48 8b 03 <80> b8 74 09 00 00 01 7
+4 06 41 bc 9d ff ff ff f6 05 2a b6 c2 02
+[ 1317.270230] RIP  [<ffffffff84225f52>] rds_ib_laddr_check+0x82/0x110
+[ 1317.270230]  RSP <ffff8803cd31bdf8>
+[ 1317.270230] CR2: 0000000000000974
+
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rds/ib.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/rds/ib.c
++++ b/net/rds/ib.c
+@@ -338,7 +338,8 @@ static int rds_ib_laddr_check(__be32 add
+       ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
+       /* due to this, we will claim to support iWARP devices unless we
+          check node_type. */
+-      if (ret || cm_id->device->node_type != RDMA_NODE_IB_CA)
++      if (ret || !cm_id->device ||
++          cm_id->device->node_type != RDMA_NODE_IB_CA)
+               ret = -EADDRNOTAVAIL;
+       rdsdebug("addr %pI4 ret %d node type %d\n",
index a06652a34141ef8802f64476161944653ee59303..9cd445a6067b5d06cc37c6837bac37ba9579073f 100644 (file)
@@ -13,3 +13,38 @@ packet-fix-send-path-when-running-with-proto-0.patch
 ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch
 net-drop_monitor-fix-the-value-of-maxattr.patch
 inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch
+net-unix-allow-set_peek_off-to-fail.patch
+vxlan-release-rt-when-found-circular-route.patch
+tg3-initialize-reg_base_addr-at-pci-config-offset-120-to-0.patch
+netvsc-don-t-flush-peers-notifying-work-during-setting-mtu.patch
+ipv6-fix-illegal-mac_header-comparison-on-32bit.patch
+net-unix-allow-bind-to-fail-on-mutex-lock.patch
+ip_gre-fix-msg_name-parsing-for-recvfrom-recvmsg.patch
+net-inet_diag-zero-out-uninitialized-idiag_-src-dst-fields.patch
+drivers-net-hamradio-integer-overflow-in-hdlcdrv_ioctl.patch
+hamradio-yam-fix-info-leak-in-ioctl.patch
+net-fec-fix-potential-use-after-free.patch
+ipv6-always-set-the-new-created-dst-s-from-in-ip6_rt_copy.patch
+rds-prevent-dereference-of-a-null-device.patch
+arc_emac-fix-potential-use-after-free.patch
+net-rose-restore-old-recvmsg-behavior.patch
+vlan-fix-header-ops-passthru-when-doing-tx-vlan-offload.patch
+virtio_net-fix-error-handling-for-mergeable-buffers.patch
+virtio-net-make-all-rx-paths-handle-errors.patch
+virtio_net-don-t-leak-memory-or-block-when-too-many-frags.patch
+ipv4-fix-tunneled-vm-traffic-over-hw-vxlan-gre-gso-nic.patch
+virtio-net-fix-refill-races-during-restore.patch
+net-llc-fix-use-after-free-in-llc_ui_recvmsg.patch
+netpoll-fix-missing-txq-unlock-and-and-oops.patch
+bridge-use-spin_lock_bh-in-br_multicast_set_hash_max.patch
+sfc-add-length-checks-to-efx_xmit_with_hwtstamp-and-efx_ptp_is_ptp_tx.patch
+sfc-ptp-moderate-log-message-on-event-queue-overflow.patch
+sfc-rate-limit-log-message-for-ptp-packets-without-a-matching-timestamp-event.patch
+sfc-stop-re-start-ptp-when-stopping-starting-the-datapath.patch
+sfc-maintain-current-frequency-adjustment-when-applying-a-time-offset.patch
+sfc-rx-buffer-allocation-takes-prefix-size-into-account-in-ip-header-alignment.patch
+sfc-refactor-efx_mcdi_poll-by-introducing-efx_mcdi_poll_once.patch
+sfc-poll-for-mcdi-completion-once-before-timeout-occurs.patch
+arm-fix-footbridge-clockevent-device.patch
+arm-fix-bad-mode-in-...-handler-message-for-undefined-instructions.patch
+arm-7923-1-mm-fix-dcache-flush-logic-for-compound-high-pages.patch
diff --git a/queue-3.12/sfc-add-length-checks-to-efx_xmit_with_hwtstamp-and-efx_ptp_is_ptp_tx.patch b/queue-3.12/sfc-add-length-checks-to-efx_xmit_with_hwtstamp-and-efx_ptp_is_ptp_tx.patch
new file mode 100644 (file)
index 0000000..3df49eb
--- /dev/null
@@ -0,0 +1,41 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Fri, 6 Dec 2013 19:26:40 +0000
+Subject: sfc: Add length checks to efx_xmit_with_hwtstamp() and efx_ptp_is_ptp_tx()
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit e5a498e943fbc497f236ab8cf31366c75f337ce6 ]
+
+efx_ptp_is_ptp_tx() must be robust against skbs from raw sockets that
+have invalid IPv4 and UDP headers.
+
+Add checks that:
+- the transport header has been found
+- there is enough space between network and transport header offset
+  for an IPv4 header
+- there is enough space after the transport header offset for a
+  UDP header
+
+Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
+Signed-off-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 |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -989,7 +989,11 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *e
+               skb->len >= PTP_MIN_LENGTH &&
+               skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM &&
+               likely(skb->protocol == htons(ETH_P_IP)) &&
++              skb_transport_header_was_set(skb) &&
++              skb_network_header_len(skb) >= sizeof(struct iphdr) &&
+               ip_hdr(skb)->protocol == IPPROTO_UDP &&
++              skb_headlen(skb) >=
++              skb_transport_offset(skb) + sizeof(struct udphdr) &&
+               udp_hdr(skb)->dest == htons(PTP_EVENT_PORT);
+ }
diff --git a/queue-3.12/sfc-maintain-current-frequency-adjustment-when-applying-a-time-offset.patch b/queue-3.12/sfc-maintain-current-frequency-adjustment-when-applying-a-time-offset.patch
new file mode 100644 (file)
index 0000000..a16ff54
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Thu, 5 Dec 2013 17:24:06 +0000
+Subject: sfc: Maintain current frequency adjustment when applying a time offset
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit cd6fe65e923175e4f2e9fb585b1d78c6bf580fc6 ]
+
+There is a single MCDI PTP operation for setting the frequency
+adjustment and applying a time offset to the hardware clock.  When
+applying a time offset we should not change the frequency adjustment.
+
+These two operations can now be requested separately but this requires
+a flash firmware update.  Keep using the single operation, but
+remember and repeat the previous frequency adjustment.
+
+Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
+Signed-off-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 |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -1426,7 +1426,7 @@ static int efx_phc_adjfreq(struct ptp_cl
+       if (rc != 0)
+               return rc;
+-      ptp_data->current_adjfreq = delta;
++      ptp_data->current_adjfreq = adjustment_ns;
+       return 0;
+ }
+@@ -1441,7 +1441,7 @@ static int efx_phc_adjtime(struct ptp_cl
+       MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST);
+       MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
+-      MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, 0);
++      MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq);
+       MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec);
+       MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec);
+       return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
diff --git a/queue-3.12/sfc-poll-for-mcdi-completion-once-before-timeout-occurs.patch b/queue-3.12/sfc-poll-for-mcdi-completion-once-before-timeout-occurs.patch
new file mode 100644 (file)
index 0000000..4b51319
--- /dev/null
@@ -0,0 +1,57 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Robert Stonehouse <rstonehouse@solarflare.com>
+Date: Wed, 9 Oct 2013 11:52:48 +0100
+Subject: sfc: Poll for MCDI completion once before timeout occurs
+
+From: Robert Stonehouse <rstonehouse@solarflare.com>
+
+[ Upstream commit 6b294b8efedaa7cf7507154148e2c79766ad6f96 ]
+
+There is an as-yet unexplained bug that sometimes prevents (or delays)
+the driver seeing the completion event for a completed MCDI request on
+the SFC9120.  The requested configuration change will have happened
+but the driver assumes it to have failed, and this can result in
+further failures.  We can mitigate this by polling for completion
+after unsuccessfully waiting for an event.
+
+Fixes: 8127d661e77f ('sfc: Add support for Solarflare SFC9100 family')
+Signed-off-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/mcdi.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/mcdi.c
++++ b/drivers/net/ethernet/sfc/mcdi.c
+@@ -630,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *
+               rc = efx_mcdi_await_completion(efx);
+       if (rc != 0) {
++              netif_err(efx, hw, efx->net_dev,
++                        "MC command 0x%x inlen %d mode %d timed out\n",
++                        cmd, (int)inlen, mcdi->mode);
++
++              if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) {
++                      netif_err(efx, hw, efx->net_dev,
++                                "MCDI request was completed without an event\n");
++                      rc = 0;
++              }
++
+               /* Close the race with efx_mcdi_ev_cpl() executing just too late
+                * and completing a request we've just cancelled, by ensuring
+                * that the seqno check therein fails.
+@@ -638,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *
+               ++mcdi->seqno;
+               ++mcdi->credits;
+               spin_unlock_bh(&mcdi->iface_lock);
++      }
+-              netif_err(efx, hw, efx->net_dev,
+-                        "MC command 0x%x inlen %d mode %d timed out\n",
+-                        cmd, (int)inlen, mcdi->mode);
+-      } else {
++      if (rc == 0) {
+               size_t hdr_len, data_len;
+               /* At the very least we need a memory barrier here to ensure
diff --git a/queue-3.12/sfc-ptp-moderate-log-message-on-event-queue-overflow.patch b/queue-3.12/sfc-ptp-moderate-log-message-on-event-queue-overflow.patch
new file mode 100644 (file)
index 0000000..60bba5c
--- /dev/null
@@ -0,0 +1,93 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Laurence Evans <levans@solarflare.com>
+Date: Mon, 28 Jan 2013 14:51:17 +0000
+Subject: sfc: PTP: Moderate log message on event queue overflow
+
+From: Laurence Evans <levans@solarflare.com>
+
+[ Upstream commit f32116003c39f3a6815215a7512e1ea8d1e4bbc7 ]
+
+Limit syslog flood if a PTP packet storm occurs.
+
+Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
+Signed-off-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 |   23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -220,6 +220,7 @@ struct efx_ptp_timeset {
+  * @evt_list: List of MC receive events awaiting packets
+  * @evt_free_list: List of free events
+  * @evt_lock: Lock for manipulating evt_list and evt_free_list
++ * @evt_overflow: Boolean indicating that event list has overflowed
+  * @rx_evts: Instantiated events (on evt_list and evt_free_list)
+  * @workwq: Work queue for processing pending PTP operations
+  * @work: Work task
+@@ -270,6 +271,7 @@ struct efx_ptp_data {
+       struct list_head evt_list;
+       struct list_head evt_free_list;
+       spinlock_t evt_lock;
++      bool evt_overflow;
+       struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS];
+       struct workqueue_struct *workwq;
+       struct work_struct work;
+@@ -635,6 +637,11 @@ static void efx_ptp_drop_time_expired_ev
+                       }
+               }
+       }
++      /* If the event overflow flag is set and the event list is now empty
++       * clear the flag to re-enable the overflow warning message.
++       */
++      if (ptp->evt_overflow && list_empty(&ptp->evt_list))
++              ptp->evt_overflow = false;
+       spin_unlock_bh(&ptp->evt_lock);
+ }
+@@ -676,6 +683,11 @@ static enum ptp_packet_state efx_ptp_mat
+                       break;
+               }
+       }
++      /* If the event overflow flag is set and the event list is now empty
++       * clear the flag to re-enable the overflow warning message.
++       */
++      if (ptp->evt_overflow && list_empty(&ptp->evt_list))
++              ptp->evt_overflow = false;
+       spin_unlock_bh(&ptp->evt_lock);
+       return rc;
+@@ -809,6 +821,7 @@ static int efx_ptp_stop(struct efx_nic *
+       list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) {
+               list_move(cursor, &efx->ptp_data->evt_free_list);
+       }
++      ptp->evt_overflow = false;
+       spin_unlock_bh(&efx->ptp_data->evt_lock);
+       return rc;
+@@ -901,6 +914,7 @@ static int efx_ptp_probe_channel(struct
+       spin_lock_init(&ptp->evt_lock);
+       for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++)
+               list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list);
++      ptp->evt_overflow = false;
+       ptp->phc_clock_info.owner = THIS_MODULE;
+       snprintf(ptp->phc_clock_info.name,
+@@ -1299,8 +1313,13 @@ static void ptp_event_rx(struct efx_nic
+               list_add_tail(&evt->link, &ptp->evt_list);
+               queue_work(ptp->workwq, &ptp->work);
+-      } else {
+-              netif_err(efx, rx_err, efx->net_dev, "No free PTP event");
++      } else if (!ptp->evt_overflow) {
++              /* Log a warning message and set the event overflow flag.
++               * The message won't be logged again until the event queue
++               * becomes empty.
++               */
++              netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n");
++              ptp->evt_overflow = true;
+       }
+       spin_unlock_bh(&ptp->evt_lock);
+ }
diff --git a/queue-3.12/sfc-rate-limit-log-message-for-ptp-packets-without-a-matching-timestamp-event.patch b/queue-3.12/sfc-rate-limit-log-message-for-ptp-packets-without-a-matching-timestamp-event.patch
new file mode 100644 (file)
index 0000000..7d4bdca
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Ben Hutchings <bhutchings@solarflare.com>
+Date: Fri, 6 Dec 2013 22:10:46 +0000
+Subject: sfc: Rate-limit log message for PTP packets without a matching timestamp event
+
+From: Ben Hutchings <bhutchings@solarflare.com>
+
+[ Upstream commit 35f9a7a380728a94d417e5824a866f969423ac83 ]
+
+In case of a flood of PTP packets, the timestamp peripheral and MC
+firmware on the SFN[56]322F boards may not be able to provide
+timestamp events for all packets.  Don't complain too much about this.
+
+Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
+Signed-off-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 |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -717,8 +717,9 @@ static bool efx_ptp_process_events(struc
+                       __skb_queue_tail(q, skb);
+               } else if (time_after(jiffies, match->expiry)) {
+                       match->state = PTP_PACKET_STATE_TIMED_OUT;
+-                      netif_warn(efx, rx_err, efx->net_dev,
+-                                 "PTP packet - no timestamp seen\n");
++                      if (net_ratelimit())
++                              netif_warn(efx, rx_err, efx->net_dev,
++                                         "PTP packet - no timestamp seen\n");
+                       __skb_queue_tail(q, skb);
+               } else {
+                       /* Replace unprocessed entry and stop */
diff --git a/queue-3.12/sfc-refactor-efx_mcdi_poll-by-introducing-efx_mcdi_poll_once.patch b/queue-3.12/sfc-refactor-efx_mcdi_poll-by-introducing-efx_mcdi_poll_once.patch
new file mode 100644 (file)
index 0000000..dc33b68
--- /dev/null
@@ -0,0 +1,68 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Robert Stonehouse <rstonehouse@solarflare.com>
+Date: Wed, 9 Oct 2013 11:52:43 +0100
+Subject: sfc: Refactor efx_mcdi_poll() by introducing efx_mcdi_poll_once()
+
+From: Robert Stonehouse <rstonehouse@solarflare.com>
+
+[ Upstream commit 5731d7b35e5b87157a9b9973cc2eff70c50aec58 ]
+
+Signed-off-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/mcdi.c |   23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/mcdi.c
++++ b/drivers/net/ethernet/sfc/mcdi.c
+@@ -50,6 +50,7 @@ struct efx_mcdi_async_param {
+ static void efx_mcdi_timeout_async(unsigned long context);
+ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
+                              bool *was_attached_out);
++static bool efx_mcdi_poll_once(struct efx_nic *efx);
+ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
+ {
+@@ -237,6 +238,21 @@ static void efx_mcdi_read_response_heade
+       }
+ }
++static bool efx_mcdi_poll_once(struct efx_nic *efx)
++{
++      struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
++
++      rmb();
++      if (!efx->type->mcdi_poll_response(efx))
++              return false;
++
++      spin_lock_bh(&mcdi->iface_lock);
++      efx_mcdi_read_response_header(efx);
++      spin_unlock_bh(&mcdi->iface_lock);
++
++      return true;
++}
++
+ static int efx_mcdi_poll(struct efx_nic *efx)
+ {
+       struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+@@ -272,18 +288,13 @@ static int efx_mcdi_poll(struct efx_nic
+               time = jiffies;
+-              rmb();
+-              if (efx->type->mcdi_poll_response(efx))
++              if (efx_mcdi_poll_once(efx))
+                       break;
+               if (time_after(time, finish))
+                       return -ETIMEDOUT;
+       }
+-      spin_lock_bh(&mcdi->iface_lock);
+-      efx_mcdi_read_response_header(efx);
+-      spin_unlock_bh(&mcdi->iface_lock);
+-
+       /* Return rc=0 like wait_event_timeout() */
+       return 0;
+ }
diff --git a/queue-3.12/sfc-rx-buffer-allocation-takes-prefix-size-into-account-in-ip-header-alignment.patch b/queue-3.12/sfc-rx-buffer-allocation-takes-prefix-size-into-account-in-ip-header-alignment.patch
new file mode 100644 (file)
index 0000000..00020f4
--- /dev/null
@@ -0,0 +1,85 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
+Date: Sat, 16 Nov 2013 11:02:27 +0400
+Subject: sfc: RX buffer allocation takes prefix size into account in IP header alignment
+
+From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
+
+[ Upstream commit 2ec030144f648a6dd208f95f55ece212f1b72771 ]
+
+rx_prefix_size is 4-bytes aligned on Falcon/Siena (16 bytes), but it is equal
+to 14 on EF10. So, it should be taken into account if arch requires IP header
+to be 4-bytes aligned (via NET_IP_ALIGN).
+
+Fixes: 8127d661e77f ('sfc: Add support for Solarflare SFC9100 family')
+Signed-off-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/efx.c        |    4 +++-
+ drivers/net/ethernet/sfc/net_driver.h |    3 +++
+ drivers/net/ethernet/sfc/rx.c         |    6 +++---
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -585,7 +585,7 @@ static void efx_start_datapath(struct ef
+                          EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
+                          efx->type->rx_buffer_padding);
+       rx_buf_len = (sizeof(struct efx_rx_page_state) +
+-                    NET_IP_ALIGN + efx->rx_dma_len);
++                    efx->rx_ip_align + efx->rx_dma_len);
+       if (rx_buf_len <= PAGE_SIZE) {
+               efx->rx_scatter = efx->type->always_rx_scatter;
+               efx->rx_buffer_order = 0;
+@@ -2554,6 +2554,8 @@ static int efx_init_struct(struct efx_ni
+       efx->net_dev = net_dev;
+       efx->rx_prefix_size = efx->type->rx_prefix_size;
++      efx->rx_ip_align =
++              NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
+       efx->rx_packet_hash_offset =
+               efx->type->rx_hash_offset - efx->type->rx_prefix_size;
+       spin_lock_init(&efx->stats_lock);
+--- a/drivers/net/ethernet/sfc/net_driver.h
++++ b/drivers/net/ethernet/sfc/net_driver.h
+@@ -673,6 +673,8 @@ struct vfdi_status;
+  * @n_channels: Number of channels in use
+  * @n_rx_channels: Number of channels used for RX (= number of RX queues)
+  * @n_tx_channels: Number of channels used for TX
++ * @rx_ip_align: RX DMA address offset to have IP header aligned in
++ *    in accordance with NET_IP_ALIGN
+  * @rx_dma_len: Current maximum RX DMA length
+  * @rx_buffer_order: Order (log2) of number of pages for each RX buffer
+  * @rx_buffer_truesize: Amortised allocation size of an RX buffer,
+@@ -806,6 +808,7 @@ struct efx_nic {
+       unsigned rss_spread;
+       unsigned tx_channel_offset;
+       unsigned n_tx_channels;
++      unsigned int rx_ip_align;
+       unsigned int rx_dma_len;
+       unsigned int rx_buffer_order;
+       unsigned int rx_buffer_truesize;
+--- a/drivers/net/ethernet/sfc/rx.c
++++ b/drivers/net/ethernet/sfc/rx.c
+@@ -93,7 +93,7 @@ static inline void efx_sync_rx_buffer(st
+ void efx_rx_config_page_split(struct efx_nic *efx)
+ {
+-      efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN,
++      efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align,
+                                     EFX_RX_BUF_ALIGNMENT);
+       efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 :
+               ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) /
+@@ -188,9 +188,9 @@ static int efx_init_rx_buffers(struct ef
+               do {
+                       index = rx_queue->added_count & rx_queue->ptr_mask;
+                       rx_buf = efx_rx_buffer(rx_queue, index);
+-                      rx_buf->dma_addr = dma_addr + NET_IP_ALIGN;
++                      rx_buf->dma_addr = dma_addr + efx->rx_ip_align;
+                       rx_buf->page = page;
+-                      rx_buf->page_offset = page_offset + NET_IP_ALIGN;
++                      rx_buf->page_offset = page_offset + efx->rx_ip_align;
+                       rx_buf->len = efx->rx_dma_len;
+                       rx_buf->flags = 0;
+                       ++rx_queue->added_count;
diff --git a/queue-3.12/sfc-stop-re-start-ptp-when-stopping-starting-the-datapath.patch b/queue-3.12/sfc-stop-re-start-ptp-when-stopping-starting-the-datapath.patch
new file mode 100644 (file)
index 0000000..220c4a0
--- /dev/null
@@ -0,0 +1,123 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Alexandre Rames <arames@solarflare.com>
+Date: Fri, 8 Nov 2013 10:20:31 +0000
+Subject: sfc: Stop/re-start PTP when stopping/starting the datapath.
+
+From: Alexandre Rames <arames@solarflare.com>
+
+[ Upstream commit 2ea4dc28a5bcec408e01a8772763871638a5ec79 ]
+
+This disables PTP when we bring the interface down to avoid getting
+unmatched RX timestamp events, and tries to re-enable it when bringing
+the interface up.
+
+[bwh: Make efx_ptp_stop() safe on Falcon. Introduce
+ efx_ptp_{start,stop}_datapath() functions; we'll expand them later.]
+
+Fixes: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP')
+Signed-off-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/efx.c |    4 ++++
+ drivers/net/ethernet/sfc/nic.h |    2 ++
+ drivers/net/ethernet/sfc/ptp.c |   30 +++++++++++++++++++++++++++---
+ 3 files changed, 33 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -645,6 +645,8 @@ static void efx_start_datapath(struct ef
+               WARN_ON(channel->rx_pkt_n_frags);
+       }
++      efx_ptp_start_datapath(efx);
++
+       if (netif_device_present(efx->net_dev))
+               netif_tx_wake_all_queues(efx->net_dev);
+ }
+@@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx
+       EFX_ASSERT_RESET_SERIALISED(efx);
+       BUG_ON(efx->port_enabled);
++      efx_ptp_stop_datapath(efx);
++
+       /* Stop RX refill */
+       efx_for_each_channel(channel, efx) {
+               efx_for_each_channel_rx_queue(rx_queue, channel)
+--- a/drivers/net/ethernet/sfc/nic.h
++++ b/drivers/net/ethernet/sfc/nic.h
+@@ -528,6 +528,8 @@ extern void efx_ptp_get_ts_info(struct e
+ extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
+ extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
+ extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
++void efx_ptp_start_datapath(struct efx_nic *efx);
++void efx_ptp_stop_datapath(struct efx_nic *efx);
+ extern const struct efx_nic_type falcon_a1_nic_type;
+ extern const struct efx_nic_type falcon_b0_nic_type;
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -801,9 +801,14 @@ fail:
+ static int efx_ptp_stop(struct efx_nic *efx)
+ {
+       struct efx_ptp_data *ptp = efx->ptp_data;
+-      int rc = efx_ptp_disable(efx);
+       struct list_head *cursor;
+       struct list_head *next;
++      int rc;
++
++      if (ptp == NULL)
++              return 0;
++
++      rc = efx_ptp_disable(efx);
+       if (ptp->rxfilter_installed) {
+               efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
+@@ -828,6 +833,13 @@ static int efx_ptp_stop(struct efx_nic *
+       return rc;
+ }
++static int efx_ptp_restart(struct efx_nic *efx)
++{
++      if (efx->ptp_data && efx->ptp_data->enabled)
++              return efx_ptp_start(efx);
++      return 0;
++}
++
+ static void efx_ptp_pps_worker(struct work_struct *work)
+ {
+       struct efx_ptp_data *ptp =
+@@ -1125,7 +1137,7 @@ static int efx_ptp_change_mode(struct ef
+ {
+       if ((enable_wanted != efx->ptp_data->enabled) ||
+           (enable_wanted && (efx->ptp_data->mode != new_mode))) {
+-              int rc;
++              int rc = 0;
+               if (enable_wanted) {
+                       /* Change of mode requires disable */
+@@ -1142,7 +1154,8 @@ static int efx_ptp_change_mode(struct ef
+                        * succeed.
+                        */
+                       efx->ptp_data->mode = new_mode;
+-                      rc = efx_ptp_start(efx);
++                      if (netif_running(efx->net_dev))
++                              rc = efx_ptp_start(efx);
+                       if (rc == 0) {
+                               rc = efx_ptp_synchronize(efx,
+                                                        PTP_SYNC_ATTEMPTS * 2);
+@@ -1515,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
+               efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
+                       &efx_ptp_channel_type;
+ }
++
++void efx_ptp_start_datapath(struct efx_nic *efx)
++{
++      if (efx_ptp_restart(efx))
++              netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
++}
++
++void efx_ptp_stop_datapath(struct efx_nic *efx)
++{
++      efx_ptp_stop(efx);
++}
diff --git a/queue-3.12/tg3-initialize-reg_base_addr-at-pci-config-offset-120-to-0.patch b/queue-3.12/tg3-initialize-reg_base_addr-at-pci-config-offset-120-to-0.patch
new file mode 100644 (file)
index 0000000..92cc758
--- /dev/null
@@ -0,0 +1,37 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Nat Gurumoorthy <natg@google.com>
+Date: Mon, 9 Dec 2013 10:43:21 -0800
+Subject: tg3: Initialize REG_BASE_ADDR at PCI config offset 120 to 0
+
+From: Nat Gurumoorthy <natg@google.com>
+
+[ Upstream commit 388d3335575f4c056dcf7138a30f1454e2145cd8 ]
+
+The new tg3 driver leaves REG_BASE_ADDR (PCI config offset 120)
+uninitialized. From power on reset this register may have garbage in it. The
+Register Base Address register defines the device local address of a
+register. The data pointed to by this location is read or written using
+the Register Data register (PCI config offset 128). When REG_BASE_ADDR has
+garbage any read or write of Register Data Register (PCI 128) will cause the
+PCI bus to lock up. The TCO watchdog will fire and bring down the system.
+
+Signed-off-by: Nat Gurumoorthy <natg@google.com>
+Acked-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 |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -16485,6 +16485,9 @@ static int tg3_get_invariants(struct tg3
+       /* Clear this out for sanity. */
+       tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
++      /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */
++      tw32(TG3PCI_REG_BASE_ADDR, 0);
++
+       pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
+                             &pci_state_reg);
+       if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
diff --git a/queue-3.12/virtio-net-fix-refill-races-during-restore.patch b/queue-3.12/virtio-net-fix-refill-races-during-restore.patch
new file mode 100644 (file)
index 0000000..8f536eb
--- /dev/null
@@ -0,0 +1,52 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Jason Wang <jasowang@redhat.com>
+Date: Mon, 30 Dec 2013 11:34:40 +0800
+Subject: virtio-net: fix refill races during restore
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 6cd4ce0099da7702f885b6fa9ebb49e3831d90b4 ]
+
+During restoring, try_fill_recv() was called with neither napi lock nor napi
+disabled. This can lead two try_fill_recv() was called in the same time. Fix
+this by refilling before trying to enable napi.
+
+Fixes 0741bcb5584f9e2390ae6261573c4de8314999f2
+(virtio: net: Add freeze, restore handlers to support S4).
+
+Cc: Amit Shah <amit.shah@redhat.com>
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1772,16 +1772,17 @@ static int virtnet_restore(struct virtio
+       if (err)
+               return err;
+-      if (netif_running(vi->dev))
++      if (netif_running(vi->dev)) {
++              for (i = 0; i < vi->curr_queue_pairs; i++)
++                      if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
++                              schedule_delayed_work(&vi->refill, 0);
++
+               for (i = 0; i < vi->max_queue_pairs; i++)
+                       virtnet_napi_enable(&vi->rq[i]);
++      }
+       netif_device_attach(vi->dev);
+-      for (i = 0; i < vi->curr_queue_pairs; i++)
+-              if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
+-                      schedule_delayed_work(&vi->refill, 0);
+-
+       mutex_lock(&vi->config_lock);
+       vi->config_enable = true;
+       mutex_unlock(&vi->config_lock);
diff --git a/queue-3.12/virtio-net-make-all-rx-paths-handle-errors.patch b/queue-3.12/virtio-net-make-all-rx-paths-handle-errors.patch
new file mode 100644 (file)
index 0000000..1d5fe4a
--- /dev/null
@@ -0,0 +1,105 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Thu, 26 Dec 2013 15:32:51 +0200
+Subject: virtio-net: make all RX paths handle errors
+ consistently
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+receive mergeable now handles errors internally.
+Do same for big and small packet paths, otherwise
+the logic is too hard to follow.
+
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: David S. Miller <davem@davemloft.net>
+Acked-by: Michael Dalton <mwdalton@google.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit f121159d72091f25afb22007c833e60a6845e912)
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   56 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 36 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -297,6 +297,34 @@ static struct sk_buff *page_to_skb(struc
+       return skb;
+ }
++static struct sk_buff *receive_small(void *buf, unsigned int len)
++{
++      struct sk_buff * skb = buf;
++
++      len -= sizeof(struct virtio_net_hdr);
++      skb_trim(skb, len);
++
++      return skb;
++}
++
++static struct sk_buff *receive_big(struct net_device *dev,
++                                 struct receive_queue *rq,
++                                 void *buf)
++{
++      struct page *page = buf;
++      struct sk_buff *skb = page_to_skb(rq, page, 0);
++
++      if (unlikely(!skb))
++              goto err;
++
++      return skb;
++
++err:
++      dev->stats.rx_dropped++;
++      give_pages(rq, page);
++      return NULL;
++}
++
+ static struct sk_buff *receive_mergeable(struct net_device *dev,
+                                        struct receive_queue *rq,
+                                        void *buf,
+@@ -360,7 +388,6 @@ static void receive_buf(struct receive_q
+       struct net_device *dev = vi->dev;
+       struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
+       struct sk_buff *skb;
+-      struct page *page;
+       struct skb_vnet_hdr *hdr;
+       if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+@@ -372,26 +399,15 @@ static void receive_buf(struct receive_q
+                       dev_kfree_skb(buf);
+               return;
+       }
++      if (vi->mergeable_rx_bufs)
++              skb = receive_mergeable(dev, rq, buf, len);
++      else if (vi->big_packets)
++              skb = receive_big(dev, rq, buf);
++      else
++              skb = receive_small(buf, len);
+-      if (!vi->mergeable_rx_bufs && !vi->big_packets) {
+-              skb = buf;
+-              len -= sizeof(struct virtio_net_hdr);
+-              skb_trim(skb, len);
+-      } else {
+-              page = buf;
+-              if (vi->mergeable_rx_bufs) {
+-                      skb = receive_mergeable(dev, rq, page, len);
+-                      if (unlikely(!skb))
+-                              return;
+-              } else {
+-                      skb = page_to_skb(rq, page, len);
+-                      if (unlikely(!skb)) {
+-                              dev->stats.rx_dropped++;
+-                              give_pages(rq, page);
+-                              return;
+-                      }
+-              }
+-      }
++      if (unlikely(!skb))
++              return;
+       hdr = skb_vnet_hdr(skb);
diff --git a/queue-3.12/virtio_net-don-t-leak-memory-or-block-when-too-many-frags.patch b/queue-3.12/virtio_net-don-t-leak-memory-or-block-when-too-many-frags.patch
new file mode 100644 (file)
index 0000000..da5e5a4
--- /dev/null
@@ -0,0 +1,39 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Thu, 26 Dec 2013 15:32:55 +0200
+Subject: virtio_net: don't leak memory or block when too many frags
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+We leak an skb when there are too many frags,
+we also stop processing the packet in the middle,
+the result is almost sure to be loss of networking.
+
+Reported-by: Michael Dalton <mwdalton@google.com>
+Acked-by: Michael Dalton <mwdalton@google.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -344,7 +344,7 @@ static struct sk_buff *receive_mergeable
+               if (i >= MAX_SKB_FRAGS) {
+                       pr_debug("%s: packet too long\n", skb->dev->name);
+                       skb->dev->stats.rx_length_errors++;
+-                      return NULL;
++                      goto err_frags;
+               }
+               page = virtqueue_get_buf(rq->vq, &len);
+               if (!page) {
+@@ -365,6 +365,7 @@ static struct sk_buff *receive_mergeable
+ err_skb:
+       give_pages(rq, page);
+       while (--num_buf) {
++err_frags:
+               buf = virtqueue_get_buf(rq->vq, &len);
+               if (unlikely(!buf)) {
+                       pr_debug("%s: rx error: %d buffers missing\n",
diff --git a/queue-3.12/virtio_net-fix-error-handling-for-mergeable-buffers.patch b/queue-3.12/virtio_net-fix-error-handling-for-mergeable-buffers.patch
new file mode 100644 (file)
index 0000000..9fcbb9c
--- /dev/null
@@ -0,0 +1,132 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Thu, 26 Dec 2013 15:32:47 +0200
+Subject: virtio_net: fix error handling for mergeable buffers
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+Eric Dumazet noticed that if we encounter an error
+when processing a mergeable buffer, we don't
+dequeue all of the buffers from this packet,
+the result is almost sure to be loss of networking.
+
+Fix this issue.
+
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Michael Dalton <mwdalton@google.com>
+Acked-by: Michael Dalton <mwdalton@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: David S. Miller <davem@davemloft.net>
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 8fc3b9e9a229778e5af3aa453c44f1a3857ba769)
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   66 ++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 46 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -297,26 +297,33 @@ static struct sk_buff *page_to_skb(struc
+       return skb;
+ }
+-static int receive_mergeable(struct receive_queue *rq, struct sk_buff *skb)
++static struct sk_buff *receive_mergeable(struct net_device *dev,
++                                       struct receive_queue *rq,
++                                       void *buf,
++                                       unsigned int len)
+ {
+-      struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
+-      struct page *page;
+-      int num_buf, i, len;
++      struct skb_vnet_hdr *hdr = page_address(buf);
++      int num_buf = hdr->mhdr.num_buffers;
++      struct page *page = buf;
++      struct sk_buff *skb = page_to_skb(rq, page, len);
++      int i;
++
++      if (unlikely(!skb))
++              goto err_skb;
+-      num_buf = hdr->mhdr.num_buffers;
+       while (--num_buf) {
+               i = skb_shinfo(skb)->nr_frags;
+               if (i >= MAX_SKB_FRAGS) {
+                       pr_debug("%s: packet too long\n", skb->dev->name);
+                       skb->dev->stats.rx_length_errors++;
+-                      return -EINVAL;
++                      return NULL;
+               }
+               page = virtqueue_get_buf(rq->vq, &len);
+               if (!page) {
+-                      pr_debug("%s: rx error: %d buffers missing\n",
+-                               skb->dev->name, hdr->mhdr.num_buffers);
+-                      skb->dev->stats.rx_length_errors++;
+-                      return -EINVAL;
++                      pr_debug("%s: rx error: %d buffers %d missing\n",
++                               dev->name, hdr->mhdr.num_buffers, num_buf);
++                      dev->stats.rx_length_errors++;
++                      goto err_buf;
+               }
+               if (len > PAGE_SIZE)
+@@ -326,7 +333,25 @@ static int receive_mergeable(struct rece
+               --rq->num;
+       }
+-      return 0;
++      return skb;
++err_skb:
++      give_pages(rq, page);
++      while (--num_buf) {
++              buf = virtqueue_get_buf(rq->vq, &len);
++              if (unlikely(!buf)) {
++                      pr_debug("%s: rx error: %d buffers missing\n",
++                               dev->name, num_buf);
++                      dev->stats.rx_length_errors++;
++                      break;
++              }
++              page = buf;
++              give_pages(rq, page);
++              --rq->num;
++      }
++err_buf:
++      dev->stats.rx_dropped++;
++      dev_kfree_skb(skb);
++      return NULL;
+ }
+ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
+@@ -354,17 +379,18 @@ static void receive_buf(struct receive_q
+               skb_trim(skb, len);
+       } else {
+               page = buf;
+-              skb = page_to_skb(rq, page, len);
+-              if (unlikely(!skb)) {
+-                      dev->stats.rx_dropped++;
+-                      give_pages(rq, page);
+-                      return;
+-              }
+-              if (vi->mergeable_rx_bufs)
+-                      if (receive_mergeable(rq, skb)) {
+-                              dev_kfree_skb(skb);
++              if (vi->mergeable_rx_bufs) {
++                      skb = receive_mergeable(dev, rq, page, len);
++                      if (unlikely(!skb))
++                              return;
++              } else {
++                      skb = page_to_skb(rq, page, len);
++                      if (unlikely(!skb)) {
++                              dev->stats.rx_dropped++;
++                              give_pages(rq, page);
+                               return;
+                       }
++              }
+       }
+       hdr = skb_vnet_hdr(skb);
diff --git a/queue-3.12/vlan-fix-header-ops-passthru-when-doing-tx-vlan-offload.patch b/queue-3.12/vlan-fix-header-ops-passthru-when-doing-tx-vlan-offload.patch
new file mode 100644 (file)
index 0000000..e6e40bc
--- /dev/null
@@ -0,0 +1,105 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: "David S. Miller" <davem@davemloft.net>
+Date: Tue, 31 Dec 2013 16:23:35 -0500
+Subject: vlan: Fix header ops passthru when doing TX VLAN offload.
+
+From: "David S. Miller" <davem@davemloft.net>
+
+[ Upstream commit 2205369a314e12fcec4781cc73ac9c08fc2b47de ]
+
+When the vlan code detects that the real device can do TX VLAN offloads
+in hardware, it tries to arrange for the real device's header_ops to
+be invoked directly.
+
+But it does so illegally, by simply hooking the real device's
+header_ops up to the VLAN device.
+
+This doesn't work because we will end up invoking a set of header_ops
+routines which expect a device type which matches the real device, but
+will see a VLAN device instead.
+
+Fix this by providing a pass-thru set of header_ops which will arrange
+to pass the proper real device instead.
+
+To facilitate this add a dev_rebuild_header().  There are
+implementations which provide a ->cache and ->create but not a
+->rebuild (f.e. PLIP).  So we need a helper function just like
+dev_hard_header() to avoid crashes.
+
+Use this helper in the one existing place where the
+header_ops->rebuild was being invoked, the neighbour code.
+
+With lots of help from Florian Westphal.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/netdevice.h |    9 +++++++++
+ net/8021q/vlan_dev.c      |   19 ++++++++++++++++++-
+ net/core/neighbour.c      |    2 +-
+ 3 files changed, 28 insertions(+), 2 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1872,6 +1872,15 @@ static inline int dev_parse_header(const
+       return dev->header_ops->parse(skb, haddr);
+ }
++static inline int dev_rebuild_header(struct sk_buff *skb)
++{
++      const struct net_device *dev = skb->dev;
++
++      if (!dev->header_ops || !dev->header_ops->rebuild)
++              return 0;
++      return dev->header_ops->rebuild(skb);
++}
++
+ typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
+ extern int            register_gifconf(unsigned int family, gifconf_func_t * gifconf);
+ static inline int unregister_gifconf(unsigned int family)
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -549,6 +549,23 @@ static const struct header_ops vlan_head
+       .parse   = eth_header_parse,
+ };
++static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev,
++                                   unsigned short type,
++                                   const void *daddr, const void *saddr,
++                                   unsigned int len)
++{
++      struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
++      struct net_device *real_dev = vlan->real_dev;
++
++      return dev_hard_header(skb, real_dev, type, daddr, saddr, len);
++}
++
++static const struct header_ops vlan_passthru_header_ops = {
++      .create  = vlan_passthru_hard_header,
++      .rebuild = dev_rebuild_header,
++      .parse   = eth_header_parse,
++};
++
+ static struct device_type vlan_type = {
+       .name   = "vlan",
+ };
+@@ -592,7 +609,7 @@ static int vlan_dev_init(struct net_devi
+       dev->needed_headroom = real_dev->needed_headroom;
+       if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) {
+-              dev->header_ops      = real_dev->header_ops;
++              dev->header_ops      = &vlan_passthru_header_ops;
+               dev->hard_header_len = real_dev->hard_header_len;
+       } else {
+               dev->header_ops      = &vlan_header_ops;
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -1274,7 +1274,7 @@ int neigh_compat_output(struct neighbour
+       if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
+                           skb->len) < 0 &&
+-          dev->header_ops->rebuild(skb))
++          dev_rebuild_header(skb))
+               return 0;
+       return dev_queue_xmit(skb);
diff --git a/queue-3.12/vxlan-release-rt-when-found-circular-route.patch b/queue-3.12/vxlan-release-rt-when-found-circular-route.patch
new file mode 100644 (file)
index 0000000..9d6964d
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Mon Jan 13 09:44:41 PST 2014
+From: Fan Du <fan.du@windriver.com>
+Date: Mon, 9 Dec 2013 10:33:53 +0800
+Subject: vxlan: release rt when found circular route
+
+From: Fan Du <fan.du@windriver.com>
+
+[ Upstream commit fffc15a5012e9052d3b236efc56840841a125416 ]
+
+Otherwise causing dst memory leakage.
+Have Checked all other type tunnel device transmit implementation,
+no such things happens anymore.
+
+Signed-off-by: Fan Du <fan.du@windriver.com>
+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>
+---
+ drivers/net/vxlan.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1672,7 +1672,7 @@ static void vxlan_xmit_one(struct sk_buf
+                       netdev_dbg(dev, "circular route to %pI4\n",
+                                  &dst->sin.sin_addr.s_addr);
+                       dev->stats.collisions++;
+-                      goto tx_error;
++                      goto rt_tx_error;
+               }
+               /* Bypass encapsulation if the destination is local */