From: Greg Kroah-Hartman Date: Thu, 27 Oct 2022 15:03:41 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v5.10.151~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10096418b0154a8f4a0f4794676181c26ec52220;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch --- diff --git a/queue-4.19/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch b/queue-4.19/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch new file mode 100644 index 00000000000..be4d11aafc0 --- /dev/null +++ b/queue-4.19/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch @@ -0,0 +1,109 @@ +From 365e1ececb2905f94cc10a5817c5b644a32a3ae2 Mon Sep 17 00:00:00 2001 +From: Gaurav Kohli +Date: Wed, 5 Oct 2022 22:52:59 -0700 +Subject: hv_netvsc: Fix race between VF offering and VF association message from host + +From: Gaurav Kohli + +commit 365e1ececb2905f94cc10a5817c5b644a32a3ae2 upstream. + +During vm boot, there might be possibility that vf registration +call comes before the vf association from host to vm. + +And this might break netvsc vf path, To prevent the same block +vf registration until vf bind message comes from host. + +Cc: stable@vger.kernel.org +Fixes: 00d7ddba11436 ("hv_netvsc: pair VF based on serial number") +Reviewed-by: Haiyang Zhang +Signed-off-by: Gaurav Kohli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/hyperv_net.h | 3 +++ + drivers/net/hyperv/netvsc.c | 4 ++++ + drivers/net/hyperv/netvsc_drv.c | 20 ++++++++++++++++++++ + 3 files changed, 27 insertions(+) + +--- a/drivers/net/hyperv/hyperv_net.h ++++ b/drivers/net/hyperv/hyperv_net.h +@@ -950,6 +950,9 @@ struct net_device_context { + u32 vf_alloc; + /* Serial number of the VF to team with */ + u32 vf_serial; ++ ++ /* completion variable to confirm vf association */ ++ struct completion vf_add; + }; + + /* Per channel data */ +--- a/drivers/net/hyperv/netvsc.c ++++ b/drivers/net/hyperv/netvsc.c +@@ -1227,6 +1227,10 @@ static void netvsc_send_vf(struct net_de + + net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated; + net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial; ++ ++ if (net_device_ctx->vf_alloc) ++ complete(&net_device_ctx->vf_add); ++ + netdev_info(ndev, "VF slot %u %s\n", + net_device_ctx->vf_serial, + net_device_ctx->vf_alloc ? "added" : "removed"); +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -2121,6 +2121,7 @@ static struct net_device *get_netvsc_bys + { + struct device *parent = vf_netdev->dev.parent; + struct net_device_context *ndev_ctx; ++ struct net_device *ndev; + struct pci_dev *pdev; + u32 serial; + +@@ -2147,6 +2148,18 @@ static struct net_device *get_netvsc_bys + return hv_get_drvdata(ndev_ctx->device_ctx); + } + ++ /* Fallback path to check synthetic vf with ++ * help of mac addr ++ */ ++ list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { ++ ndev = hv_get_drvdata(ndev_ctx->device_ctx); ++ if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) { ++ netdev_notice(vf_netdev, ++ "falling back to mac addr based matching\n"); ++ return ndev; ++ } ++ } ++ + netdev_notice(vf_netdev, + "no netdev found for vf serial:%u\n", serial); + return NULL; +@@ -2216,6 +2229,11 @@ static int netvsc_vf_changed(struct net_ + if (!netvsc_dev) + return NOTIFY_DONE; + ++ if (vf_is_up && !net_device_ctx->vf_alloc) { ++ netdev_info(ndev, "Waiting for the VF association from host\n"); ++ wait_for_completion(&net_device_ctx->vf_add); ++ } ++ + netvsc_switch_datapath(ndev, vf_is_up); + netdev_info(ndev, "Data path switched %s VF: %s\n", + vf_is_up ? "to" : "from", vf_netdev->name); +@@ -2237,6 +2255,7 @@ static int netvsc_unregister_vf(struct n + + netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name); + ++ reinit_completion(&net_device_ctx->vf_add); + netdev_rx_handler_unregister(vf_netdev); + netdev_upper_dev_unlink(vf_netdev, ndev); + RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL); +@@ -2274,6 +2293,7 @@ static int netvsc_probe(struct hv_device + + INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); + ++ init_completion(&net_device_ctx->vf_add); + spin_lock_init(&net_device_ctx->lock); + INIT_LIST_HEAD(&net_device_ctx->reconfig_events); + INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup); diff --git a/queue-4.19/series b/queue-4.19/series index 4f2ac3c80ed..661bf1cea1f 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -21,3 +21,4 @@ iommu-vt-d-clean-up-si_domain-in-the-init_dmars-erro.patch media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch acpi-video-force-backlight-native-for-more-tongfang-devices.patch makefile.debug-re-enable-debug-info-for-.s-files.patch +hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch