From: Greg Kroah-Hartman Date: Mon, 13 Jan 2014 17:49:43 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.77~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c71a8ea1007e0dc1f425eaf0d65a88b47f925356;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch macvtap-do-not-double-count-received-packets.patch macvtap-signal-truncated-packets.patch macvtap-update-file-current-position.patch net-clear-local_df-when-passing-skb-between-namespaces.patch net-do-not-pretend-fraglist-support.patch net-drop_monitor-fix-the-value-of-maxattr.patch packet-fix-send-path-when-running-with-proto-0.patch rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch tun-unbreak-truncated-packet-signalling.patch tun-update-file-current-position.patch virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch --- diff --git a/queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch b/queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch new file mode 100644 index 00000000000..a906c15d045 --- /dev/null +++ b/queue-3.12/br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch @@ -0,0 +1,77 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Jiri Pirko +Date: Thu, 5 Dec 2013 16:27:37 +0100 +Subject: br: fix use of ->rx_handler_data in code executed on non-rx_handler path + +From: Jiri Pirko + +[ Upstream commit 859828c0ea476b42f3a93d69d117aaba90994b6f ] + +br_stp_rcv() is reached by non-rx_handler path. That means there is no +guarantee that dev is bridge port and therefore simple NULL check of +->rx_handler_data is not enough. There is need to check if dev is really +bridge port and since only rcu read lock is held here, do it by checking +->rx_handler pointer. + +Note that synchronize_net() in netdev_rx_handler_unregister() ensures +this approach as valid. + +Introduced originally by: +commit f350a0a87374418635689471606454abc7beaa3a + "bridge: use rx_handler_data pointer to store net_bridge_port pointer" + +Fixed but not in the best way by: +commit b5ed54e94d324f17c97852296d61a143f01b227a + "bridge: fix RCU races with bridge port" + +Reintroduced by: +commit 716ec052d2280d511e10e90ad54a86f5b5d4dcc2 + "bridge: fix NULL pointer deref of br_port_get_rcu" + +Please apply to stable trees as well. Thanks. + +RH bugzilla reference: https://bugzilla.redhat.com/show_bug.cgi?id=1025770 + +Reported-by: Laine Stump +Debugged-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Jiri Pirko +Acked-by: Michael S. Tsirkin +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_private.h | 10 ++++++++++ + net/bridge/br_stp_bpdu.c | 2 +- + 2 files changed, 11 insertions(+), 1 deletion(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -442,6 +442,16 @@ extern netdev_features_t br_features_rec + extern int br_handle_frame_finish(struct sk_buff *skb); + extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb); + ++static inline bool br_rx_handler_check_rcu(const struct net_device *dev) ++{ ++ return rcu_dereference(dev->rx_handler) == br_handle_frame; ++} ++ ++static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) ++{ ++ return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; ++} ++ + /* br_ioctl.c */ + extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg); +--- a/net/bridge/br_stp_bpdu.c ++++ b/net/bridge/br_stp_bpdu.c +@@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto * + if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) + goto err; + +- p = br_port_get_rcu(dev); ++ p = br_port_get_check_rcu(dev); + if (!p) + goto err; + diff --git a/queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch b/queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch new file mode 100644 index 00000000000..ef45757d388 --- /dev/null +++ b/queue-3.12/inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch @@ -0,0 +1,59 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Stefan Tomanek +Date: Tue, 10 Dec 2013 23:21:25 +0100 +Subject: inet: fix NULL pointer Oops in fib(6)_rule_suppress + +From: Stefan Tomanek + +[ Upstream commit 673498b8ed4c4d4b7221c5309d891c5eac2b7528 ] + +This changes ensures that the routing entry investigated by the suppress +function actually does point to a device struct before following that pointer, +fixing a possible kernel oops situation when verifying the interface group +associated with a routing table entry. + +According to Daniel Golle, this Oops can be triggered by a user process trying +to establish an outgoing IPv6 connection while having no real IPv6 connectivity +set up (only autoassigned link-local addresses). + +Fixes: 6ef94cfafba15 ("fib_rules: add route suppression based on ifgroup") + +Reported-by: Daniel Golle +Tested-by: Daniel Golle +Signed-off-by: Stefan Tomanek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/fib_rules.c | 5 ++++- + net/ipv6/fib6_rules.c | 6 +++++- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/net/ipv4/fib_rules.c ++++ b/net/ipv4/fib_rules.c +@@ -104,7 +104,10 @@ errout: + static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) + { + struct fib_result *result = (struct fib_result *) arg->result; +- struct net_device *dev = result->fi->fib_dev; ++ struct net_device *dev = NULL; ++ ++ if (result->fi) ++ dev = result->fi->fib_dev; + + /* do not accept result if the route does + * not meet the required prefix length +--- a/net/ipv6/fib6_rules.c ++++ b/net/ipv6/fib6_rules.c +@@ -122,7 +122,11 @@ out: + static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) + { + struct rt6_info *rt = (struct rt6_info *) arg->result; +- struct net_device *dev = rt->rt6i_idev->dev; ++ struct net_device *dev = NULL; ++ ++ if (rt->rt6i_idev) ++ dev = rt->rt6i_idev->dev; ++ + /* do not accept result if the route does + * not meet the required prefix length + */ diff --git a/queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch b/queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch new file mode 100644 index 00000000000..7cc2597bb0d --- /dev/null +++ b/queue-3.12/ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch @@ -0,0 +1,44 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Hannes Frederic Sowa +Date: Sat, 7 Dec 2013 03:33:45 +0100 +Subject: ipv6: don't count addrconf generated routes against gc limit + +From: Hannes Frederic Sowa + +[ Upstream commit a3300ef4bbb1f1e33ff0400e1e6cf7733d988f4f ] + +Brett Ciphery reported that new ipv6 addresses failed to get installed +because the addrconf generated dsts where counted against the dst gc +limit. We don't need to count those routes like we currently don't count +administratively added routes. + +Because the max_addresses check enforces a limit on unbounded address +generation first in case someone plays with router advertisments, we +are still safe here. + +Reported-by: Brett Ciphery +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2171,12 +2171,10 @@ struct rt6_info *addrconf_dst_alloc(stru + bool anycast) + { + struct net *net = dev_net(idev->dev); +- struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); +- +- if (!rt) { +- net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); ++ struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, ++ DST_NOCOUNT, NULL); ++ if (!rt) + return ERR_PTR(-ENOMEM); +- } + + in6_dev_hold(idev); + diff --git a/queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch b/queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch new file mode 100644 index 00000000000..0d734e423e1 --- /dev/null +++ b/queue-3.12/ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch @@ -0,0 +1,97 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Kamala R +Date: Mon, 2 Dec 2013 19:55:21 +0530 +Subject: IPv6: Fixed support for blackhole and prohibit routes + +From: Kamala R + +[ Upstream commit 7150aede5dd241539686e17d9592f5ebd28a2cda ] + +The behaviour of blackhole and prohibit routes has been corrected by setting +the input and output pointers of the dst variable appropriately. For +blackhole routes, they are set to dst_discard and to ip6_pkt_discard and +ip6_pkt_discard_out respectively for prohibit routes. + +ipv6: ip6_pkt_prohibit(_out) should not depend on +CONFIG_IPV6_MULTIPLE_TABLES + +We need ip6_pkt_prohibit(_out) available without +CONFIG_IPV6_MULTIPLE_TABLES + +Signed-off-by: Kamala R +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops * + + static int ip6_pkt_discard(struct sk_buff *skb); + static int ip6_pkt_discard_out(struct sk_buff *skb); ++static int ip6_pkt_prohibit(struct sk_buff *skb); ++static int ip6_pkt_prohibit_out(struct sk_buff *skb); + static void ip6_link_failure(struct sk_buff *skb); + static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, + struct sk_buff *skb, u32 mtu); +@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_en + + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + +-static int ip6_pkt_prohibit(struct sk_buff *skb); +-static int ip6_pkt_prohibit_out(struct sk_buff *skb); +- + static const struct rt6_info ip6_prohibit_entry_template = { + .dst = { + .__refcnt = ATOMIC_INIT(1), +@@ -1570,21 +1569,24 @@ int ip6_route_add(struct fib6_config *cf + goto out; + } + } +- rt->dst.output = ip6_pkt_discard_out; +- rt->dst.input = ip6_pkt_discard; + rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; + switch (cfg->fc_type) { + case RTN_BLACKHOLE: + rt->dst.error = -EINVAL; ++ rt->dst.output = dst_discard; ++ rt->dst.input = dst_discard; + break; + case RTN_PROHIBIT: + rt->dst.error = -EACCES; ++ rt->dst.output = ip6_pkt_prohibit_out; ++ rt->dst.input = ip6_pkt_prohibit; + break; + case RTN_THROW: +- rt->dst.error = -EAGAIN; +- break; + default: +- rt->dst.error = -ENETUNREACH; ++ rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN ++ : -ENETUNREACH; ++ rt->dst.output = ip6_pkt_discard_out; ++ rt->dst.input = ip6_pkt_discard; + break; + } + goto install_route; +@@ -2149,8 +2151,6 @@ static int ip6_pkt_discard_out(struct sk + return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); + } + +-#ifdef CONFIG_IPV6_MULTIPLE_TABLES +- + static int ip6_pkt_prohibit(struct sk_buff *skb) + { + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); +@@ -2162,8 +2162,6 @@ static int ip6_pkt_prohibit_out(struct s + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); + } + +-#endif +- + /* + * Allocate a dst for local (unicast / anycast) address. + */ diff --git a/queue-3.12/macvtap-do-not-double-count-received-packets.patch b/queue-3.12/macvtap-do-not-double-count-received-packets.patch new file mode 100644 index 00000000000..904cfbe7ce3 --- /dev/null +++ b/queue-3.12/macvtap-do-not-double-count-received-packets.patch @@ -0,0 +1,51 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Vlad Yasevich +Date: Tue, 26 Nov 2013 12:37:12 -0500 +Subject: macvtap: Do not double-count received packets + +From: Vlad Yasevich + +[ Upstream commit 006da7b07bc4d3a7ffabad17cf639eec6849c9dc ] + +Currently macvlan will count received packets after calling each +vlans receive handler. Macvtap attempts to count the packet +yet again when the user reads the packet from the tap socket. +This code doesn't do this consistently either. Remove the +counting from macvtap and let only macvlan count received +packets. + +Signed-off-by: Vlad Yasevich +Acked-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvtap.c | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -767,7 +767,6 @@ static ssize_t macvtap_put_user(struct m + const struct sk_buff *skb, + const struct iovec *iv, int len) + { +- struct macvlan_dev *vlan; + int ret; + int vnet_hdr_len = 0; + int vlan_offset = 0; +@@ -821,15 +820,6 @@ static ssize_t macvtap_put_user(struct m + copied += len; + + done: +- rcu_read_lock(); +- vlan = rcu_dereference(q->vlan); +- if (vlan) { +- preempt_disable(); +- macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0); +- preempt_enable(); +- } +- rcu_read_unlock(); +- + return ret ? ret : copied; + } + diff --git a/queue-3.12/macvtap-signal-truncated-packets.patch b/queue-3.12/macvtap-signal-truncated-packets.patch new file mode 100644 index 00000000000..a12a9434574 --- /dev/null +++ b/queue-3.12/macvtap-signal-truncated-packets.patch @@ -0,0 +1,76 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Jason Wang +Date: Wed, 11 Dec 2013 13:08:34 +0800 +Subject: macvtap: signal truncated packets + +From: Jason Wang + +[ Upstream commit ce232ce01d61b184202bb185103d119820e1260c ] + +macvtap_put_user() never return a value grater than iov length, this in fact +bypasses the truncated checking in macvtap_recvmsg(). Fix this by always +returning the size of packet plus the possible vlan header to let the trunca +checking work. + +Cc: Vlad Yasevich +Cc: Zhi Yong Wu +Cc: Michael S. Tsirkin +Signed-off-by: Jason Wang +Acked-by: Vlad Yasevich +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvtap.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -770,7 +770,7 @@ static ssize_t macvtap_put_user(struct m + int ret; + int vnet_hdr_len = 0; + int vlan_offset = 0; +- int copied; ++ int copied, total; + + if (q->flags & IFF_VNET_HDR) { + struct virtio_net_hdr vnet_hdr; +@@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct m + if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) + return -EFAULT; + } +- copied = vnet_hdr_len; ++ total = copied = vnet_hdr_len; ++ total += skb->len; + + if (!vlan_tx_tag_present(skb)) + len = min_t(int, skb->len, len); +@@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct m + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + len = min_t(int, skb->len + VLAN_HLEN, len); ++ total += VLAN_HLEN; + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); +@@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct m + } + + ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); +- copied += len; + + done: +- return ret ? ret : copied; ++ return ret ? ret : total; + } + + static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, +@@ -875,7 +876,7 @@ static ssize_t macvtap_aio_read(struct k + } + + ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); +- ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ ++ ret = min_t(ssize_t, ret, len); + if (ret > 0) + iocb->ki_pos = ret; + out: diff --git a/queue-3.12/macvtap-update-file-current-position.patch b/queue-3.12/macvtap-update-file-current-position.patch new file mode 100644 index 00000000000..b38b393cff5 --- /dev/null +++ b/queue-3.12/macvtap-update-file-current-position.patch @@ -0,0 +1,27 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Zhi Yong Wu +Date: Fri, 6 Dec 2013 14:16:50 +0800 +Subject: macvtap: update file current position + +From: Zhi Yong Wu + +[ Upstream commit e6ebc7f16ca1434a334647aa56399c546be4e64b ] + +Signed-off-by: Zhi Yong Wu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macvtap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -886,6 +886,8 @@ static ssize_t macvtap_aio_read(struct k + + ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ ++ if (ret > 0) ++ iocb->ki_pos = ret; + out: + return ret; + } diff --git a/queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch b/queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch new file mode 100644 index 00000000000..2a2426fadcc --- /dev/null +++ b/queue-3.12/net-clear-local_df-when-passing-skb-between-namespaces.patch @@ -0,0 +1,36 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Hannes Frederic Sowa +Date: Thu, 5 Dec 2013 23:29:19 +0100 +Subject: net: clear local_df when passing skb between namespaces + +From: Hannes Frederic Sowa + +[ Upstream commit 239c78db9c41a8f524cce60507440d72229d73bc ] + +We must clear local_df when passing the skb between namespaces as the +packet is not local to the new namespace any more and thus may not get +fragmented by local rules. Fred Templin noticed that other namespaces +do fragment IPv6 packets while forwarding. Instead they should have send +back a PTB. + +The same problem should be present when forwarding DF-IPv4 packets +between namespaces. + +Reported-by: Templin, Fred L +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3541,6 +3541,7 @@ void skb_scrub_packet(struct sk_buff *sk + skb->tstamp.tv64 = 0; + skb->pkt_type = PACKET_HOST; + skb->skb_iif = 0; ++ skb->local_df = 0; + skb_dst_drop(skb); + skb->mark = 0; + secpath_reset(skb); diff --git a/queue-3.12/net-do-not-pretend-fraglist-support.patch b/queue-3.12/net-do-not-pretend-fraglist-support.patch new file mode 100644 index 00000000000..4771ca9247c --- /dev/null +++ b/queue-3.12/net-do-not-pretend-fraglist-support.patch @@ -0,0 +1,74 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Eric Dumazet +Date: Mon, 2 Dec 2013 08:51:13 -0800 +Subject: net: do not pretend FRAGLIST support + +From: Eric Dumazet + +[ Upstream commit 28e24c62ab3062e965ef1b3bcc244d50aee7fa85 ] + +Few network drivers really supports frag_list : virtual drivers. + +Some drivers wrongly advertise NETIF_F_FRAGLIST feature. + +If skb with a frag_list is given to them, packet on the wire will be +corrupt. + +Remove this flag, as core networking stack will make sure to +provide packets that can be sent without corruption. + +Signed-off-by: Eric Dumazet +Cc: Thadeu Lima de Souza Cascardo +Cc: Anirudha Sarangi +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +- + drivers/net/ethernet/tehuti/tehuti.c | 1 - + drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 +- + 4 files changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c ++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c +@@ -3033,7 +3033,7 @@ static struct ehea_port *ehea_setup_sing + + dev->hw_features = NETIF_F_SG | NETIF_F_TSO | + NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX; +- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | ++ dev->features = NETIF_F_SG | NETIF_F_TSO | + NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM; +--- a/drivers/net/ethernet/tehuti/tehuti.c ++++ b/drivers/net/ethernet/tehuti/tehuti.c +@@ -2019,7 +2019,6 @@ bdx_probe(struct pci_dev *pdev, const st + ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO + | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM +- /*| NETIF_F_FRAGLIST */ + ; + ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX; +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1016,7 +1016,7 @@ static int temac_of_probe(struct platfor + platform_set_drvdata(op, ndev); + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ +- ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; ++ ndev->features = NETIF_F_SG; + ndev->netdev_ops = &temac_netdev_ops; + ndev->ethtool_ops = &temac_ethtool_ops; + #if 0 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1486,7 +1486,7 @@ static int axienet_of_probe(struct platf + + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ +- ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; ++ ndev->features = NETIF_F_SG; + ndev->netdev_ops = &axienet_netdev_ops; + ndev->ethtool_ops = &axienet_ethtool_ops; + diff --git a/queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch b/queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch new file mode 100644 index 00000000000..ce94edf7e9c --- /dev/null +++ b/queue-3.12/net-drop_monitor-fix-the-value-of-maxattr.patch @@ -0,0 +1,29 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Changli Gao +Date: Sun, 8 Dec 2013 09:36:56 -0500 +Subject: net: drop_monitor: fix the value of maxattr + +From: Changli Gao + +[ Upstream commit d323e92cc3f4edd943610557c9ea1bb4bb5056e8 ] + +maxattr in genl_family should be used to save the max attribute +type, but not the max command type. Drop monitor doesn't support +any attributes, so we should leave it as zero. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/drop_monitor.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -64,7 +64,6 @@ static struct genl_family net_drop_monit + .hdrsize = 0, + .name = "NET_DM", + .version = 2, +- .maxattr = NET_DM_CMD_MAX, + }; + + static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); diff --git a/queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch b/queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch new file mode 100644 index 00000000000..f1c4c31feae --- /dev/null +++ b/queue-3.12/packet-fix-send-path-when-running-with-proto-0.patch @@ -0,0 +1,206 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Daniel Borkmann +Date: Fri, 6 Dec 2013 11:36:15 +0100 +Subject: packet: fix send path when running with proto == 0 + +From: Daniel Borkmann + +[ Upstream commit 66e56cd46b93ef407c60adcac62cf33b06119d50 ] + +Commit e40526cb20b5 introduced a cached dev pointer, that gets +hooked into register_prot_hook(), __unregister_prot_hook() to +update the device used for the send path. + +We need to fix this up, as otherwise this will not work with +sockets created with protocol = 0, plus with sll_protocol = 0 +passed via sockaddr_ll when doing the bind. + +So instead, assign the pointer directly. The compiler can inline +these helper functions automagically. + +While at it, also assume the cached dev fast-path as likely(), +and document this variant of socket creation as it seems it is +not widely used (seems not even the author of TX_RING was aware +of that in his reference example [1]). Tested with reproducer +from e40526cb20b5. + + [1] http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap#Example + +Fixes: e40526cb20b5 ("packet: fix use after free race in send path when dev is released") +Signed-off-by: Daniel Borkmann +Tested-by: Salam Noureddine +Tested-by: Jesper Dangaard Brouer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/networking/packet_mmap.txt | 10 ++++ + net/packet/af_packet.c | 65 +++++++++++++++++++------------ + 2 files changed, 50 insertions(+), 25 deletions(-) + +--- a/Documentation/networking/packet_mmap.txt ++++ b/Documentation/networking/packet_mmap.txt +@@ -123,6 +123,16 @@ Transmission process is similar to captu + [shutdown] close() --------> destruction of the transmission socket and + deallocation of all associated resources. + ++Socket creation and destruction is also straight forward, and is done ++the same way as in capturing described in the previous paragraph: ++ ++ int fd = socket(PF_PACKET, mode, 0); ++ ++The protocol can optionally be 0 in case we only want to transmit ++via this socket, which avoids an expensive call to packet_rcv(). ++In this case, you also need to bind(2) the TX_RING with sll_protocol = 0 ++set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example. ++ + Binding the socket to your network interface is mandatory (with zero copy) to + know the header size of frames used in the circular buffer. + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -237,6 +237,30 @@ struct packet_skb_cb { + static void __fanout_unlink(struct sock *sk, struct packet_sock *po); + static void __fanout_link(struct sock *sk, struct packet_sock *po); + ++static struct net_device *packet_cached_dev_get(struct packet_sock *po) ++{ ++ struct net_device *dev; ++ ++ rcu_read_lock(); ++ dev = rcu_dereference(po->cached_dev); ++ if (likely(dev)) ++ dev_hold(dev); ++ rcu_read_unlock(); ++ ++ return dev; ++} ++ ++static void packet_cached_dev_assign(struct packet_sock *po, ++ struct net_device *dev) ++{ ++ rcu_assign_pointer(po->cached_dev, dev); ++} ++ ++static void packet_cached_dev_reset(struct packet_sock *po) ++{ ++ RCU_INIT_POINTER(po->cached_dev, NULL); ++} ++ + /* register_prot_hook must be invoked with the po->bind_lock held, + * or from a context in which asynchronous accesses to the packet + * socket is not possible (packet_create()). +@@ -246,12 +270,10 @@ static void register_prot_hook(struct so + struct packet_sock *po = pkt_sk(sk); + + if (!po->running) { +- if (po->fanout) { ++ if (po->fanout) + __fanout_link(sk, po); +- } else { ++ else + dev_add_pack(&po->prot_hook); +- rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); +- } + + sock_hold(sk); + po->running = 1; +@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struc + struct packet_sock *po = pkt_sk(sk); + + po->running = 0; +- if (po->fanout) { ++ ++ if (po->fanout) + __fanout_unlink(sk, po); +- } else { ++ else + __dev_remove_pack(&po->prot_hook); +- RCU_INIT_POINTER(po->cached_dev, NULL); +- } + + __sock_put(sk); + +@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packe + return tp_len; + } + +-static struct net_device *packet_cached_dev_get(struct packet_sock *po) +-{ +- struct net_device *dev; +- +- rcu_read_lock(); +- dev = rcu_dereference(po->cached_dev); +- if (dev) +- dev_hold(dev); +- rcu_read_unlock(); +- +- return dev; +-} +- + static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + { + struct sk_buff *skb; +@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_soc + + mutex_lock(&po->pg_vec_lock); + +- if (saddr == NULL) { ++ if (likely(saddr == NULL)) { + dev = packet_cached_dev_get(po); + proto = po->num; + addr = NULL; +@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *soc + * Get and verify the address. + */ + +- if (saddr == NULL) { ++ if (likely(saddr == NULL)) { + dev = packet_cached_dev_get(po); + proto = po->num; + addr = NULL; +@@ -2451,6 +2459,8 @@ static int packet_release(struct socket + + spin_lock(&po->bind_lock); + unregister_prot_hook(sk, false); ++ packet_cached_dev_reset(po); ++ + if (po->prot_hook.dev) { + dev_put(po->prot_hook.dev); + po->prot_hook.dev = NULL; +@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *s + + spin_lock(&po->bind_lock); + unregister_prot_hook(sk, true); ++ + po->num = protocol; + po->prot_hook.type = protocol; + if (po->prot_hook.dev) + dev_put(po->prot_hook.dev); +- po->prot_hook.dev = dev; + ++ po->prot_hook.dev = dev; + po->ifindex = dev ? dev->ifindex : 0; + ++ packet_cached_dev_assign(po, dev); ++ + if (protocol == 0) + goto out_unlock; + +@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net + po = pkt_sk(sk); + sk->sk_family = PF_PACKET; + po->num = proto; +- RCU_INIT_POINTER(po->cached_dev, NULL); ++ ++ packet_cached_dev_reset(po); + + sk->sk_destruct = packet_sock_destruct; + sk_refcnt_debug_inc(sk); +@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifi + sk->sk_error_report(sk); + } + if (msg == NETDEV_UNREGISTER) { ++ packet_cached_dev_reset(po); + po->ifindex = -1; + if (po->prot_hook.dev) + dev_put(po->prot_hook.dev); diff --git a/queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch b/queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch new file mode 100644 index 00000000000..85919d45896 --- /dev/null +++ b/queue-3.12/rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch @@ -0,0 +1,90 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Venkat Venkatsubra +Date: Mon, 2 Dec 2013 15:41:39 -0800 +Subject: rds: prevent BUG_ON triggered on congestion update to loopback + +From: Venkat Venkatsubra + +[ Upstream commit 18fc25c94eadc52a42c025125af24657a93638c0 ] + +After congestion update on a local connection, when rds_ib_xmit returns +less bytes than that are there in the message, rds_send_xmit calls +back rds_ib_xmit with an offset that causes BUG_ON(off & RDS_FRAG_SIZE) +to trigger. + +For a 4Kb PAGE_SIZE rds_ib_xmit returns min(8240,4096)=4096 when actually +the message contains 8240 bytes. rds_send_xmit thinks there is more to send +and calls rds_ib_xmit again with a data offset "off" of 4096-48(rds header) +=4048 bytes thus hitting the BUG_ON(off & RDS_FRAG_SIZE) [RDS_FRAG_SIZE=4k]. + +The commit 6094628bfd94323fc1cea05ec2c6affd98c18f7f +"rds: prevent BUG_ON triggering on congestion map updates" introduced +this regression. That change was addressing the triggering of a different +BUG_ON in rds_send_xmit() on PowerPC architecture with 64Kbytes PAGE_SIZE: + BUG_ON(ret != 0 && + conn->c_xmit_sg == rm->data.op_nents); +This was the sequence it was going through: +(rds_ib_xmit) +/* Do not send cong updates to IB loopback */ +if (conn->c_loopback + && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { + rds_cong_map_updated(conn->c_fcong, ~(u64) 0); + return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; +} +rds_ib_xmit returns 8240 +rds_send_xmit: + c_xmit_data_off = 0 + 8240 - 48 (rds header accounted only the first time) + = 8192 + c_xmit_data_off < 65536 (sg->length), so calls rds_ib_xmit again +rds_ib_xmit returns 8240 +rds_send_xmit: + c_xmit_data_off = 8192 + 8240 = 16432, calls rds_ib_xmit again + and so on (c_xmit_data_off 24672,32912,41152,49392,57632) +rds_ib_xmit returns 8240 +On this iteration this sequence causes the BUG_ON in rds_send_xmit: + while (ret) { + tmp = min_t(int, ret, sg->length - conn->c_xmit_data_off); + [tmp = 65536 - 57632 = 7904] + conn->c_xmit_data_off += tmp; + [c_xmit_data_off = 57632 + 7904 = 65536] + ret -= tmp; + [ret = 8240 - 7904 = 336] + if (conn->c_xmit_data_off == sg->length) { + conn->c_xmit_data_off = 0; + sg++; + conn->c_xmit_sg++; + BUG_ON(ret != 0 && + conn->c_xmit_sg == rm->data.op_nents); + [c_xmit_sg = 1, rm->data.op_nents = 1] + +What the current fix does: +Since the congestion update over loopback is not actually transmitted +as a message, all that rds_ib_xmit needs to do is let the caller think +the full message has been transmitted and not return partial bytes. +It will return 8240 (RDS_CONG_MAP_BYTES+48) when PAGE_SIZE is 4Kb. +And 64Kb+48 when page size is 64Kb. + +Reported-by: Josh Hunt +Tested-by: Honggang Li +Acked-by: Bang Nguyen +Signed-off-by: Venkat Venkatsubra +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/ib_send.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/rds/ib_send.c ++++ b/net/rds/ib_send.c +@@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *c + && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { + rds_cong_map_updated(conn->c_fcong, ~(u64) 0); + scat = &rm->data.op_sg[sg]; +- ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; +- ret = min_t(int, ret, scat->length - conn->c_xmit_data_off); +- return ret; ++ ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length); ++ return sizeof(struct rds_header) + ret; + } + + /* FIXME we may overallocate here */ diff --git a/queue-3.12/series b/queue-3.12/series new file mode 100644 index 00000000000..a06652a3414 --- /dev/null +++ b/queue-3.12/series @@ -0,0 +1,15 @@ +ipv6-fixed-support-for-blackhole-and-prohibit-routes.patch +net-do-not-pretend-fraglist-support.patch +rds-prevent-bug_on-triggered-on-congestion-update-to-loopback.patch +net-clear-local_df-when-passing-skb-between-namespaces.patch +macvtap-update-file-current-position.patch +tun-update-file-current-position.patch +tun-unbreak-truncated-packet-signalling.patch +macvtap-do-not-double-count-received-packets.patch +macvtap-signal-truncated-packets.patch +virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch +br-fix-use-of-rx_handler_data-in-code-executed-on-non-rx_handler-path.patch +packet-fix-send-path-when-running-with-proto-0.patch +ipv6-don-t-count-addrconf-generated-routes-against-gc-limit.patch +net-drop_monitor-fix-the-value-of-maxattr.patch +inet-fix-null-pointer-oops-in-fib-6-_rule_suppress.patch diff --git a/queue-3.12/tun-unbreak-truncated-packet-signalling.patch b/queue-3.12/tun-unbreak-truncated-packet-signalling.patch new file mode 100644 index 00000000000..79f13387a23 --- /dev/null +++ b/queue-3.12/tun-unbreak-truncated-packet-signalling.patch @@ -0,0 +1,78 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Jason Wang +Date: Wed, 11 Dec 2013 13:08:33 +0800 +Subject: tun: unbreak truncated packet signalling + +From: Jason Wang + +[ Upstream commit e6fd07c899cd719bb5517bc7f32ce03a62220351 ] + +Commit 6680ec68eff47d36f67b4351bc9836fd6cba9532 +(tuntap: hardware vlan tx support) breaks the truncated packet signal by nev +return a length greater than iov length in tun_put_user(). This patch fixes +by always return the length of packet plus possible vlan header. Caller can +detect the truncated packet by comparing the return value and the size of io +length. + +Cc: Zhi Yong Wu +Cc: Michael S. Tsirkin +Signed-off-by: Vlad Yasevich +Signed-off-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1184,7 +1184,7 @@ static ssize_t tun_put_user(struct tun_s + { + struct tun_pi pi = { 0, skb->protocol }; + ssize_t total = 0; +- int vlan_offset = 0; ++ int vlan_offset = 0, copied; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) < 0) +@@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_s + total += tun->vnet_hdr_sz; + } + ++ copied = total; ++ total += skb->len; + if (!vlan_tx_tag_present(skb)) { + len = min_t(int, skb->len, len); + } else { +@@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_s + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + len = min_t(int, skb->len + VLAN_HLEN, len); ++ total += VLAN_HLEN; + + copy = min_t(int, vlan_offset, len); +- ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); ++ ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); + len -= copy; +- total += copy; ++ copied += copy; + if (ret || !len) + goto done; + + copy = min_t(int, sizeof(veth), len); +- ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); ++ ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); + len -= copy; +- total += copy; ++ copied += copy; + if (ret || !len) + goto done; + } + +- skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); +- total += len; ++ skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + + done: + tun->dev->stats.tx_packets++; diff --git a/queue-3.12/tun-update-file-current-position.patch b/queue-3.12/tun-update-file-current-position.patch new file mode 100644 index 00000000000..6547c3ee21c --- /dev/null +++ b/queue-3.12/tun-update-file-current-position.patch @@ -0,0 +1,27 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Zhi Yong Wu +Date: Fri, 6 Dec 2013 14:16:51 +0800 +Subject: tun: update file current position + +From: Zhi Yong Wu + +[ Upstream commit d0b7da8afa079ffe018ab3e92879b7138977fc8f ] + +Signed-off-by: Zhi Yong Wu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1356,6 +1356,8 @@ static ssize_t tun_chr_aio_read(struct k + ret = tun_do_read(tun, tfile, iocb, iv, len, + file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); ++ if (ret > 0) ++ iocb->ki_pos = ret; + out: + tun_put(tun); + return ret; diff --git a/queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch b/queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch new file mode 100644 index 00000000000..5541835339a --- /dev/null +++ b/queue-3.12/virtio-delete-napi-structures-from-netdev-before-releasing-memory.patch @@ -0,0 +1,80 @@ +From foo@baz Mon Jan 13 09:44:41 PST 2014 +From: Andrey Vagin +Date: Thu, 5 Dec 2013 18:36:21 +0400 +Subject: virtio: delete napi structures from netdev before releasing memory + +From: Andrey Vagin + +[ Upstream commit d4fb84eefe5164f6a6ea51d0a9e26280c661a0dd ] + +free_netdev calls netif_napi_del too, but it's too late, because napi +structures are placed on vi->rq. netif_napi_add() is called from +virtnet_alloc_queues. + +general protection fault: 0000 [#1] SMP +Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: ip6table_filter ip6_tables iptable_filter ip_tables virtio_balloon pcspkr virtio_net(-) i2c_pii +CPU: 1 PID: 347 Comm: rmmod Not tainted 3.13.0-rc2+ #171 +Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +task: ffff8800b779c420 ti: ffff8800379e0000 task.ti: ffff8800379e0000 +RIP: 0010:[] [] __list_del_entry+0x29/0xd0 +RSP: 0018:ffff8800379e1dd0 EFLAGS: 00010a83 +RAX: 6b6b6b6b6b6b6b6b RBX: ffff8800379c2fd0 RCX: dead000000200200 +RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000001 RDI: ffff8800379c2fd0 +RBP: ffff8800379e1dd0 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000001 R12: ffff8800379c2f90 +R13: ffff880037839160 R14: 0000000000000000 R15: 00000000013352f0 +FS: 00007f1400e34740(0000) GS:ffff8800bfb00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: 00007f464124c763 CR3: 00000000b68cf000 CR4: 00000000000006e0 +Stack: + ffff8800379e1df0 ffffffff8155beab 6b6b6b6b6b6b6b2b ffff8800378391c0 + ffff8800379e1e18 ffffffff8156499b ffff880037839be0 ffff880037839d20 + ffff88003779d3f0 ffff8800379e1e38 ffffffffa003477c ffff88003779d388 +Call Trace: + [] netif_napi_del+0x1b/0x80 + [] free_netdev+0x8b/0x110 + [] virtnet_remove+0x7c/0x90 [virtio_net] + [] virtio_dev_remove+0x23/0x80 + [] __device_release_driver+0x7f/0xf0 + [] driver_detach+0xc0/0xd0 + [] bus_remove_driver+0x58/0xd0 + [] driver_unregister+0x2c/0x50 + [] unregister_virtio_driver+0xe/0x10 + [] virtio_net_driver_exit+0x10/0x6ce [virtio_net] + [] SyS_delete_module+0x172/0x220 + [] ? trace_hardirqs_on+0xd/0x10 + [] ? __audit_syscall_entry+0x9c/0xf0 + [] system_call_fastpath+0x16/0x1b +Code: 00 00 55 48 8b 17 48 b9 00 01 10 00 00 00 ad de 48 8b 47 08 48 89 e5 48 39 ca 74 29 48 b9 00 02 20 00 00 00 +RIP [] __list_del_entry+0x29/0xd0 + RSP +---[ end trace d5931cd3f87c9763 ]--- + +Fixes: 986a4f4d452d (virtio_net: multiqueue support) +Cc: Rusty Russell +Cc: "Michael S. Tsirkin" +Signed-off-by: Andrey Vagin +Acked-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1307,6 +1307,11 @@ static void virtnet_config_changed(struc + + static void virtnet_free_queues(struct virtnet_info *vi) + { ++ int i; ++ ++ for (i = 0; i < vi->max_queue_pairs; i++) ++ netif_napi_del(&vi->rq[i].napi); ++ + kfree(vi->rq); + kfree(vi->sq); + }