From: Greg Kroah-Hartman Date: Mon, 4 Jul 2022 12:04:29 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.9.322~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68311960b1332c2c5b5bbc206c34b946aca92b15;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: net-tun-stop-napi-when-detaching-queues.patch net-tun-unlink-napi-from-device-on-destruction.patch net-usb-ax88179_178a-fix-packet-receiving.patch rdma-qedr-fix-reporting-qp-timeout-attribute.patch selftests-net-pass-ipv6_args-to-udpgso_bench-s-ipv6-tcp-test.patch usbnet-fix-memory-allocation-in-helpers.patch virtio-net-fix-race-between-ndo_open-and-virtio_device_ready.patch --- diff --git a/queue-4.19/net-tun-stop-napi-when-detaching-queues.patch b/queue-4.19/net-tun-stop-napi-when-detaching-queues.patch new file mode 100644 index 00000000000..5a6075f631b --- /dev/null +++ b/queue-4.19/net-tun-stop-napi-when-detaching-queues.patch @@ -0,0 +1,58 @@ +From a8fc8cb5692aebb9c6f7afd4265366d25dcd1d01 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 22 Jun 2022 21:21:05 -0700 +Subject: net: tun: stop NAPI when detaching queues + +From: Jakub Kicinski + +commit a8fc8cb5692aebb9c6f7afd4265366d25dcd1d01 upstream. + +While looking at a syzbot report I noticed the NAPI only gets +disabled before it's deleted. I think that user can detach +the queue before destroying the device and the NAPI will never +be stopped. + +Fixes: 943170998b20 ("tun: enable NAPI for TUN/TAP driver") +Acked-by: Petar Penkov +Link: https://lore.kernel.org/r/20220623042105.2274812-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -333,6 +333,12 @@ static void tun_napi_init(struct tun_str + } + } + ++static void tun_napi_enable(struct tun_file *tfile) ++{ ++ if (tfile->napi_enabled) ++ napi_enable(&tfile->napi); ++} ++ + static void tun_napi_disable(struct tun_file *tfile) + { + if (tfile->napi_enabled) +@@ -723,8 +729,10 @@ static void __tun_detach(struct tun_file + if (clean) { + RCU_INIT_POINTER(tfile->tun, NULL); + sock_put(&tfile->sk); +- } else ++ } else { + tun_disable_queue(tun, tfile); ++ tun_napi_disable(tfile); ++ } + + synchronize_net(); + tun_flow_delete_by_queue(tun, tun->numqueues + 1); +@@ -878,6 +886,7 @@ static int tun_attach(struct tun_struct + + if (tfile->detached) { + tun_enable_queue(tfile); ++ tun_napi_enable(tfile); + } else { + sock_hold(&tfile->sk); + tun_napi_init(tun, tfile, napi, napi_frags); diff --git a/queue-4.19/net-tun-unlink-napi-from-device-on-destruction.patch b/queue-4.19/net-tun-unlink-napi-from-device-on-destruction.patch new file mode 100644 index 00000000000..32808c8da61 --- /dev/null +++ b/queue-4.19/net-tun-unlink-napi-from-device-on-destruction.patch @@ -0,0 +1,34 @@ +From 3b9bc84d311104906d2b4995a9a02d7b7ddab2db Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Wed, 22 Jun 2022 21:20:39 -0700 +Subject: net: tun: unlink NAPI from device on destruction + +From: Jakub Kicinski + +commit 3b9bc84d311104906d2b4995a9a02d7b7ddab2db upstream. + +Syzbot found a race between tun file and device destruction. +NAPIs live in struct tun_file which can get destroyed before +the netdev so we have to del them explicitly. The current +code is missing deleting the NAPI if the queue was detached +first. + +Fixes: 943170998b20 ("tun: enable NAPI for TUN/TAP driver") +Reported-by: syzbot+b75c138e9286ac742647@syzkaller.appspotmail.com +Link: https://lore.kernel.org/r/20220623042039.2274708-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -797,6 +797,7 @@ static void tun_detach_all(struct net_de + sock_put(&tfile->sk); + } + list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { ++ tun_napi_del(tfile); + tun_enable_queue(tfile); + tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); diff --git a/queue-4.19/net-usb-ax88179_178a-fix-packet-receiving.patch b/queue-4.19/net-usb-ax88179_178a-fix-packet-receiving.patch new file mode 100644 index 00000000000..1e5c999c43e --- /dev/null +++ b/queue-4.19/net-usb-ax88179_178a-fix-packet-receiving.patch @@ -0,0 +1,230 @@ +From f8ebb3ac881b17712e1d5967c97ab1806b16d3d6 Mon Sep 17 00:00:00 2001 +From: Jose Alonso +Date: Tue, 28 Jun 2022 12:13:02 -0300 +Subject: net: usb: ax88179_178a: Fix packet receiving + +From: Jose Alonso + +commit f8ebb3ac881b17712e1d5967c97ab1806b16d3d6 upstream. + +This patch corrects packet receiving in ax88179_rx_fixup. + +- problem observed: + ifconfig shows allways a lot of 'RX Errors' while packets + are received normally. + + This occurs because ax88179_rx_fixup does not recognise properly + the usb urb received. + The packets are normally processed and at the end, the code exits + with 'return 0', generating RX Errors. + (pkt_cnt==-2 and ptk_hdr over field rx_hdr trying to identify + another packet there) + + This is a usb urb received by "tcpdump -i usbmon2 -X" on a + little-endian CPU: + 0x0000: eeee f8e3 3b19 87a0 94de 80e3 daac 0800 + ^ packet 1 start (pkt_len = 0x05ec) + ^^^^ IP alignment pseudo header + ^ ethernet packet start + last byte ethernet packet v + padding (8-bytes aligned) vvvv vvvv + 0x05e0: c92d d444 1420 8a69 83dd 272f e82b 9811 + 0x05f0: eeee f8e3 3b19 87a0 94de 80e3 daac 0800 + ... ^ packet 2 + 0x0be0: eeee f8e3 3b19 87a0 94de 80e3 daac 0800 + ... + 0x1130: 9d41 9171 8a38 0ec5 eeee f8e3 3b19 87a0 + ... + 0x1720: 8cfc 15ff 5e4c e85c eeee f8e3 3b19 87a0 + ... + 0x1d10: ecfa 2a3a 19ab c78c eeee f8e3 3b19 87a0 + ... + 0x2070: eeee f8e3 3b19 87a0 94de 80e3 daac 0800 + ... ^ packet 7 + 0x2120: 7c88 4ca5 5c57 7dcc 0d34 7577 f778 7e0a + 0x2130: f032 e093 7489 0740 3008 ec05 0000 0080 + ====1==== ====2==== + hdr_off ^ + pkt_len = 0x05ec ^^^^ + AX_RXHDR_*=0x00830 ^^^^ ^ + pkt_len = 0 ^^^^ + AX_RXHDR_DROP_ERR=0x80000000 ^^^^ ^ + 0x2140: 3008 ec05 0000 0080 3008 5805 0000 0080 + 0x2150: 3008 ec05 0000 0080 3008 ec05 0000 0080 + 0x2160: 3008 5803 0000 0080 3008 c800 0000 0080 + ===11==== ===12==== ===13==== ===14==== + 0x2170: 0000 0000 0e00 3821 + ^^^^ ^^^^ rx_hdr + ^^^^ pkt_cnt=14 + ^^^^ hdr_off=0x2138 + ^^^^ ^^^^ padding + + The dump shows that pkt_cnt is the number of entrys in the + per-packet metadata. It is "2 * packet count". + Each packet have two entrys. The first have a valid + value (pkt_len and AX_RXHDR_*) and the second have a + dummy-header 0x80000000 (pkt_len=0 with AX_RXHDR_DROP_ERR). + Why exists dummy-header for each packet?!? + My guess is that this was done probably to align the + entry for each packet to 64-bits and maintain compatibility + with old firmware. + There is also a padding (0x00000000) before the rx_hdr to + align the end of rx_hdr to 64-bit. + Note that packets have a alignment of 64-bits (8-bytes). + + This patch assumes that the dummy-header and the last + padding are optional. So it preserves semantics and + recognises the same valid packets as the current code. + + This patch was made using only the dumpfile information and + tested with only one device: + 0b95:1790 ASIX Electronics Corp. AX88179 Gigabit Ethernet + +Fixes: 57bc3d3ae8c1 ("net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup") +Fixes: e2ca90c276e1 ("ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver") +Signed-off-by: Jose Alonso +Acked-by: Paolo Abeni +Link: https://lore.kernel.org/r/d6970bb04bf67598af4d316eaeb1792040b18cfd.camel@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/ax88179_178a.c | 101 ++++++++++++++++++++++++++++++----------- + 1 file changed, 76 insertions(+), 25 deletions(-) + +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -1377,6 +1377,42 @@ static int ax88179_rx_fixup(struct usbne + * are bundled into this buffer and where we can find an array of + * per-packet metadata (which contains elements encoded into u16). + */ ++ ++ /* SKB contents for current firmware: ++ * ++ * ... ++ * ++ * ++ * ... ++ * ++ * ++ * ++ * where: ++ * contains pkt_len bytes: ++ * 2 bytes of IP alignment pseudo header ++ * packet received ++ * contains 4 bytes: ++ * pkt_len and fields AX_RXHDR_* ++ * 0-7 bytes to terminate at ++ * 8 bytes boundary (64-bit). ++ * 4 bytes to make rx_hdr terminate at ++ * 8 bytes boundary (64-bit) ++ * contains 4 bytes: ++ * pkt_len=0 and AX_RXHDR_DROP_ERR ++ * contains 4 bytes: ++ * pkt_cnt and hdr_off (offset of ++ * ) ++ * ++ * pkt_cnt is number of entrys in the per-packet metadata. ++ * In current firmware there is 2 entrys per packet. ++ * The first points to the packet and the ++ * second is a dummy header. ++ * This was done probably to align fields in 64-bit and ++ * maintain compatibility with old firmware. ++ * This code assumes that and are ++ * optional. ++ */ ++ + if (skb->len < 4) + return 0; + skb_trim(skb, skb->len - 4); +@@ -1391,51 +1427,66 @@ static int ax88179_rx_fixup(struct usbne + /* Make sure that the bounds of the metadata array are inside the SKB + * (and in front of the counter at the end). + */ +- if (pkt_cnt * 2 + hdr_off > skb->len) ++ if (pkt_cnt * 4 + hdr_off > skb->len) + return 0; + pkt_hdr = (u32 *)(skb->data + hdr_off); + + /* Packets must not overlap the metadata array */ + skb_trim(skb, hdr_off); + +- for (; ; pkt_cnt--, pkt_hdr++) { ++ for (; pkt_cnt > 0; pkt_cnt--, pkt_hdr++) { ++ u16 pkt_len_plus_padd; + u16 pkt_len; + + le32_to_cpus(pkt_hdr); + pkt_len = (*pkt_hdr >> 16) & 0x1fff; ++ pkt_len_plus_padd = (pkt_len + 7) & 0xfff8; + +- if (pkt_len > skb->len) ++ /* Skip dummy header used for alignment ++ */ ++ if (pkt_len == 0) ++ continue; ++ ++ if (pkt_len_plus_padd > skb->len) + return 0; + + /* Check CRC or runt packet */ +- if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) && +- pkt_len >= 2 + ETH_HLEN) { +- bool last = (pkt_cnt == 0); +- +- if (last) { +- ax_skb = skb; +- } else { +- ax_skb = skb_clone(skb, GFP_ATOMIC); +- if (!ax_skb) +- return 0; +- } +- ax_skb->len = pkt_len; +- /* Skip IP alignment pseudo header */ +- skb_pull(ax_skb, 2); +- skb_set_tail_pointer(ax_skb, ax_skb->len); +- ax_skb->truesize = pkt_len + sizeof(struct sk_buff); +- ax88179_rx_checksum(ax_skb, pkt_hdr); ++ if ((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) || ++ pkt_len < 2 + ETH_HLEN) { ++ dev->net->stats.rx_errors++; ++ skb_pull(skb, pkt_len_plus_padd); ++ continue; ++ } + +- if (last) +- return 1; ++ /* last packet */ ++ if (pkt_len_plus_padd == skb->len) { ++ skb_trim(skb, pkt_len); + +- usbnet_skb_return(dev, ax_skb); ++ /* Skip IP alignment pseudo header */ ++ skb_pull(skb, 2); ++ ++ skb->truesize = SKB_TRUESIZE(pkt_len_plus_padd); ++ ax88179_rx_checksum(skb, pkt_hdr); ++ return 1; + } + +- /* Trim this packet away from the SKB */ +- if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8)) ++ ax_skb = skb_clone(skb, GFP_ATOMIC); ++ if (!ax_skb) + return 0; ++ skb_trim(ax_skb, pkt_len); ++ ++ /* Skip IP alignment pseudo header */ ++ skb_pull(ax_skb, 2); ++ ++ skb->truesize = pkt_len_plus_padd + ++ SKB_DATA_ALIGN(sizeof(struct sk_buff)); ++ ax88179_rx_checksum(ax_skb, pkt_hdr); ++ usbnet_skb_return(dev, ax_skb); ++ ++ skb_pull(skb, pkt_len_plus_padd); + } ++ ++ return 0; + } + + static struct sk_buff * diff --git a/queue-4.19/rdma-qedr-fix-reporting-qp-timeout-attribute.patch b/queue-4.19/rdma-qedr-fix-reporting-qp-timeout-attribute.patch new file mode 100644 index 00000000000..04a999fec3e --- /dev/null +++ b/queue-4.19/rdma-qedr-fix-reporting-qp-timeout-attribute.patch @@ -0,0 +1,58 @@ +From 118f767413ada4eef7825fbd4af7c0866f883441 Mon Sep 17 00:00:00 2001 +From: Kamal Heib +Date: Wed, 25 May 2022 16:20:29 +0300 +Subject: RDMA/qedr: Fix reporting QP timeout attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kamal Heib + +commit 118f767413ada4eef7825fbd4af7c0866f883441 upstream. + +Make sure to save the passed QP timeout attribute when the QP gets modified, +so when calling query QP the right value is reported and not the +converted value that is required by the firmware. This issue was found +while running the pyverbs tests. + +Fixes: cecbcddf6461 ("qedr: Add support for QP verbs") +Link: https://lore.kernel.org/r/20220525132029.84813-1-kamalheib1@gmail.com +Signed-off-by: Kamal Heib +Acked-by: Michal Kalderon  +Signed-off-by: Leon Romanovsky +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/hw/qedr/qedr.h | 1 + + drivers/infiniband/hw/qedr/verbs.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/qedr/qedr.h ++++ b/drivers/infiniband/hw/qedr/qedr.h +@@ -407,6 +407,7 @@ struct qedr_qp { + u32 sq_psn; + u32 qkey; + u32 dest_qp_num; ++ u8 timeout; + + /* Relevant to qps created from kernel space only (ULPs) */ + u8 prev_wqe_size; +--- a/drivers/infiniband/hw/qedr/verbs.c ++++ b/drivers/infiniband/hw/qedr/verbs.c +@@ -2376,6 +2376,8 @@ int qedr_modify_qp(struct ib_qp *ibqp, s + 1 << max_t(int, attr->timeout - 8, 0); + else + qp_params.ack_timeout = 0; ++ ++ qp->timeout = attr->timeout; + } + + if (attr_mask & IB_QP_RETRY_CNT) { +@@ -2535,7 +2537,7 @@ int qedr_query_qp(struct ib_qp *ibqp, + rdma_ah_set_dgid_raw(&qp_attr->ah_attr, ¶ms.dgid.bytes[0]); + rdma_ah_set_port_num(&qp_attr->ah_attr, 1); + rdma_ah_set_sl(&qp_attr->ah_attr, 0); +- qp_attr->timeout = params.timeout; ++ qp_attr->timeout = qp->timeout; + qp_attr->rnr_retry = params.rnr_retry; + qp_attr->retry_cnt = params.retry_cnt; + qp_attr->min_rnr_timer = params.min_rnr_nak_timer; diff --git a/queue-4.19/selftests-net-pass-ipv6_args-to-udpgso_bench-s-ipv6-tcp-test.patch b/queue-4.19/selftests-net-pass-ipv6_args-to-udpgso_bench-s-ipv6-tcp-test.patch new file mode 100644 index 00000000000..42117b8817d --- /dev/null +++ b/queue-4.19/selftests-net-pass-ipv6_args-to-udpgso_bench-s-ipv6-tcp-test.patch @@ -0,0 +1,34 @@ +From b968080808f7f28b89aa495b7402ba48eb17ee93 Mon Sep 17 00:00:00 2001 +From: Dimitris Michailidis +Date: Wed, 22 Jun 2022 17:02:34 -0700 +Subject: selftests/net: pass ipv6_args to udpgso_bench's IPv6 TCP test + +From: Dimitris Michailidis + +commit b968080808f7f28b89aa495b7402ba48eb17ee93 upstream. + +udpgso_bench.sh has been running its IPv6 TCP test with IPv4 arguments +since its initial conmit. Looks like a typo. + +Fixes: 3a687bef148d ("selftests: udp gso benchmark") +Cc: willemb@google.com +Signed-off-by: Dimitris Michailidis +Acked-by: Willem de Bruijn +Link: https://lore.kernel.org/r/20220623000234.61774-1-dmichail@fungible.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/udpgso_bench.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/testing/selftests/net/udpgso_bench.sh ++++ b/tools/testing/selftests/net/udpgso_bench.sh +@@ -57,7 +57,7 @@ run_all() { + run_udp "${ipv4_args}" + + echo "ipv6" +- run_tcp "${ipv4_args}" ++ run_tcp "${ipv6_args}" + run_udp "${ipv6_args}" + } + diff --git a/queue-4.19/series b/queue-4.19/series index 10d697ba77c..65ec724d205 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -4,3 +4,10 @@ dm-raid-fix-kasan-warning-in-raid5_add_disks.patch s390-archrandom-simplify-back-to-earlier-design-and-initialize-earlier.patch sunrpc-fix-read_plus-crasher.patch net-rose-fix-uaf-bugs-caused-by-timer-handler.patch +net-usb-ax88179_178a-fix-packet-receiving.patch +virtio-net-fix-race-between-ndo_open-and-virtio_device_ready.patch +selftests-net-pass-ipv6_args-to-udpgso_bench-s-ipv6-tcp-test.patch +net-tun-unlink-napi-from-device-on-destruction.patch +net-tun-stop-napi-when-detaching-queues.patch +rdma-qedr-fix-reporting-qp-timeout-attribute.patch +usbnet-fix-memory-allocation-in-helpers.patch diff --git a/queue-4.19/usbnet-fix-memory-allocation-in-helpers.patch b/queue-4.19/usbnet-fix-memory-allocation-in-helpers.patch new file mode 100644 index 00000000000..8b8dee986a5 --- /dev/null +++ b/queue-4.19/usbnet-fix-memory-allocation-in-helpers.patch @@ -0,0 +1,45 @@ +From e65af5403e462ccd7dff6a045a886c64da598c2e Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Tue, 28 Jun 2022 11:35:17 +0200 +Subject: usbnet: fix memory allocation in helpers + +From: Oliver Neukum + +commit e65af5403e462ccd7dff6a045a886c64da598c2e upstream. + +usbnet provides some helper functions that are also used in +the context of reset() operations. During a reset the other +drivers on a device are unable to operate. As that can be block +drivers, a driver for another interface cannot use paging +in its memory allocations without risking a deadlock. +Use GFP_NOIO in the helpers. + +Fixes: 877bd862f32b8 ("usbnet: introduce usbnet 3 command helpers") +Signed-off-by: Oliver Neukum +Link: https://lore.kernel.org/r/20220628093517.7469-1-oneukum@suse.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/usbnet.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1998,7 +1998,7 @@ static int __usbnet_read_cmd(struct usbn + cmd, reqtype, value, index, size); + + if (size) { +- buf = kmalloc(size, GFP_KERNEL); ++ buf = kmalloc(size, GFP_NOIO); + if (!buf) + goto out; + } +@@ -2030,7 +2030,7 @@ static int __usbnet_write_cmd(struct usb + cmd, reqtype, value, index, size); + + if (data) { +- buf = kmemdup(data, size, GFP_KERNEL); ++ buf = kmemdup(data, size, GFP_NOIO); + if (!buf) + goto out; + } else { diff --git a/queue-4.19/virtio-net-fix-race-between-ndo_open-and-virtio_device_ready.patch b/queue-4.19/virtio-net-fix-race-between-ndo_open-and-virtio_device_ready.patch new file mode 100644 index 00000000000..f922101d6e8 --- /dev/null +++ b/queue-4.19/virtio-net-fix-race-between-ndo_open-and-virtio_device_ready.patch @@ -0,0 +1,52 @@ +From 50c0ada627f56c92f5953a8bf9158b045ad026a1 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 17 Jun 2022 15:29:49 +0800 +Subject: virtio-net: fix race between ndo_open() and virtio_device_ready() + +From: Jason Wang + +commit 50c0ada627f56c92f5953a8bf9158b045ad026a1 upstream. + +We currently call virtio_device_ready() after netdev +registration. Since ndo_open() can be called immediately +after register_netdev, this means there exists a race between +ndo_open() and virtio_device_ready(): the driver may start to use the +device before DRIVER_OK which violates the spec. + +Fix this by switching to use register_netdevice() and protect the +virtio_device_ready() with rtnl_lock() to make sure ndo_open() can +only be called after virtio_device_ready(). + +Fixes: 4baf1e33d0842 ("virtio_net: enable VQs early") +Signed-off-by: Jason Wang +Message-Id: <20220617072949.30734-1-jasowang@redhat.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3105,14 +3105,20 @@ static int virtnet_probe(struct virtio_d + } + } + +- err = register_netdev(dev); ++ /* serialize netdev register + virtio_device_ready() with ndo_open() */ ++ rtnl_lock(); ++ ++ err = register_netdevice(dev); + if (err) { + pr_debug("virtio_net: registering device failed\n"); ++ rtnl_unlock(); + goto free_failover; + } + + virtio_device_ready(vdev); + ++ rtnl_unlock(); ++ + err = virtnet_cpu_notif_add(vi); + if (err) { + pr_debug("virtio_net: registering cpu notifier failed\n");