diff options
author | Haiyang Zhang <haiyangz@microsoft.com> | 2018-10-15 19:06:15 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-15 22:58:11 -0700 |
commit | 005479556197f80139771960dda0dfdcd2d2aad5 (patch) | |
tree | 40cd822e5ac3a70bc6125258985ccc312fd9bb91 /drivers/net/hyperv | |
parent | b13949678b0abd374214dfd1472b4087a0898562 (diff) | |
download | blackbird-op-linux-005479556197f80139771960dda0dfdcd2d2aad5.tar.gz blackbird-op-linux-005479556197f80139771960dda0dfdcd2d2aad5.zip |
hv_netvsc: fix vf serial matching with pci slot info
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 <vkuznets@redhat.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9bcaf204a7d4..cf36e7ff3191 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2030,14 +2030,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 */ @@ -2048,16 +2049,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; } |