driver inclusion category:feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6DRLU CVE: NA
When using the old PCI_FUNC method to obtain the vf id, if the number of vf big than 8, the obtained id number will be wrong, and the new method needs to be used to correct it.
Signed-off-by: Longfang Liu liulongfang@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- .../hisilicon/migration/acc_vf_migration.c | 17 ++++++++++-- .../hisilicon/migration/acc_vf_migration.h | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/hisilicon/migration/acc_vf_migration.c b/drivers/crypto/hisilicon/migration/acc_vf_migration.c index 920f19916fea..7c5fc4eb02ac 100644 --- a/drivers/crypto/hisilicon/migration/acc_vf_migration.c +++ b/drivers/crypto/hisilicon/migration/acc_vf_migration.c @@ -1610,6 +1610,19 @@ static int acc_vf_dev_init(struct pci_dev *pdev, struct hisi_qm *pf_qm, return -ENOMEM; }
+static int hisi_acc_get_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; +} + static void *acc_vf_probe(struct pci_dev *pdev) { struct acc_vf_migration *acc_vf_dev; @@ -1635,7 +1648,7 @@ static void *acc_vf_probe(struct pci_dev *pdev) return ERR_PTR(-EINVAL); }
- vf_id = PCI_FUNC(vf_dev->devfn); + vf_id = hisi_acc_get_vf_id(vf_dev); if (vf_id < 0) { dev_info(&pdev->dev, "vf device: %s, vf id: %d\n", pf_qm->dev_name, vf_id); @@ -1652,7 +1665,7 @@ static void *acc_vf_probe(struct pci_dev *pdev) return ERR_PTR(-ENOMEM); }
- acc_vf_dev->vf_id = vf_id; + acc_vf_dev->vf_id = vf_id + 1; acc_vf_dev->vf_vendor = pdev->vendor; acc_vf_dev->vf_device = pdev->device; acc_vf_dev->pf_dev = pf_dev; diff --git a/drivers/crypto/hisilicon/migration/acc_vf_migration.h b/drivers/crypto/hisilicon/migration/acc_vf_migration.h index 2f459eecb8f0..8b38b9943d35 100644 --- a/drivers/crypto/hisilicon/migration/acc_vf_migration.h +++ b/drivers/crypto/hisilicon/migration/acc_vf_migration.h @@ -215,6 +215,32 @@ struct acc_vf_region_ops { struct vfio_info_cap *caps); };
+/* Single Root I/O Virtualization */ +struct pci_sriov { + int pos; /* Capability position */ + int nres; /* Number of resources */ + u32 cap; /* SR-IOV Capabilities */ + u16 ctrl; /* SR-IOV Control */ + u16 total_VFs; /* Total VFs associated with the PF */ + u16 initial_VFs; /* Initial VFs associated with the PF */ + u16 num_VFs; /* Number of VFs available */ + u16 offset; /* First VF Routing ID offset */ + u16 stride; /* Following VF stride */ + u16 vf_device; /* VF device ID */ + u32 pgsz; /* Page size for BAR alignment */ + u8 link; /* Function Dependency Link */ + u8 max_VF_buses; /* Max buses consumed by VFs */ + u16 driver_max_VFs; /* Max num VFs driver supports */ + struct pci_dev *dev; /* Lowest numbered PF */ + struct pci_dev *self; /* This PF */ + u32 class; /* VF device */ + u8 hdr_type; /* VF header type */ + u16 subsystem_vendor; /* VF subsystem vendor */ + u16 subsystem_device; /* VF subsystem device */ + resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */ + bool drivers_autoprobe; /* Auto probing of VFs by driver */ +}; + struct acc_vf_region { u32 type; u32 subtype;