From: Jason Gunthorpe jgg@nvidia.com
mainline inclusion from mainline-v5.18-rc1 commit 21ca9fb62d4688da41825e0f05d8e7e26afc69d6 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I86ITO Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------------------------------------
The PCI core uses the VF index internally, often called the vf_id, during the setup of the VF, eg pci_iov_add_virtfn().
This index is needed for device drivers that implement live migration for their internal operations that configure/control their VFs.
Specifically, mlx5_vfio_pci driver that is introduced in coming patches from this series needs it and not the bus/device/function which is exposed today.
Add pci_iov_vf_id() which computes the vf_id by reversing the math that was used to create the bus/device/function.
Link: https://lore.kernel.org/all/20220224142024.147653-2-yishaih@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Acked-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Yishai Hadas yishaih@nvidia.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: jiangdongxu jiangdongxu1@huawei.com --- drivers/pci/iov.c | 14 ++++++++++++++ include/linux/pci.h | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4afd4ee4f7f0..08db0610da76 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -32,6 +32,20 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int vf_id) dev->sriov->stride * vf_id) & 0xff; }
+int pci_iov_vf_id(struct pci_dev *dev) +{ + struct pci_dev *pf; + + if (!dev->is_virtfn) + return -EINVAL; + + pf = pci_physfn(dev); + return (((dev->bus->number << 8) + dev->devfn) - + ((pf->bus->number << 8) + pf->devfn + pf->sriov->offset)) / + pf->sriov->stride; +} +EXPORT_SYMBOL_GPL(pci_iov_vf_id); + /* * Per SR-IOV spec sec 3.3.10 and 3.3.11, First VF Offset and VF Stride may * change when NumVFs changes. diff --git a/include/linux/pci.h b/include/linux/pci.h index c05a2cc63c8a..cde61998a055 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2118,7 +2118,7 @@ void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar); #ifdef CONFIG_PCI_IOV int pci_iov_virtfn_bus(struct pci_dev *dev, int id); int pci_iov_virtfn_devfn(struct pci_dev *dev, int id); - +int pci_iov_vf_id(struct pci_dev *dev); int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); void pci_disable_sriov(struct pci_dev *dev);
@@ -2146,6 +2146,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev *dev, int id) { return -ENOSYS; } + +static inline int pci_iov_vf_id(struct pci_dev *dev) +{ + return -ENOSYS; +} + static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) { return -ENODEV; }