]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 02:55:13 +0000 (11:55 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Nov 2013 02:55:13 +0000 (11:55 +0900)
added patches:
cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
ip_gre-fix-wccpv2-header-parsing.patch
ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
net-flow_dissector-fail-on-evil-iph-ihl.patch
net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
series
virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
xen-netback-transition-to-closed-when-removing-a-vif.patch
xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch

queue-3.10/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch [new file with mode: 0644]
queue-3.10/ip_gre-fix-wccpv2-header-parsing.patch [new file with mode: 0644]
queue-3.10/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch [new file with mode: 0644]
queue-3.10/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch [new file with mode: 0644]
queue-3.10/net-flow_dissector-fail-on-evil-iph-ihl.patch [new file with mode: 0644]
queue-3.10/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch [new file with mode: 0644]
queue-3.10/series [new file with mode: 0644]
queue-3.10/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch [new file with mode: 0644]
queue-3.10/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch [new file with mode: 0644]
queue-3.10/xen-netback-transition-to-closed-when-removing-a-vif.patch [new file with mode: 0644]
queue-3.10/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch [new file with mode: 0644]

diff --git a/queue-3.10/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch b/queue-3.10/cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
new file mode 100644 (file)
index 0000000..b52c22c
--- /dev/null
@@ -0,0 +1,45 @@
+From 932bc4212eab5f74cf876ee60989b23eddaae8f8 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 27 Oct 2013 21:02:39 +0000
+Subject: cxgb3: Fix length calculation in write_ofld_wr() on 32-bit architectures
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit 262e827fe745642589450ae241b7afd3912c3f25 ]
+
+The length calculation here is now invalid on 32-bit architectures,
+since sk_buff::tail is a pointer and sk_buff::transport_header is
+an integer offset:
+
+drivers/net/ethernet/chelsio/cxgb3/sge.c: In function 'write_ofld_wr':
+drivers/net/ethernet/chelsio/cxgb3/sge.c:1603:9: warning: passing argument 4 of 'make_sgl' makes integer from pointer without a cast [enabled by default]
+         adap->pdev);
+         ^
+drivers/net/ethernet/chelsio/cxgb3/sge.c:964:28: note: expected 'unsigned int' but argument is of type 'sk_buff_data_t'
+ static inline unsigned int make_sgl(const struct sk_buff *skb,
+                            ^
+
+Use the appropriate skb accessor functions.
+
+Compile-tested only.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 1a37e412a022 ('net: Use 16bits for *_headers fields of struct skbuff')
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/chelsio/cxgb3/sge.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
++++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
+@@ -1600,7 +1600,8 @@ static void write_ofld_wr(struct adapter
+       flits = skb_transport_offset(skb) / 8;
+       sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
+       sgl_flits = make_sgl(skb, sgp, skb_transport_header(skb),
+-                           skb->tail - skb->transport_header,
++                           skb_tail_pointer(skb) -
++                           skb_transport_header(skb),
+                            adap->pdev);
+       if (need_skb_unmap()) {
+               setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
diff --git a/queue-3.10/ip_gre-fix-wccpv2-header-parsing.patch b/queue-3.10/ip_gre-fix-wccpv2-header-parsing.patch
new file mode 100644 (file)
index 0000000..a0f6ef6
--- /dev/null
@@ -0,0 +1,79 @@
+From 29811f1bf697e68ee5c9c0c8b9f464c16d82d6c7 Mon Sep 17 00:00:00 2001
+From: Pravin B Shelar <pshelar@nicira.com>
+Date: Mon, 28 Oct 2013 10:38:55 -0700
+Subject: ip_gre: Fix WCCPv2 header parsing.
+
+From: Pravin B Shelar <pshelar@nicira.com>
+
+[ No applicable upstream commit, the upstream implementation is
+  now completely different and doesn't have this bug. ]
+
+In case of WCCPv2 GRE header has extra four bytes.  Following
+patch pull those extra four bytes so that skb offsets are set
+correctly.
+
+CC: Eric Dumazet <eric.dumazet@gmail.com>
+Reported-by: Peter Schmitt <peter.schmitt82@yahoo.de>
+Tested-by: Peter Schmitt <peter.schmitt82@yahoo.de>
+Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip_tunnels.h |    2 +-
+ net/ipv4/ip_gre.c        |    2 +-
+ net/ipv4/ip_tunnel.c     |    4 ++--
+ net/ipv4/ipip.c          |    2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/include/net/ip_tunnels.h
++++ b/include/net/ip_tunnels.h
+@@ -113,7 +113,7 @@ struct ip_tunnel *ip_tunnel_lookup(struc
+                                  __be32 key);
+ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+-                const struct tnl_ptk_info *tpi, bool log_ecn_error);
++                const struct tnl_ptk_info *tpi, int hdr_len, bool log_ecn_error);
+ int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
+                        struct ip_tunnel_parm *p);
+ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -335,7 +335,7 @@ static int ipgre_rcv(struct sk_buff *skb
+                                 iph->saddr, iph->daddr, tpi.key);
+       if (tunnel) {
+-              ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
++              ip_tunnel_rcv(tunnel, skb, &tpi, hdr_len, log_ecn_error);
+               return 0;
+       }
+       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -402,7 +402,7 @@ static struct ip_tunnel *ip_tunnel_creat
+ }
+ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+-                const struct tnl_ptk_info *tpi, bool log_ecn_error)
++                const struct tnl_ptk_info *tpi, int hdr_len, bool log_ecn_error)
+ {
+       struct pcpu_tstats *tstats;
+       const struct iphdr *iph = ip_hdr(skb);
+@@ -413,7 +413,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunn
+       skb->protocol = tpi->proto;
+       skb->mac_header = skb->network_header;
+-      __pskb_pull(skb, tunnel->hlen);
++      __pskb_pull(skb, hdr_len);
+       skb_postpull_rcsum(skb, skb_transport_header(skb), tunnel->hlen);
+ #ifdef CONFIG_NET_IPGRE_BROADCAST
+       if (ipv4_is_multicast(iph->daddr)) {
+--- a/net/ipv4/ipip.c
++++ b/net/ipv4/ipip.c
+@@ -195,7 +195,7 @@ static int ipip_rcv(struct sk_buff *skb)
+       if (tunnel) {
+               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+                       goto drop;
+-              return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
++              return ip_tunnel_rcv(tunnel, skb, &tpi, 0, log_ecn_error);
+       }
+       return -1;
diff --git a/queue-3.10/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch b/queue-3.10/ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
new file mode 100644 (file)
index 0000000..271c70b
--- /dev/null
@@ -0,0 +1,68 @@
+From 4f2a19b55d944b754a564552cc8bcbdfa6675b1f Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 24 Oct 2013 07:48:24 +0200
+Subject: ipv6: ip6_dst_check needs to check for expired dst_entries
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit e3bc10bd95d7fcc3f2ac690c6ff22833ea6781d6 ]
+
+On receiving a packet too big icmp error we check if our current cached
+dst_entry in the socket is still valid. This validation check did not
+care about the expiration of the (cached) route.
+
+The error path I traced down:
+The socket receives a packet too big mtu notification. It still has a
+valid dst_entry and thus issues the ip6_rt_pmtu_update on this dst_entry,
+setting RTF_EXPIRE and updates the dst.expiration value (which could
+fail because of not up-to-date expiration values, see previous patch).
+
+In some seldom cases we race with a) the ip6_fib gc or b) another routing
+lookup which would result in a recreation of the cached rt6_info from its
+parent non-cached rt6_info. While copying the rt6_info we reinitialize the
+metrics store by copying it over from the parent thus invalidating the
+just installed pmtu update (both dsts use the same key to the inetpeer
+storage). The dst_entry with the just invalidated metrics data would
+just get its RTF_EXPIRES flag cleared and would continue to stay valid
+for the socket.
+
+We should have not issued the pmtu update on the already expired dst_entry
+in the first placed. By checking the expiration on the dst entry and
+doing a relookup in case it is out of date we close the race because
+we would install a new rt6_info into the fib before we issue the pmtu
+update, thus closing this race.
+
+Not reliably updating the dst.expire value was fixed by the patch "ipv6:
+reset dst.expires value when clearing expire flag".
+
+Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
+Reported-by: Valentijn Sessink <valentyn@blub.net>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Valentijn Sessink <valentyn@blub.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1084,10 +1084,13 @@ static struct dst_entry *ip6_dst_check(s
+       if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
+               return NULL;
+-      if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
+-              return dst;
++      if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
++              return NULL;
++
++      if (rt6_check_expired(rt))
++              return NULL;
+-      return NULL;
++      return dst;
+ }
+ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
diff --git a/queue-3.10/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch b/queue-3.10/ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
new file mode 100644 (file)
index 0000000..4147779
--- /dev/null
@@ -0,0 +1,54 @@
+From 42e8e1242b39e258b3178fcbcade59eda1bb0a73 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 24 Oct 2013 10:14:27 +0200
+Subject: ipv6: reset dst.expires value when clearing expire flag
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 01ba16d6ec85a1ec4669c75513a76b61ec53ee50 ]
+
+On receiving a packet too big icmp error we update the expire value by
+calling rt6_update_expires. This function uses dst_set_expires which is
+implemented that it can only reduce the expiration value of the dst entry.
+
+If we insert new routing non-expiry information into the ipv6 fib where
+we already have a matching rt6_info we only clear the RTF_EXPIRES flag
+in rt6i_flags and leave the dst.expires value as is.
+
+When new mtu information arrives for that cached dst_entry we again
+call dst_set_expires. This time it won't update the dst.expire value
+because we left the dst.expire value intact from the last update. So
+dst_set_expires won't touch dst.expires.
+
+Fix this by resetting dst.expires when clearing the RTF_EXPIRE flag.
+dst_set_expires checks for a zero expiration and updates the
+dst.expires.
+
+In the past this (not updating dst.expires) was necessary because
+dst.expire was placed in a union with the dst_entry *from reference
+and rt6_clean_expires did assign NULL to it. This split happend in
+ecd9883724b78cc72ed92c98bcb1a46c764fff21 ("ipv6: fix race condition
+regarding dst->expires and dst->from").
+
+Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
+Reported-by: Valentijn Sessink <valentyn@blub.net>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Valentijn Sessink <valentyn@blub.net>
+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>
+---
+ include/net/ip6_fib.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/net/ip6_fib.h
++++ b/include/net/ip6_fib.h
+@@ -165,6 +165,7 @@ static inline struct inet6_dev *ip6_dst_
+ static inline void rt6_clean_expires(struct rt6_info *rt)
+ {
+       rt->rt6i_flags &= ~RTF_EXPIRES;
++      rt->dst.expires = 0;
+ }
+ static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
diff --git a/queue-3.10/net-flow_dissector-fail-on-evil-iph-ihl.patch b/queue-3.10/net-flow_dissector-fail-on-evil-iph-ihl.patch
new file mode 100644 (file)
index 0000000..f38cc29
--- /dev/null
@@ -0,0 +1,39 @@
+From 66c176a08e33daf7b619441c46c657adcda93889 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 1 Nov 2013 15:01:10 +0800
+Subject: net: flow_dissector: fail on evil iph->ihl
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 6f092343855a71e03b8d209815d8c45bf3a27fcd ]
+
+We don't validate iph->ihl which may lead a dead loop if we meet a IPIP
+skb whose iph->ihl is zero. Fix this by failing immediately when iph->ihl
+is evil (less than 5).
+
+This issue were introduced by commit ec5efe7946280d1e84603389a1030ccec0a767ae
+(rps: support IPIP encapsulation).
+
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Petr Matousek <pmatouse@redhat.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Daniel Borkmann <dborkman@redhat.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>
+---
+ net/core/flow_dissector.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -40,7 +40,7 @@ again:
+               struct iphdr _iph;
+ ip:
+               iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+-              if (!iph)
++              if (!iph || iph->ihl < 5)
+                       return false;
+               if (ip_is_fragment(iph))
diff --git a/queue-3.10/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch b/queue-3.10/net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
new file mode 100644 (file)
index 0000000..66c48a6
--- /dev/null
@@ -0,0 +1,31 @@
+From d6de8d2b18605c5a5f01cf001bce1bf6ef8765fe Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Date: Sun, 3 Nov 2013 10:04:07 +0200
+Subject: net/mlx4_core: Fix call to __mlx4_unregister_mac
+
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+
+[ Upstream commit c32b7dfbb1dfb3f0a68f250deff65103c8bb704a ]
+
+In function mlx4_master_deactivate_admin_state() __mlx4_unregister_mac was
+called using the MAC index. It should be called with the value of the MAC itself.
+
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cmd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+@@ -1544,7 +1544,7 @@ static void mlx4_master_deactivate_admin
+                       vp_oper->vlan_idx = NO_INDX;
+               }
+               if (NO_INDX != vp_oper->mac_idx) {
+-                      __mlx4_unregister_mac(&priv->dev, port, vp_oper->mac_idx);
++                      __mlx4_unregister_mac(&priv->dev, port, vp_oper->state.mac);
+                       vp_oper->mac_idx = NO_INDX;
+               }
+       }
diff --git a/queue-3.10/series b/queue-3.10/series
new file mode 100644 (file)
index 0000000..bfa876f
--- /dev/null
@@ -0,0 +1,10 @@
+ip_gre-fix-wccpv2-header-parsing.patch
+ipv6-ip6_dst_check-needs-to-check-for-expired-dst_entries.patch
+ipv6-reset-dst.expires-value-when-clearing-expire-flag.patch
+cxgb3-fix-length-calculation-in-write_ofld_wr-on-32-bit-architectures.patch
+xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch
+virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
+net-flow_dissector-fail-on-evil-iph-ihl.patch
+net-mlx4_core-fix-call-to-__mlx4_unregister_mac.patch
+xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
+xen-netback-transition-to-closed-when-removing-a-vif.patch
diff --git a/queue-3.10/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch b/queue-3.10/virtio-net-correctly-handle-cpu-hotplug-notifier-during-resuming.patch
new file mode 100644 (file)
index 0000000..5947cf1
--- /dev/null
@@ -0,0 +1,116 @@
+From c2ad10d575684b896ca1a57c353c038a76dd1d30 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Tue, 29 Oct 2013 15:11:07 +0800
+Subject: virtio-net: correctly handle cpu hotplug notifier during resuming
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit ec9debbd9a88d8ea86c488d6ffcac419ee7d46d9 ]
+
+commit 3ab098df35f8b98b6553edc2e40234af512ba877 (virtio-net: don't respond to
+cpu hotplug notifier if we're not ready) tries to bypass the cpu hotplug
+notifier by checking the config_enable and does nothing is it was false. So it
+need to try to hold the config_lock mutex which may happen in atomic
+environment which leads the following warnings:
+
+[  622.944441] CPU0 attaching NULL sched-domain.
+[  622.944446] CPU1 attaching NULL sched-domain.
+[  622.944485] CPU0 attaching NULL sched-domain.
+[  622.950795] BUG: sleeping function called from invalid context at kernel/mutex.c:616
+[  622.950796] in_atomic(): 1, irqs_disabled(): 1, pid: 10, name: migration/1
+[  622.950796] no locks held by migration/1/10.
+[  622.950798] CPU: 1 PID: 10 Comm: migration/1 Not tainted 3.12.0-rc5-wl-01249-gb91e82d #317
+[  622.950799] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[  622.950802]  0000000000000000 ffff88001d42dba0 ffffffff81a32f22 ffff88001bfb9c70
+[  622.950803]  ffff88001d42dbb0 ffffffff810edb02 ffff88001d42dc38 ffffffff81a396ed
+[  622.950805]  0000000000000046 ffff88001d42dbe8 ffffffff810e861d 0000000000000000
+[  622.950805] Call Trace:
+[  622.950810]  [<ffffffff81a32f22>] dump_stack+0x54/0x74
+[  622.950815]  [<ffffffff810edb02>] __might_sleep+0x112/0x114
+[  622.950817]  [<ffffffff81a396ed>] mutex_lock_nested+0x3c/0x3c6
+[  622.950818]  [<ffffffff810e861d>] ? up+0x39/0x3e
+[  622.950821]  [<ffffffff8153ea7c>] ? acpi_os_signal_semaphore+0x21/0x2d
+[  622.950824]  [<ffffffff81565ed1>] ? acpi_ut_release_mutex+0x5e/0x62
+[  622.950828]  [<ffffffff816d04ec>] virtnet_cpu_callback+0x33/0x87
+[  622.950830]  [<ffffffff81a42576>] notifier_call_chain+0x3c/0x5e
+[  622.950832]  [<ffffffff810e86a8>] __raw_notifier_call_chain+0xe/0x10
+[  622.950835]  [<ffffffff810c5556>] __cpu_notify+0x20/0x37
+[  622.950836]  [<ffffffff810c5580>] cpu_notify+0x13/0x15
+[  622.950838]  [<ffffffff81a237cd>] take_cpu_down+0x27/0x3a
+[  622.950841]  [<ffffffff81136289>] stop_machine_cpu_stop+0x93/0xf1
+[  622.950842]  [<ffffffff81136167>] cpu_stopper_thread+0xa0/0x12f
+[  622.950844]  [<ffffffff811361f6>] ? cpu_stopper_thread+0x12f/0x12f
+[  622.950847]  [<ffffffff81119710>] ? lock_release_holdtime.part.7+0xa3/0xa8
+[  622.950848]  [<ffffffff81135e4b>] ? cpu_stop_should_run+0x3f/0x47
+[  622.950850]  [<ffffffff810ea9b0>] smpboot_thread_fn+0x1c5/0x1e3
+[  622.950852]  [<ffffffff810ea7eb>] ? lg_global_unlock+0x67/0x67
+[  622.950854]  [<ffffffff810e36b7>] kthread+0xd8/0xe0
+[  622.950857]  [<ffffffff81a3bfad>] ? wait_for_common+0x12f/0x164
+[  622.950859]  [<ffffffff810e35df>] ? kthread_create_on_node+0x124/0x124
+[  622.950861]  [<ffffffff81a45ffc>] ret_from_fork+0x7c/0xb0
+[  622.950862]  [<ffffffff810e35df>] ? kthread_create_on_node+0x124/0x124
+[  622.950876] smpboot: CPU 1 is now offline
+[  623.194556] SMP alternatives: lockdep: fixing up alternatives
+[  623.194559] smpboot: Booting Node 0 Processor 1 APIC 0x1
+...
+
+A correct fix is to unregister the hotcpu notifier during restore and register a
+new one in resume.
+
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Tested-by: Fengguang Wu <fengguang.wu@intel.com>
+Cc: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1096,11 +1096,6 @@ static int virtnet_cpu_callback(struct n
+ {
+       struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
+-      mutex_lock(&vi->config_lock);
+-
+-      if (!vi->config_enable)
+-              goto done;
+-
+       switch(action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+@@ -1114,8 +1109,6 @@ static int virtnet_cpu_callback(struct n
+               break;
+       }
+-done:
+-      mutex_unlock(&vi->config_lock);
+       return NOTIFY_OK;
+ }
+@@ -1672,6 +1665,8 @@ static int virtnet_freeze(struct virtio_
+       struct virtnet_info *vi = vdev->priv;
+       int i;
++      unregister_hotcpu_notifier(&vi->nb);
++
+       /* Prevent config work handler from accessing the device */
+       mutex_lock(&vi->config_lock);
+       vi->config_enable = false;
+@@ -1720,6 +1715,10 @@ static int virtnet_restore(struct virtio
+       virtnet_set_queues(vi, vi->curr_queue_pairs);
+       rtnl_unlock();
++      err = register_hotcpu_notifier(&vi->nb);
++      if (err)
++              return err;
++
+       return 0;
+ }
+ #endif
diff --git a/queue-3.10/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch b/queue-3.10/xen-netback-handle-backend-state-transitions-in-a-more-robust-way.patch
new file mode 100644 (file)
index 0000000..47e1cd2
--- /dev/null
@@ -0,0 +1,249 @@
+From 3541fc8387b844547671fba0a0725381cf4b1016 Mon Sep 17 00:00:00 2001
+From: Paul Durrant <Paul.Durrant@citrix.com>
+Date: Thu, 26 Sep 2013 12:09:52 +0100
+Subject: xen-netback: Handle backend state transitions in a more robust way
+
+From: Paul Durrant <Paul.Durrant@citrix.com>
+
+[ Upstream commit ea732dff5cfa10789007bf4a5b935388a0bb2a8f ]
+
+When the frontend state changes netback now specifies its desired state to
+a new function, set_backend_state(), which transitions through any
+necessary intermediate states.
+This fixes an issue observed with some old Windows frontend drivers where
+they failed to transition through the Closing state and netback would not
+behave correctly.
+
+Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Wei Liu <wei.liu2@citrix.com>
+Cc: David Vrabel <david.vrabel@citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/xenbus.c |  149 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 118 insertions(+), 31 deletions(-)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -24,6 +24,12 @@
+ struct backend_info {
+       struct xenbus_device *dev;
+       struct xenvif *vif;
++
++      /* This is the state that will be reflected in xenstore when any
++       * active hotplug script completes.
++       */
++      enum xenbus_state state;
++
+       enum xenbus_state frontend_state;
+       struct xenbus_watch hotplug_status_watch;
+       u8 have_hotplug_status_watch:1;
+@@ -126,6 +132,8 @@ static int netback_probe(struct xenbus_d
+       if (err)
+               goto fail;
++      be->state = XenbusStateInitWait;
++
+       /* This kicks hotplug scripts, so do it immediately. */
+       backend_create_xenvif(be);
+@@ -198,24 +206,113 @@ static void backend_create_xenvif(struct
+       kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
+ }
+-
+-static void disconnect_backend(struct xenbus_device *dev)
++static void backend_disconnect(struct backend_info *be)
+ {
+-      struct backend_info *be = dev_get_drvdata(&dev->dev);
+-
+       if (be->vif)
+               xenvif_disconnect(be->vif);
+ }
+-static void destroy_backend(struct xenbus_device *dev)
++static void backend_connect(struct backend_info *be)
+ {
+-      struct backend_info *be = dev_get_drvdata(&dev->dev);
++      if (be->vif)
++              connect(be);
++}
+-      if (be->vif) {
+-              kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
+-              xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
+-              xenvif_free(be->vif);
+-              be->vif = NULL;
++static inline void backend_switch_state(struct backend_info *be,
++                                      enum xenbus_state state)
++{
++      struct xenbus_device *dev = be->dev;
++
++      pr_debug("%s -> %s\n", dev->nodename, xenbus_strstate(state));
++      be->state = state;
++
++      /* If we are waiting for a hotplug script then defer the
++       * actual xenbus state change.
++       */
++      if (!be->have_hotplug_status_watch)
++              xenbus_switch_state(dev, state);
++}
++
++/* Handle backend state transitions:
++ *
++ * The backend state starts in InitWait and the following transitions are
++ * allowed.
++ *
++ * InitWait -> Connected
++ *
++ *    ^    \         |
++ *    |     \        |
++ *    |      \       |
++ *    |       \      |
++ *    |        \     |
++ *    |         \    |
++ *    |          V   V
++ *
++ *  Closed  <-> Closing
++ *
++ * The state argument specifies the eventual state of the backend and the
++ * function transitions to that state via the shortest path.
++ */
++static void set_backend_state(struct backend_info *be,
++                            enum xenbus_state state)
++{
++      while (be->state != state) {
++              switch (be->state) {
++              case XenbusStateClosed:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateConnected:
++                              pr_info("%s: prepare for reconnect\n",
++                                      be->dev->nodename);
++                              backend_switch_state(be, XenbusStateInitWait);
++                              break;
++                      case XenbusStateClosing:
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateInitWait:
++                      switch (state) {
++                      case XenbusStateConnected:
++                              backend_connect(be);
++                              backend_switch_state(be, XenbusStateConnected);
++                              break;
++                      case XenbusStateClosing:
++                      case XenbusStateClosed:
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateConnected:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateClosing:
++                      case XenbusStateClosed:
++                              backend_disconnect(be);
++                              backend_switch_state(be, XenbusStateClosing);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              case XenbusStateClosing:
++                      switch (state) {
++                      case XenbusStateInitWait:
++                      case XenbusStateConnected:
++                      case XenbusStateClosed:
++                              backend_switch_state(be, XenbusStateClosed);
++                              break;
++                      default:
++                              BUG();
++                      }
++                      break;
++              default:
++                      BUG();
++              }
+       }
+ }
+@@ -227,41 +324,33 @@ static void frontend_changed(struct xenb
+ {
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
+-      pr_debug("frontend state %s", xenbus_strstate(frontend_state));
++      pr_debug("%s -> %s\n", dev->otherend, xenbus_strstate(frontend_state));
+       be->frontend_state = frontend_state;
+       switch (frontend_state) {
+       case XenbusStateInitialising:
+-              if (dev->state == XenbusStateClosed) {
+-                      printk(KERN_INFO "%s: %s: prepare for reconnect\n",
+-                             __func__, dev->nodename);
+-                      xenbus_switch_state(dev, XenbusStateInitWait);
+-              }
++              set_backend_state(be, XenbusStateInitWait);
+               break;
+       case XenbusStateInitialised:
+               break;
+       case XenbusStateConnected:
+-              if (dev->state == XenbusStateConnected)
+-                      break;
+-              if (be->vif)
+-                      connect(be);
++              set_backend_state(be, XenbusStateConnected);
+               break;
+       case XenbusStateClosing:
+-              disconnect_backend(dev);
+-              xenbus_switch_state(dev, XenbusStateClosing);
++              set_backend_state(be, XenbusStateClosing);
+               break;
+       case XenbusStateClosed:
+-              xenbus_switch_state(dev, XenbusStateClosed);
++              set_backend_state(be, XenbusStateClosed);
+               if (xenbus_dev_is_online(dev))
+                       break;
+-              destroy_backend(dev);
+               /* fall through if not online */
+       case XenbusStateUnknown:
++              set_backend_state(be, XenbusStateClosed);
+               device_unregister(&dev->dev);
+               break;
+@@ -354,7 +443,9 @@ static void hotplug_status_changed(struc
+       if (IS_ERR(str))
+               return;
+       if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) {
+-              xenbus_switch_state(be->dev, XenbusStateConnected);
++              /* Complete any pending state change */
++              xenbus_switch_state(be->dev, be->state);
++
+               /* Not interested in this watch anymore. */
+               unregister_hotplug_status_watch(be);
+       }
+@@ -384,12 +475,8 @@ static void connect(struct backend_info
+       err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
+                                  hotplug_status_changed,
+                                  "%s/%s", dev->nodename, "hotplug-status");
+-      if (err) {
+-              /* Switch now, since we can't do a watch. */
+-              xenbus_switch_state(dev, XenbusStateConnected);
+-      } else {
++      if (!err)
+               be->have_hotplug_status_watch = 1;
+-      }
+       netif_wake_queue(be->vif->dev);
+ }
diff --git a/queue-3.10/xen-netback-transition-to-closed-when-removing-a-vif.patch b/queue-3.10/xen-netback-transition-to-closed-when-removing-a-vif.patch
new file mode 100644 (file)
index 0000000..6751f0c
--- /dev/null
@@ -0,0 +1,50 @@
+From 619a333e10f36740f152463d3768b9d69a611068 Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Mon, 7 Oct 2013 13:55:19 +0100
+Subject: xen-netback: transition to CLOSED when removing a VIF
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+[ Upstream commit dc62ccaccfb139d9b04bbc5a2688a4402adbfab3 ]
+
+If a guest is destroyed without transitioning its frontend to CLOSED,
+the domain becomes a zombie as netback was not grant unmapping the
+shared rings.
+
+When removing a VIF, transition the backend to CLOSED so the VIF is
+disconnected if necessary (which will unmap the shared rings etc).
+
+This fixes a regression introduced by
+279f438e36c0a70b23b86d2090aeec50155034a9 (xen-netback: Don't destroy
+the netdev until the vif is shut down).
+
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Wei Liu <wei.liu2@citrix.com>
+Cc: Paul Durrant <Paul.Durrant@citrix.com>
+Acked-by: Wei Liu <wei.liu2@citrix.com>
+Reviewed-by:  Paul Durrant <paul.durrant@citrix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/xenbus.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -39,11 +39,15 @@ static int connect_rings(struct backend_
+ static void connect(struct backend_info *);
+ static void backend_create_xenvif(struct backend_info *be);
+ static void unregister_hotplug_status_watch(struct backend_info *be);
++static void set_backend_state(struct backend_info *be,
++                            enum xenbus_state state);
+ static int netback_remove(struct xenbus_device *dev)
+ {
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
++      set_backend_state(be, XenbusStateClosed);
++
+       unregister_hotplug_status_watch(be);
+       if (be->vif) {
+               kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
diff --git a/queue-3.10/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch b/queue-3.10/xen-netback-use-jiffies_64-value-to-calculate-credit-timeout.patch
new file mode 100644 (file)
index 0000000..737e2d0
--- /dev/null
@@ -0,0 +1,87 @@
+From d279fe2fe398bfd41a7d614ceeb7ad73941e0a51 Mon Sep 17 00:00:00 2001
+From: Wei Liu <wei.liu2@citrix.com>
+Date: Mon, 28 Oct 2013 12:07:57 +0000
+Subject: xen-netback: use jiffies_64 value to calculate credit timeout
+
+From: Wei Liu <wei.liu2@citrix.com>
+
+[ Upstream commit 059dfa6a93b779516321e5112db9d7621b1367ba ]
+
+time_after_eq() only works if the delta is < MAX_ULONG/2.
+
+For a 32bit Dom0, if netfront sends packets at a very low rate, the time
+between subsequent calls to tx_credit_exceeded() may exceed MAX_ULONG/2
+and the test for timer_after_eq() will be incorrect. Credit will not be
+replenished and the guest may become unable to send packets (e.g., if
+prior to the long gap, all credit was exhausted).
+
+Use jiffies_64 variant to mitigate this problem for 32bit Dom0.
+
+Suggested-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Wei Liu <wei.liu2@citrix.com>
+Reviewed-by: David Vrabel <david.vrabel@citrix.com>
+Cc: Ian Campbell <ian.campbell@citrix.com>
+Cc: Jason Luan <jianhai.luan@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/common.h    |    1 +
+ drivers/net/xen-netback/interface.c |    3 +--
+ drivers/net/xen-netback/netback.c   |   10 +++++-----
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -88,6 +88,7 @@ struct xenvif {
+       unsigned long   credit_usec;
+       unsigned long   remaining_credit;
+       struct timer_list credit_timeout;
++      u64 credit_window_start;
+       /* Statistics */
+       unsigned long rx_gso_checksum_fixup;
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -275,8 +275,7 @@ struct xenvif *xenvif_alloc(struct devic
+       vif->credit_bytes = vif->remaining_credit = ~0UL;
+       vif->credit_usec  = 0UL;
+       init_timer(&vif->credit_timeout);
+-      /* Initialize 'expires' now: it's used to track the credit window. */
+-      vif->credit_timeout.expires = jiffies;
++      vif->credit_window_start = get_jiffies_64();
+       dev->netdev_ops = &xenvif_netdev_ops;
+       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -1423,9 +1423,8 @@ out:
+ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size)
+ {
+-      unsigned long now = jiffies;
+-      unsigned long next_credit =
+-              vif->credit_timeout.expires +
++      u64 now = get_jiffies_64();
++      u64 next_credit = vif->credit_window_start +
+               msecs_to_jiffies(vif->credit_usec / 1000);
+       /* Timer could already be pending in rare cases. */
+@@ -1433,8 +1432,8 @@ static bool tx_credit_exceeded(struct xe
+               return true;
+       /* Passed the point where we can replenish credit? */
+-      if (time_after_eq(now, next_credit)) {
+-              vif->credit_timeout.expires = now;
++      if (time_after_eq64(now, next_credit)) {
++              vif->credit_window_start = now;
+               tx_add_credit(vif);
+       }
+@@ -1446,6 +1445,7 @@ static bool tx_credit_exceeded(struct xe
+                       tx_credit_callback;
+               mod_timer(&vif->credit_timeout,
+                         next_credit);
++              vif->credit_window_start = next_credit;
+               return true;
+       }