--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -1007,7 +1007,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;
+ }
+
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -871,6 +871,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) {
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -1022,12 +1022,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;
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -752,10 +752,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);
+@@ -771,12 +769,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);
+ }
+net-phy-allow-eee-for-all-rgmii-variants.patch
+ipv4-avoid-crashing-in-ip_error.patch
+bridge-fix-parsing-of-mldv2-reports.patch
+net-dp83640-fix-broken-calibration-routine.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
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -1293,10 +1293,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
+@@ -494,10 +494,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;
+ }
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -1898,6 +1898,10 @@ static long unix_stream_data_wait(struct
+ unix_state_unlock(sk);
+ timeo = 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) {
--- /dev/null
+From foo@baz Sat Jun 13 09:49:42 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
+@@ -33,6 +33,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 *);
+@@ -55,6 +57,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;
+@@ -72,6 +75,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) {
+@@ -132,6 +136,15 @@ static int netback_probe(struct xenbus_d
+ goto fail;
+ }
+
++ 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;
+@@ -162,22 +175,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);