From: Haiyang Zhang <haiya...@microsoft.com>

[ Upstream commit 005479556197f80139771960dda0dfdcd2d2aad5 ]

The VF device's serial number is saved as a string in PCI slot's
kobj name, not the slot->number. This patch corrects the netvsc
driver, so the VF device can be successfully paired with synthetic
NIC.

Fixes: 00d7ddba1143 ("hv_netvsc: pair VF based on serial number")
Reported-by: Vitaly Kuznetsov <vkuzn...@redhat.com>
Signed-off-by: Haiyang Zhang <haiya...@microsoft.com>
Reviewed-by: Stephen Hemminger <sthem...@microsoft.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/net/hyperv/netvsc_drv.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 3af6d8d15233..1c37a821895b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2022,14 +2022,15 @@ static void netvsc_vf_setup(struct work_struct *w)
        rtnl_unlock();
 }
 
-/* Find netvsc by VMBus serial number.
- * The PCI hyperv controller records the serial number as the slot.
+/* Find netvsc by VF serial number.
+ * The PCI hyperv controller records the serial number as the slot kobj name.
  */
 static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
 {
        struct device *parent = vf_netdev->dev.parent;
        struct net_device_context *ndev_ctx;
        struct pci_dev *pdev;
+       u32 serial;
 
        if (!parent || !dev_is_pci(parent))
                return NULL; /* not a PCI device */
@@ -2040,16 +2041,22 @@ static struct net_device *get_netvsc_byslot(const 
struct net_device *vf_netdev)
                return NULL;
        }
 
+       if (kstrtou32(pci_slot_name(pdev->slot), 10, &serial)) {
+               netdev_notice(vf_netdev, "Invalid vf serial:%s\n",
+                             pci_slot_name(pdev->slot));
+               return NULL;
+       }
+
        list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
                if (!ndev_ctx->vf_alloc)
                        continue;
 
-               if (ndev_ctx->vf_serial == pdev->slot->number)
+               if (ndev_ctx->vf_serial == serial)
                        return hv_get_drvdata(ndev_ctx->device_ctx);
        }
 
        netdev_notice(vf_netdev,
-                     "no netdev found for slot %u\n", pdev->slot->number);
+                     "no netdev found for vf serial:%u\n", serial);
        return NULL;
 }
 
-- 
2.17.1

Reply via email to