From: Greg Kroah-Hartman Date: Thu, 27 Oct 2022 15:03:48 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.10.151~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f2b711b74768c14b1fae6cbbf90ef9a5aac4b7a0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch --- diff --git a/queue-5.4/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch b/queue-5.4/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch new file mode 100644 index 00000000000..b327c9dc45d --- /dev/null +++ b/queue-5.4/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 +@@ -954,6 +954,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 +@@ -1223,6 +1223,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 +@@ -2133,6 +2133,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; + +@@ -2159,6 +2160,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; +@@ -2232,6 +2245,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); +@@ -2253,6 +2271,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); +@@ -2290,6 +2309,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-5.4/series b/queue-5.4/series index 85382fb8a50..8b399ea7f9b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -49,3 +49,4 @@ arm64-topology-move-store_cpu_topology-to-shared-code.patch riscv-topology-fix-default-topology-reporting.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