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
© 2016 - 2026 Red Hat, Inc.