[PATCH v6 18/27] vfio: selftests: Initialize vfio_pci_device using a VFIO cdev FD
From: Vipin Sharma
Date: Mon Nov 02 2026 - 11:49:13 EST
Use the given VFIO cdev FD to initialize vfio_pci_device in VFIO
selftests. Add the assertion to make sure that passed cdev FD is not
used with legacy VFIO APIs. If VFIO cdev FD is provided then do not open
the device instead use the FD for any interaction with the device.
This API will allow writing selftests where VFIO device FD is preserved
using liveupdate and retrieved later using liveupdate ioctl after kexec.
Co-developed-by: David Matlack <dmatlack@xxxxxxxxxx>
Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
Signed-off-by: Vipin Sharma <vipinsh@xxxxxxxxxx>
---
.../lib/include/libvfio/vfio_pci_device.h | 3 +++
.../selftests/vfio/lib/vfio_pci_device.c | 25 ++++++++++++++-----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
index e19bd94b8dd2..9a62bfb6b440 100644
--- a/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
+++ b/tools/testing/selftests/vfio/lib/include/libvfio/vfio_pci_device.h
@@ -40,6 +40,9 @@ struct vfio_pci_device {
struct vfio_pci_device *vfio_pci_device_alloc(const char *bdf, struct iommu *iommu);
void vfio_pci_device_free(struct vfio_pci_device *device);
+struct vfio_pci_device *__vfio_pci_device_init(const char *bdf,
+ struct iommu *iommu,
+ int device_fd);
struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu);
void vfio_pci_device_cleanup(struct vfio_pci_device *device);
diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
index 4063a0e2b3df..af789c859586 100644
--- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c
+++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
@@ -457,9 +457,13 @@ void vfio_pci_cdev_open(struct vfio_pci_device *device, const char *bdf)
}
static void vfio_pci_iommufd_setup(struct vfio_pci_device *device,
- const char *bdf, const char *vf_token)
+ const char *bdf, int device_fd,
+ const char *vf_token)
{
- vfio_pci_cdev_open(device, bdf);
+ if (device_fd >= 0)
+ device->fd = device_fd;
+ else
+ vfio_pci_cdev_open(device, bdf);
vfio_device_bind_iommufd(device->fd, device->iommu->iommufd, vf_token);
vfio_device_attach_iommufd_pt(device->fd, device->iommu->ioas_id);
}
@@ -482,16 +486,20 @@ void vfio_pci_device_free(struct vfio_pci_device *device)
free(device);
}
-struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu)
+struct vfio_pci_device *__vfio_pci_device_init(const char *bdf,
+ struct iommu *iommu,
+ int device_fd)
{
struct vfio_pci_device *device;
device = vfio_pci_device_alloc(bdf, iommu);
- if (iommu->mode->container_path)
+ if (iommu->mode->container_path) {
+ VFIO_ASSERT_EQ(device_fd, -1);
vfio_pci_container_setup(device, bdf, NULL);
- else
- vfio_pci_iommufd_setup(device, bdf, NULL);
+ } else {
+ vfio_pci_iommufd_setup(device, bdf, device_fd, NULL);
+ }
vfio_pci_device_setup(device);
vfio_pci_driver_probe(device);
@@ -499,6 +507,11 @@ struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iomm
return device;
}
+struct vfio_pci_device *vfio_pci_device_init(const char *bdf, struct iommu *iommu)
+{
+ return __vfio_pci_device_init(bdf, iommu, /*device_fd=*/-1);
+}
+
void vfio_pci_device_cleanup(struct vfio_pci_device *device)
{
int i;
--
2.56.0.317.g454f8302e1-goog