]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Jun 2015 16:51:30 +0000 (09:51 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Jun 2015 16:51:30 +0000 (09:51 -0700)
added patches:
bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch
bridge-fix-parsing-of-mldv2-reports.patch
ipv4-avoid-crashing-in-ip_error.patch
ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch
net-core-correct-an-over-stringent-device-loop-detection.patch
net-dp83640-fix-broken-calibration-routine.patch
net-dp83640-reinforce-locking-rules.patch
net-phy-allow-eee-for-all-rgmii-variants.patch
net_sched-invoke-attach-after-setting-dev-qdisc.patch
tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch
udp-fix-behavior-of-wrong-checksums.patch
unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch
x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch
xen-netback-read-hotplug-script-once-at-start-of-day.patch

15 files changed:
queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch [new file with mode: 0644]
queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch [new file with mode: 0644]
queue-3.14/ipv4-avoid-crashing-in-ip_error.patch [new file with mode: 0644]
queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch [new file with mode: 0644]
queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch [new file with mode: 0644]
queue-3.14/net-dp83640-fix-broken-calibration-routine.patch [new file with mode: 0644]
queue-3.14/net-dp83640-reinforce-locking-rules.patch [new file with mode: 0644]
queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch [new file with mode: 0644]
queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch [new file with mode: 0644]
queue-3.14/series
queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch [new file with mode: 0644]
queue-3.14/udp-fix-behavior-of-wrong-checksums.patch [new file with mode: 0644]
queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch [new file with mode: 0644]
queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch [new file with mode: 0644]
queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch [new file with mode: 0644]

diff --git a/queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch b/queue-3.14/bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch
new file mode 100644 (file)
index 0000000..3b22b54
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Sat, 6 Jun 2015 06:49:00 -0700
+Subject: bridge: disable softirqs around br_fdb_update to avoid lockup
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+[ Upstream commit c4c832f89dc468cf11dc0dd17206bace44526651 ]
+
+br_fdb_update() can be called in process context in the following way:
+br_fdb_add() -> __br_fdb_add() -> br_fdb_update() (if NTF_USE flag is set)
+so we need to disable softirqs because there are softirq users of the
+hash_lock. One easy way to reproduce this is to modify the bridge utility
+to set NTF_USE, enable stp and then set maxageing to a low value so
+br_fdb_cleanup() is called frequently and then just add new entries in
+a loop. This happens because br_fdb_cleanup() is called from timer/softirq
+context. The spin locks in br_fdb_update were _bh before commit f8ae737deea1
+("[BRIDGE]: forwarding remove unneeded preempt and bh diasables")
+and at the time that commit was correct because br_fdb_update() couldn't be
+called from process context, but that changed after commit:
+292d1398983f ("bridge: add NTF_USE support")
+Using local_bh_disable/enable around br_fdb_update() allows us to keep
+using the spin_lock/unlock in br_fdb_update for the fast-path.
+
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Fixes: 292d1398983f ("bridge: add NTF_USE support")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_fdb.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/bridge/br_fdb.c
++++ b/net/bridge/br_fdb.c
+@@ -705,9 +705,11 @@ static int __br_fdb_add(struct ndmsg *nd
+       int err = 0;
+       if (ndm->ndm_flags & NTF_USE) {
++              local_bh_disable();
+               rcu_read_lock();
+               br_fdb_update(p->br, p, addr, vid, true);
+               rcu_read_unlock();
++              local_bh_enable();
+       } else {
+               spin_lock_bh(&p->br->hash_lock);
+               err = fdb_add_entry(p, addr, ndm->ndm_state,
diff --git a/queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch b/queue-3.14/bridge-fix-parsing-of-mldv2-reports.patch
new file mode 100644 (file)
index 0000000..ec47ad1
--- /dev/null
@@ -0,0 +1,63 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+Date: Fri, 22 May 2015 12:18:59 -0300
+Subject: bridge: fix parsing of MLDv2 reports
+
+From: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+
+[ Upstream commit 47cc84ce0c2fe75c99ea5963c4b5704dd78ead54 ]
+
+When more than a multicast address is present in a MLDv2 report, all but
+the first address is ignored, because the code breaks out of the loop if
+there has not been an error adding that address.
+
+This has caused failures when two guests connected through the bridge
+tried to communicate using IPv6. Neighbor discoveries would not be
+transmitted to the other guest when both used a link-local address and a
+static address.
+
+This only happens when there is a MLDv2 querier in the network.
+
+The fix will only break out of the loop when there is a failure adding a
+multicast address.
+
+The mdb before the patch:
+
+dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp
+dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp
+dev ovirtmgmt port bond0.86 grp ff02::2 temp
+
+After the patch:
+
+dev ovirtmgmt port vnet0 grp ff02::1:ff7d:6603 temp
+dev ovirtmgmt port vnet1 grp ff02::1:ff7d:6604 temp
+dev ovirtmgmt port bond0.86 grp ff02::fb temp
+dev ovirtmgmt port bond0.86 grp ff02::2 temp
+dev ovirtmgmt port bond0.86 grp ff02::d temp
+dev ovirtmgmt port vnet0 grp ff02::1:ff00:76 temp
+dev ovirtmgmt port bond0.86 grp ff02::16 temp
+dev ovirtmgmt port vnet1 grp ff02::1:ff00:77 temp
+dev ovirtmgmt port bond0.86 grp ff02::1:ff00:def temp
+dev ovirtmgmt port bond0.86 grp ff02::1:ffa1:40bf temp
+
+Fixes: 08b202b67264 ("bridge br_multicast: IPv6 MLD support.")
+Reported-by: Rik Theys <Rik.Theys@esat.kuleuven.be>
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@redhat.com>
+Tested-by: Rik Theys <Rik.Theys@esat.kuleuven.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_multicast.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -1056,7 +1056,7 @@ static int br_ip6_multicast_mld2_report(
+               err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
+                                                vid);
+-              if (!err)
++              if (err)
+                       break;
+       }
diff --git a/queue-3.14/ipv4-avoid-crashing-in-ip_error.patch b/queue-3.14/ipv4-avoid-crashing-in-ip_error.patch
new file mode 100644 (file)
index 0000000..c33d361
--- /dev/null
@@ -0,0 +1,60 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Fri, 22 May 2015 04:58:12 -0500
+Subject: ipv4: Avoid crashing in ip_error
+
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+
+[ Upstream commit 381c759d9916c42959515ad34a6d467e24a88e93 ]
+
+ip_error does not check if in_dev is NULL before dereferencing it.
+
+IThe following sequence of calls is possible:
+CPU A                          CPU B
+ip_rcv_finish
+    ip_route_input_noref()
+        ip_route_input_slow()
+                               inetdev_destroy()
+    dst_input()
+
+With the result that a network device can be destroyed while processing
+an input packet.
+
+A crash was triggered with only unicast packets in flight, and
+forwarding enabled on the only network device.   The error condition
+was created by the removal of the network device.
+
+As such it is likely the that error code was -EHOSTUNREACH, and the
+action taken by ip_error (if in_dev had been accessible) would have
+been to not increment any counters and to have tried and likely failed
+to send an icmp error as the network device is going away.
+
+Therefore handle this weird case by just dropping the packet if
+!in_dev.  It will result in dropping the packet sooner, and will not
+result in an actual change of behavior.
+
+Fixes: 251da4130115b ("ipv4: Cache ip_error() routes even when not forwarding.")
+Reported-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
+Tested-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
+Signed-off-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.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/ipv4/route.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -910,6 +910,10 @@ static int ip_error(struct sk_buff *skb)
+       bool send;
+       int code;
++      /* IP on this device is disabled. */
++      if (!in_dev)
++              goto out;
++
+       net = dev_net(rt->dst.dev);
+       if (!IN_DEV_FORWARD(in_dev)) {
+               switch (rt->dst.error) {
diff --git a/queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch b/queue-3.14/ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch
new file mode 100644 (file)
index 0000000..336e58a
--- /dev/null
@@ -0,0 +1,73 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Shawn Bohrer <sbohrer@rgmadvisors.com>
+Date: Wed, 3 Jun 2015 16:27:38 -0500
+Subject: ipv4/udp: Verify multicast group is ours in upd_v4_early_demux()
+
+From: Shawn Bohrer <sbohrer@rgmadvisors.com>
+
+[ Upstream commit 6e540309326188f769e03bb4c6dd8ff6752930c2 ]
+
+421b3885bf6d56391297844f43fb7154a6396e12 "udp: ipv4: Add udp early
+demux" introduced a regression that allowed sockets bound to INADDR_ANY
+to receive packets from multicast groups that the socket had not joined.
+For example a socket that had joined 224.168.2.9 could also receive
+packets from 225.168.2.9 despite not having joined that group if
+ip_early_demux is enabled.
+
+Fix this by calling ip_check_mc_rcu() in udp_v4_early_demux() to verify
+that the multicast packet is indeed ours.
+
+Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
+Reported-by: Yurij M. Plotnikov <Yurij.Plotnikov@oktetlabs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/udp.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -90,6 +90,7 @@
+ #include <linux/socket.h>
+ #include <linux/sockios.h>
+ #include <linux/igmp.h>
++#include <linux/inetdevice.h>
+ #include <linux/in.h>
+ #include <linux/errno.h>
+ #include <linux/timer.h>
+@@ -1922,6 +1923,7 @@ void udp_v4_early_demux(struct sk_buff *
+       struct sock *sk;
+       struct dst_entry *dst;
+       int dif = skb->dev->ifindex;
++      int ours;
+       /* validate the packet */
+       if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))
+@@ -1931,14 +1933,24 @@ void udp_v4_early_demux(struct sk_buff *
+       uh = udp_hdr(skb);
+       if (skb->pkt_type == PACKET_BROADCAST ||
+-          skb->pkt_type == PACKET_MULTICAST)
++          skb->pkt_type == PACKET_MULTICAST) {
++              struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
++
++              if (!in_dev)
++                      return;
++
++              ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
++                                     iph->protocol);
++              if (!ours)
++                      return;
+               sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
+                                                  uh->source, iph->saddr, dif);
+-      else if (skb->pkt_type == PACKET_HOST)
++      } else if (skb->pkt_type == PACKET_HOST) {
+               sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
+                                            uh->source, iph->saddr, dif);
+-      else
++      } else {
+               return;
++      }
+       if (!sk)
+               return;
diff --git a/queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch b/queue-3.14/net-core-correct-an-over-stringent-device-loop-detection.patch
new file mode 100644 (file)
index 0000000..8e3eab8
--- /dev/null
@@ -0,0 +1,53 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Vlad Yasevich <vyasevich@gmail.com>
+Date: Sat, 2 May 2015 21:33:44 -0400
+Subject: net: core: Correct an over-stringent device loop detection.
+
+From: Vlad Yasevich <vyasevich@gmail.com>
+
+[ Upstream commit d66bf7dd27573ee5ea90484899ee952c19ccb194 ]
+
+The code in __netdev_upper_dev_link() has an over-stringent
+loop detection logic that actually prevents valid configurations
+from working correctly.
+
+In particular, the logic returns an error if an upper device
+is already in the list of all upper devices for a given dev.
+This particular check seems to be a overzealous as it disallows
+perfectly valid configurations.  For example:
+  # ip l a link eth0 name eth0.10 type vlan id 10
+  # ip l a dev br0 typ bridge
+  # ip l s eth0.10 master br0
+  # ip l s eth0 master br0  <--- Will fail
+
+If you switch the last two commands (add eth0 first), then both
+will succeed.  If after that, you remove eth0 and try to re-add
+it, it will fail!
+
+It appears to be enough to simply check adj_list to keeps things
+safe.
+
+I've tried stacking multiple devices multiple times in all different
+combinations, and either rx_handler registration prevented the stacking
+of the device linking cought the error.
+
+Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
+Acked-by: Jiri Pirko <jiri@resnulli.us>
+Acked-by: Veaceslav Falico <vfalico@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4903,7 +4903,7 @@ static int __netdev_upper_dev_link(struc
+       if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper))
+               return -EBUSY;
+-      if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper))
++      if (__netdev_find_adj(dev, upper_dev, &dev->adj_list.upper))
+               return -EEXIST;
+       if (master && netdev_master_upper_dev_get(dev))
diff --git a/queue-3.14/net-dp83640-fix-broken-calibration-routine.patch b/queue-3.14/net-dp83640-fix-broken-calibration-routine.patch
new file mode 100644 (file)
index 0000000..b094b42
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Richard Cochran <richardcochran@gmail.com>
+Date: Mon, 25 May 2015 11:55:43 +0200
+Subject: net: dp83640: fix broken calibration routine.
+
+From: Richard Cochran <richardcochran@gmail.com>
+
+[ Upstream commit 397a253af5031de4a4612210055935309af4472c ]
+
+Currently, the calibration function that corrects the initial offsets
+among multiple devices only works the first time.  If the function is
+called more than once, the calibration fails and bogus offsets will be
+programmed into the devices.
+
+In a well hidden spot, the device documentation tells that trigger indexes
+0 and 1 are special in allowing the TRIG_IF_LATE flag to actually work.
+
+This patch fixes the issue by using one of the special triggers during the
+recalibration method.
+
+Signed-off-by: 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/phy/dp83640.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/phy/dp83640.c
++++ b/drivers/net/phy/dp83640.c
+@@ -45,7 +45,7 @@
+ #define PSF_TX                0x1000
+ #define EXT_EVENT     1
+ #define CAL_EVENT     7
+-#define CAL_TRIGGER   7
++#define CAL_TRIGGER   1
+ #define PER_TRIGGER   6
+ #define MII_DP83640_MICR 0x11
diff --git a/queue-3.14/net-dp83640-reinforce-locking-rules.patch b/queue-3.14/net-dp83640-reinforce-locking-rules.patch
new file mode 100644 (file)
index 0000000..76ea0e0
--- /dev/null
@@ -0,0 +1,77 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Richard Cochran <richardcochran@gmail.com>
+Date: Mon, 25 May 2015 11:55:44 +0200
+Subject: net: dp83640: reinforce locking rules.
+
+From: Richard Cochran <richardcochran@gmail.com>
+
+[ Upstream commit a935865c828c8cd20501f618c69f659a5b6d6a5f ]
+
+Callers of the ext_write function are supposed to hold a mutex that
+protects the state of the dialed page, but one caller was missing the
+lock from the very start, and over time the code has been changed
+without following the rule.  This patch cleans up the call sites in
+violation of the rule.
+
+Signed-off-by: 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/phy/dp83640.c |   17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/dp83640.c
++++ b/drivers/net/phy/dp83640.c
+@@ -442,7 +442,9 @@ static int ptp_dp83640_enable(struct ptp
+                       else
+                               evnt |= EVNT_RISE;
+               }
++              mutex_lock(&clock->extreg_lock);
+               ext_write(0, phydev, PAGE5, PTP_EVNT, evnt);
++              mutex_unlock(&clock->extreg_lock);
+               return 0;
+       case PTP_CLK_REQ_PEROUT:
+@@ -463,6 +465,8 @@ static u8 status_frame_src[6] = { 0x08,
+ static void enable_status_frames(struct phy_device *phydev, bool on)
+ {
++      struct dp83640_private *dp83640 = phydev->priv;
++      struct dp83640_clock *clock = dp83640->clock;
+       u16 cfg0 = 0, ver;
+       if (on)
+@@ -470,9 +474,13 @@ static void enable_status_frames(struct
+       ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT;
++      mutex_lock(&clock->extreg_lock);
++
+       ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0);
+       ext_write(0, phydev, PAGE6, PSF_CFG1, ver);
++      mutex_unlock(&clock->extreg_lock);
++
+       if (!phydev->attached_dev) {
+               pr_warn("expected to find an attached netdevice\n");
+               return;
+@@ -1063,11 +1071,18 @@ static int dp83640_config_init(struct ph
+       if (clock->chosen && !list_empty(&clock->phylist))
+               recalibrate(clock);
+-      else
++      else {
++              mutex_lock(&clock->extreg_lock);
+               enable_broadcast(phydev, clock->page, 1);
++              mutex_unlock(&clock->extreg_lock);
++      }
+       enable_status_frames(phydev, true);
++
++      mutex_lock(&clock->extreg_lock);
+       ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE);
++      mutex_unlock(&clock->extreg_lock);
++
+       return 0;
+ }
diff --git a/queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch b/queue-3.14/net-phy-allow-eee-for-all-rgmii-variants.patch
new file mode 100644 (file)
index 0000000..89829ff
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Fri, 15 May 2015 16:30:41 -0700
+Subject: net: phy: Allow EEE for all RGMII variants
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 7e14069651591c81046ffaec13c3dac8cb70f5fb ]
+
+RGMII interfaces come in multiple flavors: RGMII with transmit or
+receive internal delay, no delays at all, or delays in both direction.
+
+This change extends the initial check for PHY_INTERFACE_MODE_RGMII to
+cover all of these variants since EEE should be allowed for any of these
+modes, since it is a property of the RGMII, hence Gigabit PHY capability
+more than the RGMII electrical interface and its delays.
+
+Fixes: a59a4d192166 ("phy: add the EEE support and the way to access to the MMD registers")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -965,12 +965,14 @@ int phy_init_eee(struct phy_device *phyd
+ {
+       /* According to 802.3az,the EEE is supported only in full duplex-mode.
+        * Also EEE feature is active when core is operating with MII, GMII
+-       * or RGMII.
++       * or RGMII (all kinds). Internal PHYs are also allowed to proceed and
++       * should return an error if they do not support EEE.
+        */
+       if ((phydev->duplex == DUPLEX_FULL) &&
+           ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
+           (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
+-          (phydev->interface == PHY_INTERFACE_MODE_RGMII))) {
++           (phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
++            phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID))) {
+               int eee_lp, eee_cap, eee_adv;
+               u32 lp, cap, adv;
+               int status;
diff --git a/queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch b/queue-3.14/net_sched-invoke-attach-after-setting-dev-qdisc.patch
new file mode 100644 (file)
index 0000000..cc45863
--- /dev/null
@@ -0,0 +1,110 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: WANG Cong <xiyou.wangcong@gmail.com>
+Date: Tue, 26 May 2015 16:08:48 -0700
+Subject: net_sched: invoke ->attach() after setting dev->qdisc
+
+From: WANG Cong <xiyou.wangcong@gmail.com>
+
+[ Upstream commit 86e363dc3b50bfd50a1f315934583fbda673ab8d ]
+
+For mq qdisc, we add per tx queue qdisc to root qdisc
+for display purpose, however, that happens too early,
+before the new dev->qdisc is finally set, this causes
+q->list points to an old root qdisc which is going to be
+freed right before assigning with a new one.
+
+Fix this by moving ->attach() after setting dev->qdisc.
+
+For the record, this fixes the following crash:
+
+ ------------[ cut here ]------------
+ WARNING: CPU: 1 PID: 975 at lib/list_debug.c:59 __list_del_entry+0x5a/0x98()
+ list_del corruption. prev->next should be ffff8800d1998ae8, but was 6b6b6b6b6b6b6b6b
+ CPU: 1 PID: 975 Comm: tc Not tainted 4.1.0-rc4+ #1019
+ Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+  0000000000000009 ffff8800d73fb928 ffffffff81a44e7f 0000000047574756
+  ffff8800d73fb978 ffff8800d73fb968 ffffffff810790da ffff8800cfc4cd20
+  ffffffff814e725b ffff8800d1998ae8 ffffffff82381250 0000000000000000
+ Call Trace:
+  [<ffffffff81a44e7f>] dump_stack+0x4c/0x65
+  [<ffffffff810790da>] warn_slowpath_common+0x9c/0xb6
+  [<ffffffff814e725b>] ? __list_del_entry+0x5a/0x98
+  [<ffffffff81079162>] warn_slowpath_fmt+0x46/0x48
+  [<ffffffff81820eb0>] ? dev_graft_qdisc+0x5e/0x6a
+  [<ffffffff814e725b>] __list_del_entry+0x5a/0x98
+  [<ffffffff814e72a7>] list_del+0xe/0x2d
+  [<ffffffff81822f05>] qdisc_list_del+0x1e/0x20
+  [<ffffffff81820cd1>] qdisc_destroy+0x30/0xd6
+  [<ffffffff81822676>] qdisc_graft+0x11d/0x243
+  [<ffffffff818233c1>] tc_get_qdisc+0x1a6/0x1d4
+  [<ffffffff810b5eaf>] ? mark_lock+0x2e/0x226
+  [<ffffffff817ff8f5>] rtnetlink_rcv_msg+0x181/0x194
+  [<ffffffff817ff72e>] ? rtnl_lock+0x17/0x19
+  [<ffffffff817ff72e>] ? rtnl_lock+0x17/0x19
+  [<ffffffff817ff774>] ? __rtnl_unlock+0x17/0x17
+  [<ffffffff81855dc6>] netlink_rcv_skb+0x4d/0x93
+  [<ffffffff817ff756>] rtnetlink_rcv+0x26/0x2d
+  [<ffffffff818544b2>] netlink_unicast+0xcb/0x150
+  [<ffffffff81161db9>] ? might_fault+0x59/0xa9
+  [<ffffffff81854f78>] netlink_sendmsg+0x4fa/0x51c
+  [<ffffffff817d6e09>] sock_sendmsg_nosec+0x12/0x1d
+  [<ffffffff817d8967>] sock_sendmsg+0x29/0x2e
+  [<ffffffff817d8cf3>] ___sys_sendmsg+0x1b4/0x23a
+  [<ffffffff8100a1b8>] ? native_sched_clock+0x35/0x37
+  [<ffffffff810a1d83>] ? sched_clock_local+0x12/0x72
+  [<ffffffff810a1fd4>] ? sched_clock_cpu+0x9e/0xb7
+  [<ffffffff810def2a>] ? current_kernel_time+0xe/0x32
+  [<ffffffff810b4bc5>] ? lock_release_holdtime.part.29+0x71/0x7f
+  [<ffffffff810ddebf>] ? read_seqcount_begin.constprop.27+0x5f/0x76
+  [<ffffffff810b6292>] ? trace_hardirqs_on_caller+0x17d/0x199
+  [<ffffffff811b14d5>] ? __fget_light+0x50/0x78
+  [<ffffffff817d9808>] __sys_sendmsg+0x42/0x60
+  [<ffffffff817d9838>] SyS_sendmsg+0x12/0x1c
+  [<ffffffff81a50e97>] system_call_fastpath+0x12/0x6f
+ ---[ end trace ef29d3fb28e97ae7 ]---
+
+For long term, we probably need to clean up the qdisc_graft() code
+in case it hides other bugs like this.
+
+Fixes: 95dc19299f74 ("pkt_sched: give visibility to mq slave qdiscs")
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.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/sched/sch_api.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -812,10 +812,8 @@ static int qdisc_graft(struct net_device
+               if (dev->flags & IFF_UP)
+                       dev_deactivate(dev);
+-              if (new && new->ops->attach) {
+-                      new->ops->attach(new);
+-                      num_q = 0;
+-              }
++              if (new && new->ops->attach)
++                      goto skip;
+               for (i = 0; i < num_q; i++) {
+                       struct netdev_queue *dev_queue = dev_ingress_queue(dev);
+@@ -831,12 +829,16 @@ static int qdisc_graft(struct net_device
+                               qdisc_destroy(old);
+               }
++skip:
+               if (!ingress) {
+                       notify_and_destroy(net, skb, n, classid,
+                                          dev->qdisc, new);
+                       if (new && !new->ops->attach)
+                               atomic_inc(&new->refcnt);
+                       dev->qdisc = new ? : &noop_qdisc;
++
++                      if (new && new->ops->attach)
++                              new->ops->attach(new);
+               } else {
+                       notify_and_destroy(net, skb, n, classid, old, new);
+               }
index 47644bd3afc16a23c53cf64ebdf771c87ba45fc0..277ee78235248f4901623e1c5a3d2ae3432935b3 100644 (file)
@@ -1 +1,15 @@
 crush-ensuring-at-most-num-rep-osds-are-selected.patch
+net-core-correct-an-over-stringent-device-loop-detection.patch
+x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch
+net-phy-allow-eee-for-all-rgmii-variants.patch
+tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch
+ipv4-avoid-crashing-in-ip_error.patch
+bridge-fix-parsing-of-mldv2-reports.patch
+net-dp83640-fix-broken-calibration-routine.patch
+net-dp83640-reinforce-locking-rules.patch
+unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch
+net_sched-invoke-attach-after-setting-dev-qdisc.patch
+udp-fix-behavior-of-wrong-checksums.patch
+xen-netback-read-hotplug-script-once-at-start-of-day.patch
+ipv4-udp-verify-multicast-group-is-ours-in-upd_v4_early_demux.patch
+bridge-disable-softirqs-around-br_fdb_update-to-avoid-lockup.patch
diff --git a/queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch b/queue-3.14/tcp-ipv6-fix-flow-label-setting-in-time_wait-state.patch
new file mode 100644 (file)
index 0000000..ce802df
--- /dev/null
@@ -0,0 +1,48 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
+Date: Sat, 16 May 2015 00:24:59 +0200
+Subject: tcp/ipv6: fix flow label setting in TIME_WAIT state
+
+From: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
+
+[ Upstream commit 21858cd02dabcf290564cbf4769b101eba54d7bb ]
+
+commit 1d13a96c74fc ("ipv6: tcp: fix flowlabel value in ACK messages
+send from TIME_WAIT") added the flow label in the last TCP packets.
+Unfortunately, it was not casted properly.
+
+This patch replace the buggy shift with be32_to_cpu/cpu_to_be32.
+
+Fixes: 1d13a96c74fc ("ipv6: tcp: fix flowlabel value in ACK messages")
+Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
+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/ipv4/tcp_minisocks.c |    2 +-
+ net/ipv6/tcp_ipv6.c      |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -297,7 +297,7 @@ void tcp_time_wait(struct sock *sk, int
+                       tw->tw_v6_daddr = sk->sk_v6_daddr;
+                       tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
+                       tw->tw_tclass = np->tclass;
+-                      tw->tw_flowlabel = np->flow_label >> 12;
++                      tw->tw_flowlabel = be32_to_cpu(np->flow_label & IPV6_FLOWLABEL_MASK);
+                       tw->tw_ipv6only = np->ipv6only;
+               }
+ #endif
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -905,7 +905,7 @@ static void tcp_v6_timewait_ack(struct s
+                       tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
+                       tcp_time_stamp + tcptw->tw_ts_offset,
+                       tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw),
+-                      tw->tw_tclass, (tw->tw_flowlabel << 12));
++                      tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel));
+       inet_twsk_put(tw);
+ }
diff --git a/queue-3.14/udp-fix-behavior-of-wrong-checksums.patch b/queue-3.14/udp-fix-behavior-of-wrong-checksums.patch
new file mode 100644 (file)
index 0000000..00bd32a
--- /dev/null
@@ -0,0 +1,63 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Eric Dumazet <edumazet@google.com>
+Date: Sat, 30 May 2015 09:16:53 -0700
+Subject: udp: fix behavior of wrong checksums
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit beb39db59d14990e401e235faf66a6b9b31240b0 ]
+
+We have two problems in UDP stack related to bogus checksums :
+
+1) We return -EAGAIN to application even if receive queue is not empty.
+   This breaks applications using edge trigger epoll()
+
+2) Under UDP flood, we can loop forever without yielding to other
+   processes, potentially hanging the host, especially on non SMP.
+
+This patch is an attempt to make things better.
+
+We might in the future add extra support for rt applications
+wanting to better control time spent doing a recv() in a hostile
+environment. For example we could validate checksums before queuing
+packets in socket receive queue.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/udp.c |    6 ++----
+ net/ipv6/udp.c |    6 ++----
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1317,10 +1317,8 @@ csum_copy_err:
+       }
+       unlock_sock_fast(sk, slow);
+-      if (noblock)
+-              return -EAGAIN;
+-
+-      /* starting over for a new packet */
++      /* starting over for a new packet, but check if we need to yield */
++      cond_resched();
+       msg->msg_flags &= ~MSG_TRUNC;
+       goto try_again;
+ }
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -515,10 +515,8 @@ csum_copy_err:
+       }
+       unlock_sock_fast(sk, slow);
+-      if (noblock)
+-              return -EAGAIN;
+-
+-      /* starting over for a new packet */
++      /* starting over for a new packet, but check if we need to yield */
++      cond_resched();
+       msg->msg_flags &= ~MSG_TRUNC;
+       goto try_again;
+ }
diff --git a/queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch b/queue-3.14/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch
new file mode 100644 (file)
index 0000000..86c79f4
--- /dev/null
@@ -0,0 +1,71 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Tue, 26 May 2015 08:22:19 -0700
+Subject: unix/caif: sk_socket can disappear when state is unlocked
+
+From: Mark Salyzyn <salyzyn@android.com>
+
+[ Upstream commit b48732e4a48d80ed4a14812f0bab09560846514e ]
+
+got a rare NULL pointer dereference in clear_bit
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+----
+v2: switch to sock_flag(sk, SOCK_DEAD) and added net/caif/caif_socket.c
+v3: return -ECONNRESET in upstream caller of wait function for SOCK_DEAD
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/caif/caif_socket.c |    8 ++++++++
+ net/unix/af_unix.c     |    8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+--- a/net/caif/caif_socket.c
++++ b/net/caif/caif_socket.c
+@@ -332,6 +332,10 @@ static long caif_stream_data_wait(struct
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
++
++              if (sock_flag(sk, SOCK_DEAD))
++                      break;
++
+               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       }
+@@ -376,6 +380,10 @@ static int caif_stream_recvmsg(struct ki
+               struct sk_buff *skb;
+               lock_sock(sk);
++              if (sock_flag(sk, SOCK_DEAD)) {
++                      err = -ECONNRESET;
++                      goto unlock;
++              }
+               skb = skb_dequeue(&sk->sk_receive_queue);
+               caif_check_flow_release(sk);
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1893,6 +1893,10 @@ static long unix_stream_data_wait(struct
+               unix_state_unlock(sk);
+               timeo = freezable_schedule_timeout(timeo);
+               unix_state_lock(sk);
++
++              if (sock_flag(sk, SOCK_DEAD))
++                      break;
++
+               clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+       }
+@@ -1957,6 +1961,10 @@ static int unix_stream_recvmsg(struct ki
+               struct sk_buff *skb, *last;
+               unix_state_lock(sk);
++              if (sock_flag(sk, SOCK_DEAD)) {
++                      err = -ECONNRESET;
++                      goto unlock;
++              }
+               last = skb = skb_peek(&sk->sk_receive_queue);
+ again:
+               if (skb == NULL) {
diff --git a/queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch b/queue-3.14/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch
new file mode 100644 (file)
index 0000000..10b237a
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Alexei Starovoitov <ast@plumgrid.com>
+Date: Fri, 22 May 2015 15:42:55 -0700
+Subject: x86: bpf_jit: fix compilation of large bpf programs
+
+From: Alexei Starovoitov <ast@plumgrid.com>
+
+[ Upstream commit 3f7352bf21f8fd7ba3e2fcef9488756f188e12be ]
+
+x86 has variable length encoding. x86 JIT compiler is trying
+to pick the shortest encoding for given bpf instruction.
+While doing so the jump targets are changing, so JIT is doing
+multiple passes over the program. Typical program needs 3 passes.
+Some very short programs converge with 2 passes. Large programs
+may need 4 or 5. But specially crafted bpf programs may hit the
+pass limit and if the program converges on the last iteration
+the JIT compiler will be producing an image full of 'int 3' insns.
+Fix this corner case by doing final iteration over bpf program.
+
+Fixes: 0a14842f5a3c ("net: filter: Just In Time compiler for x86-64")
+Reported-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
+Tested-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/net/bpf_jit_comp.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -211,7 +211,12 @@ void bpf_jit_compile(struct sk_filter *f
+       }
+       cleanup_addr = proglen; /* epilogue address */
+-      for (pass = 0; pass < 10; pass++) {
++      /* JITed image shrinks with every pass and the loop iterates
++       * until the image stops shrinking. Very large bpf programs
++       * may converge on the last pass. In such case do one more
++       * pass to emit the final image
++       */
++      for (pass = 0; pass < 10 || image; pass++) {
+               u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
+               /* no prologue/epilogue for trivial filters (RET something) */
+               proglen = 0;
diff --git a/queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch b/queue-3.14/xen-netback-read-hotplug-script-once-at-start-of-day.patch
new file mode 100644 (file)
index 0000000..bd22384
--- /dev/null
@@ -0,0 +1,117 @@
+From foo@baz Sat Jun 13 09:49:06 PDT 2015
+From: Ian Campbell <Ian.Campbell@citrix.com>
+Date: Mon, 1 Jun 2015 11:30:24 +0100
+Subject: xen: netback: read hotplug script once at start of day.
+
+From: Ian Campbell <Ian.Campbell@citrix.com>
+
+[ Upstream commit 31a418986a5852034d520a5bab546821ff1ccf3d ]
+
+When we come to tear things down in netback_remove() and generate the
+uevent it is possible that the xenstore directory has already been
+removed (details below).
+
+In such cases netback_uevent() won't be able to read the hotplug
+script and will write a xenstore error node.
+
+A recent change to the hypervisor exposed this race such that we now
+sometimes lose it (where apparently we didn't ever before).
+
+Instead read the hotplug script configuration during setup and use it
+for the lifetime of the backend device.
+
+The apparently more obvious fix of moving the transition to
+state=Closed in netback_remove() to after the uevent does not work
+because it is possible that we are already in state=Closed (in
+reaction to the guest having disconnected as it shutdown). Being
+already in Closed means the toolstack is at liberty to start tearing
+down the xenstore directories. In principal it might be possible to
+arrange to unregister the device sooner (e.g on transition to Closing)
+such that xenstore would still be there but this state machine is
+fragile and prone to anger...
+
+A modern Xen system only relies on the hotplug uevent for driver
+domains, when the backend is in the same domain as the toolstack it
+will run the necessary setup/teardown directly in the correct sequence
+wrt xenstore changes.
+
+Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
+Acked-by: Wei Liu <wei.liu2@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 |   33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -32,6 +32,8 @@ struct backend_info {
+       enum xenbus_state frontend_state;
+       struct xenbus_watch hotplug_status_watch;
+       u8 have_hotplug_status_watch:1;
++
++      const char *hotplug_script;
+ };
+ static int connect_rings(struct backend_info *);
+@@ -54,6 +56,7 @@ static int netback_remove(struct xenbus_
+               xenvif_free(be->vif);
+               be->vif = NULL;
+       }
++      kfree(be->hotplug_script);
+       kfree(be);
+       dev_set_drvdata(&dev->dev, NULL);
+       return 0;
+@@ -71,6 +74,7 @@ static int netback_probe(struct xenbus_d
+       struct xenbus_transaction xbt;
+       int err;
+       int sg;
++      const char *script;
+       struct backend_info *be = kzalloc(sizeof(struct backend_info),
+                                         GFP_KERNEL);
+       if (!be) {
+@@ -157,6 +161,15 @@ static int netback_probe(struct xenbus_d
+       if (err)
+               pr_debug("Error writing feature-split-event-channels\n");
++      script = xenbus_read(XBT_NIL, dev->nodename, "script", NULL);
++      if (IS_ERR(script)) {
++              err = PTR_ERR(script);
++              xenbus_dev_fatal(dev, err, "reading script");
++              goto fail;
++      }
++
++      be->hotplug_script = script;
++
+       err = xenbus_switch_state(dev, XenbusStateInitWait);
+       if (err)
+               goto fail;
+@@ -187,22 +200,14 @@ static int netback_uevent(struct xenbus_
+                         struct kobj_uevent_env *env)
+ {
+       struct backend_info *be = dev_get_drvdata(&xdev->dev);
+-      char *val;
+-      val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
+-      if (IS_ERR(val)) {
+-              int err = PTR_ERR(val);
+-              xenbus_dev_fatal(xdev, err, "reading script");
+-              return err;
+-      } else {
+-              if (add_uevent_var(env, "script=%s", val)) {
+-                      kfree(val);
+-                      return -ENOMEM;
+-              }
+-              kfree(val);
+-      }
++      if (!be)
++              return 0;
++
++      if (add_uevent_var(env, "script=%s", be->hotplug_script))
++              return -ENOMEM;
+-      if (!be || !be->vif)
++      if (!be->vif)
+               return 0;
+       return add_uevent_var(env, "vif=%s", be->vif->dev->name);