]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Oct 2022 15:03:48 +0000 (17:03 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Oct 2022 15:03:48 +0000 (17:03 +0200)
added patches:
hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch

queue-5.4/hv_netvsc-fix-race-between-vf-offering-and-vf-association-message-from-host.patch [new file with mode: 0644]
queue-5.4/series

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 (file)
index 0000000..b327c9d
--- /dev/null
@@ -0,0 +1,109 @@
+From 365e1ececb2905f94cc10a5817c5b644a32a3ae2 Mon Sep 17 00:00:00 2001
+From: Gaurav Kohli <gauravkohli@linux.microsoft.com>
+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 <gauravkohli@linux.microsoft.com>
+
+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 <haiyangz@microsoft.com>
+Signed-off-by: Gaurav Kohli <gauravkohli@linux.microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
index 85382fb8a5044d95554b8802c358953d5d533bb5..8b399ea7f9b34ba17b4da459f87d22b7e3183cc4 100644 (file)
@@ -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