From: Michal Privoznik <mprivozn@redhat.com> In case of an SRIOV device the sysfs struct looks like this: -r--r--r--. 1 root root 4096 Feb 26 14:40 /sys/bus/pci/devices/0000:82:00.0/sriov_totalvfs lrwxrwxrwx. 1 root root 0 Feb 25 22:51 /sys/bus/pci/devices/0000:82:00.0/virtfn0 -> ../0000:82:10.0 lrwxrwxrwx. 1 root root 0 Feb 25 22:51 /sys/bus/pci/devices/0000:82:00.0/virtfn1 -> ../0000:82:10.4 lrwxrwxrwx. 1 root root 0 Feb 25 22:51 /sys/bus/pci/devices/0000:82:00.0/virtfn2 -> ../0000:82:11.0 lrwxrwxrwx. 1 root root 0 Feb 25 22:51 /sys/bus/pci/devices/0000:82:00.0/virtfn3 -> ../0000:82:11.4 Of course, there is much more, I've just picked up files that our code touches during hotplug of an <interface type='hostdev'/>. The first file 'sriov_totalvfs' contains the maximum number of VFs supported. Then, for each VF created there's 'virtfnN' symlink to individual VFs. Teach our virpcimock to create the file and symlinks. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/virpcimock.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/tests/virpcimock.c b/tests/virpcimock.c index ca345f37a3..c59359b889 100644 --- a/tests/virpcimock.c +++ b/tests/virpcimock.c @@ -141,6 +141,8 @@ struct pciDevice { int device; int klass; int iommuGroup; + int sriovTotalvfs; + unsigned int virtfnCount; const char *physfn; struct pciDriver *driver; /* Driver attached. NULL if attached to no driver */ struct pciVPD vpd; @@ -439,6 +441,38 @@ pci_device_create_iommu(const struct pciDevice *dev, } +static void +register_vf(struct pciDevice *vf) +{ + struct pciDeviceAddress pfAddr; + struct pciDevice *pf; + g_autofree char *relPath = NULL; + g_autofree char *pfPath = NULL; + g_autofree char *virtfnName = NULL; + + if (pci_address_parse(&pfAddr, vf->physfn) < 0) + ABORT("Unable to parse PCI address %s", vf->physfn); + + if (!(pf = pci_device_find_by_id(&pfAddr))) { + ABORT("Unable to find PF for VF %s", vf->physfn); + } + + relPath = g_strdup_printf("../" ADDR_STR_FMT, + vf->addr.domain, + vf->addr.bus, + vf->addr.device, + vf->addr.function); + + virtfnName = g_strdup_printf("virtfn%u", pf->virtfnCount); + + pfPath = pci_device_get_path(pf, NULL, true); + + make_symlink(pfPath, virtfnName, relPath); + + pf->virtfnCount++; +} + + static void pci_device_new_from_stub(const struct pciDevice *data) { @@ -537,6 +571,14 @@ pci_device_new_from_stub(const struct pciDevice *data) make_symlink(devsympath, devid, tmp); + if (dev->sriovTotalvfs) { + if (g_snprintf(tmp, sizeof(tmp), "%d\n", dev->sriovTotalvfs) < 0) { + ABORT("@tmp overflow"); + } + + make_file(devpath, "sriov_totalvfs", tmp, -1); + } + if (dev->physfn) { if (g_snprintf(tmp, sizeof(tmp), "%s%s/devices/%s", fakerootdir, @@ -544,6 +586,8 @@ pci_device_new_from_stub(const struct pciDevice *data) ABORT("@tmp overflow"); } make_symlink(devpath, "physfn", tmp); + + register_vf(dev); } if (dev->vpd.data && dev->vpd.vpd_len) @@ -1043,12 +1087,14 @@ init_env(void) MAKE_PCI_DEVICE("0000:0a:01.0", 0x8086, 0x0047, 8); MAKE_PCI_DEVICE("0000:0a:02.0", 0x8286, 0x0048, 8); MAKE_PCI_DEVICE("0000:0a:03.0", 0x8386, 0x0048, 8); - MAKE_PCI_DEVICE("0000:06:12.0", 0x8086, 0x0047, 9); + MAKE_PCI_DEVICE("0000:06:12.0", 0x8086, 0x0047, 9, + .sriovTotalvfs = 7); MAKE_PCI_DEVICE("0000:06:12.1", 0x8086, 0x0047, 10, .physfn = "0000:06:12.0"); /* Virtual Function */ MAKE_PCI_DEVICE("0000:06:12.2", 0x8086, 0x0047, 11, .physfn = "0000:06:12.0"); /* Virtual Function */ - MAKE_PCI_DEVICE("0021:de:1f.0", 0x8086, 0x0047, 12); + MAKE_PCI_DEVICE("0021:de:1f.0", 0x8086, 0x0047, 12, + .sriovTotalvfs = 7); MAKE_PCI_DEVICE("0021:de:1f.1", 0x8086, 0x0047, 13, .physfn = "0021:de:1f.0"); /* Virtual Function */ -- 2.52.0