From 7c1e2c0011ea329ee38c99ff7d4bc62d563b238c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 13 Jun 2015 10:01:59 -0700 Subject: [PATCH] 3.10-stable patches added patches: bridge-fix-parsing-of-mldv2-reports.patch ipv4-avoid-crashing-in-ip_error.patch net-dp83640-fix-broken-calibration-routine.patch net-phy-allow-eee-for-all-rgmii-variants.patch net_sched-invoke-attach-after-setting-dev-qdisc.patch udp-fix-behavior-of-wrong-checksums.patch unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch xen-netback-read-hotplug-script-once-at-start-of-day.patch --- .../bridge-fix-parsing-of-mldv2-reports.patch | 63 ++++++++++ .../ipv4-avoid-crashing-in-ip_error.patch | 60 +++++++++ ...83640-fix-broken-calibration-routine.patch | 38 ++++++ ...phy-allow-eee-for-all-rgmii-variants.patch | 44 +++++++ ...nvoke-attach-after-setting-dev-qdisc.patch | 110 ++++++++++++++++ queue-3.10/series | 8 ++ .../udp-fix-behavior-of-wrong-checksums.patch | 63 ++++++++++ ...can-disappear-when-state-is-unlocked.patch | 71 +++++++++++ ...-hotplug-script-once-at-start-of-day.patch | 117 ++++++++++++++++++ 9 files changed, 574 insertions(+) create mode 100644 queue-3.10/bridge-fix-parsing-of-mldv2-reports.patch create mode 100644 queue-3.10/ipv4-avoid-crashing-in-ip_error.patch create mode 100644 queue-3.10/net-dp83640-fix-broken-calibration-routine.patch create mode 100644 queue-3.10/net-phy-allow-eee-for-all-rgmii-variants.patch create mode 100644 queue-3.10/net_sched-invoke-attach-after-setting-dev-qdisc.patch create mode 100644 queue-3.10/udp-fix-behavior-of-wrong-checksums.patch create mode 100644 queue-3.10/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch create mode 100644 queue-3.10/xen-netback-read-hotplug-script-once-at-start-of-day.patch diff --git a/queue-3.10/bridge-fix-parsing-of-mldv2-reports.patch b/queue-3.10/bridge-fix-parsing-of-mldv2-reports.patch new file mode 100644 index 00000000000..e7a2555fa1f --- /dev/null +++ b/queue-3.10/bridge-fix-parsing-of-mldv2-reports.patch @@ -0,0 +1,63 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Thadeu Lima de Souza Cascardo +Date: Fri, 22 May 2015 12:18:59 -0300 +Subject: bridge: fix parsing of MLDv2 reports + +From: Thadeu Lima de Souza Cascardo + +[ 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 +Signed-off-by: Thadeu Lima de Souza Cascardo +Tested-by: Rik Theys +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + diff --git a/queue-3.10/ipv4-avoid-crashing-in-ip_error.patch b/queue-3.10/ipv4-avoid-crashing-in-ip_error.patch new file mode 100644 index 00000000000..f579a6ff03c --- /dev/null +++ b/queue-3.10/ipv4-avoid-crashing-in-ip_error.patch @@ -0,0 +1,60 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: "Eric W. Biederman" +Date: Fri, 22 May 2015 04:58:12 -0500 +Subject: ipv4: Avoid crashing in ip_error + +From: "Eric W. Biederman" + +[ 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 +Tested-by: Vittorio Gambaletta +Signed-off-by: Vittorio Gambaletta +Signed-off-by: "Eric W. Biederman" +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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) { diff --git a/queue-3.10/net-dp83640-fix-broken-calibration-routine.patch b/queue-3.10/net-dp83640-fix-broken-calibration-routine.patch new file mode 100644 index 00000000000..d0532d25ac6 --- /dev/null +++ b/queue-3.10/net-dp83640-fix-broken-calibration-routine.patch @@ -0,0 +1,38 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Richard Cochran +Date: Mon, 25 May 2015 11:55:43 +0200 +Subject: net: dp83640: fix broken calibration routine. + +From: Richard Cochran + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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.10/net-phy-allow-eee-for-all-rgmii-variants.patch b/queue-3.10/net-phy-allow-eee-for-all-rgmii-variants.patch new file mode 100644 index 00000000000..f2f1e349a72 --- /dev/null +++ b/queue-3.10/net-phy-allow-eee-for-all-rgmii-variants.patch @@ -0,0 +1,44 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Florian Fainelli +Date: Fri, 15 May 2015 16:30:41 -0700 +Subject: net: phy: Allow EEE for all RGMII variants + +From: Florian Fainelli + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-3.10/net_sched-invoke-attach-after-setting-dev-qdisc.patch b/queue-3.10/net_sched-invoke-attach-after-setting-dev-qdisc.patch new file mode 100644 index 00000000000..c0ecac851df --- /dev/null +++ b/queue-3.10/net_sched-invoke-attach-after-setting-dev-qdisc.patch @@ -0,0 +1,110 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: WANG Cong +Date: Tue, 26 May 2015 16:08:48 -0700 +Subject: net_sched: invoke ->attach() after setting dev->qdisc + +From: WANG Cong + +[ 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: + [] dump_stack+0x4c/0x65 + [] warn_slowpath_common+0x9c/0xb6 + [] ? __list_del_entry+0x5a/0x98 + [] warn_slowpath_fmt+0x46/0x48 + [] ? dev_graft_qdisc+0x5e/0x6a + [] __list_del_entry+0x5a/0x98 + [] list_del+0xe/0x2d + [] qdisc_list_del+0x1e/0x20 + [] qdisc_destroy+0x30/0xd6 + [] qdisc_graft+0x11d/0x243 + [] tc_get_qdisc+0x1a6/0x1d4 + [] ? mark_lock+0x2e/0x226 + [] rtnetlink_rcv_msg+0x181/0x194 + [] ? rtnl_lock+0x17/0x19 + [] ? rtnl_lock+0x17/0x19 + [] ? __rtnl_unlock+0x17/0x17 + [] netlink_rcv_skb+0x4d/0x93 + [] rtnetlink_rcv+0x26/0x2d + [] netlink_unicast+0xcb/0x150 + [] ? might_fault+0x59/0xa9 + [] netlink_sendmsg+0x4fa/0x51c + [] sock_sendmsg_nosec+0x12/0x1d + [] sock_sendmsg+0x29/0x2e + [] ___sys_sendmsg+0x1b4/0x23a + [] ? native_sched_clock+0x35/0x37 + [] ? sched_clock_local+0x12/0x72 + [] ? sched_clock_cpu+0x9e/0xb7 + [] ? current_kernel_time+0xe/0x32 + [] ? lock_release_holdtime.part.29+0x71/0x7f + [] ? read_seqcount_begin.constprop.27+0x5f/0x76 + [] ? trace_hardirqs_on_caller+0x17d/0x199 + [] ? __fget_light+0x50/0x78 + [] __sys_sendmsg+0x42/0x60 + [] SyS_sendmsg+0x12/0x1c + [] 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 +Signed-off-by: Cong Wang +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } diff --git a/queue-3.10/series b/queue-3.10/series index e69de29bb2d..e02d7a41625 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -0,0 +1,8 @@ +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 diff --git a/queue-3.10/udp-fix-behavior-of-wrong-checksums.patch b/queue-3.10/udp-fix-behavior-of-wrong-checksums.patch new file mode 100644 index 00000000000..bb8ed91d26b --- /dev/null +++ b/queue-3.10/udp-fix-behavior-of-wrong-checksums.patch @@ -0,0 +1,63 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Eric Dumazet +Date: Sat, 30 May 2015 09:16:53 -0700 +Subject: udp: fix behavior of wrong checksums + +From: Eric Dumazet + +[ 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 +Cc: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/queue-3.10/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch b/queue-3.10/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch new file mode 100644 index 00000000000..bdb1e3eb544 --- /dev/null +++ b/queue-3.10/unix-caif-sk_socket-can-disappear-when-state-is-unlocked.patch @@ -0,0 +1,71 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Mark Salyzyn +Date: Tue, 26 May 2015 08:22:19 -0700 +Subject: unix/caif: sk_socket can disappear when state is unlocked + +From: Mark Salyzyn + +[ Upstream commit b48732e4a48d80ed4a14812f0bab09560846514e ] + +got a rare NULL pointer dereference in clear_bit + +Signed-off-by: Mark Salyzyn +Acked-by: Hannes Frederic Sowa +---- +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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) { diff --git a/queue-3.10/xen-netback-read-hotplug-script-once-at-start-of-day.patch b/queue-3.10/xen-netback-read-hotplug-script-once-at-start-of-day.patch new file mode 100644 index 00000000000..35e8bfc8dfb --- /dev/null +++ b/queue-3.10/xen-netback-read-hotplug-script-once-at-start-of-day.patch @@ -0,0 +1,117 @@ +From foo@baz Sat Jun 13 09:49:42 PDT 2015 +From: Ian Campbell +Date: Mon, 1 Jun 2015 11:30:24 +0100 +Subject: xen: netback: read hotplug script once at start of day. + +From: Ian Campbell + +[ 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 +Acked-by: Wei Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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); -- 2.47.3