Re: [RFC PATCH 00/33] vfio: Introduce selftests for VFIO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 5/24/25 01:29, David Matlack wrote:
This series introduces VFIO selftests, located in
tools/testing/selftests/vfio/.

VFIO selftests aim to enable kernel developers to write and run tests
that take the form of userspace programs that interact with VFIO and
IOMMUFD uAPIs. VFIO selftests can be used to write functional tests for
new features, regression tests for bugs, and performance tests for
optimizations.

These tests are designed to interact with real PCI devices, i.e. they do
not rely on mocking out or faking any behavior in the kernel. This
allows the tests to exercise not only VFIO but also IOMMUFD, the IOMMU
driver, interrupt remapping, IRQ handling, etc.

We chose selftests to host these tests primarily to enable integration
with the existing KVM selftests. As explained in the next section,
enabling KVM developers to test the interaction between VFIO and KVM is
one of the motivators of this series.

Motivation
-----------------------------------------------------------------------

The main motivation for this series is upcoming development in the
kernel to support Hypervisor Live Updates [1][2]. Live Update is a
specialized reboot process where selected devices are kept operational
and their kernel state is preserved and recreated across a kexec. For
devices, DMA and interrupts may continue during the reboot. VFIO-bound
devices are the main target, since the first usecase of Live Updates is
to enable host kernel upgrades in a Cloud Computing environment without
disrupting running customer VMs.

To prepare for upcoming support for Live Updates in VFIO, IOMMUFD, IOMMU
drivers, the PCI layer, etc., we'd like to first lay the ground work for
exercising and testing VFIO from kernel selftests. This way when we
eventually upstream support for Live Updates, we can also upstream tests
for those changes, rather than purely relying on Live Update integration
tests which would be hard to share and reproduce upstream.

But even without Live Updates, VFIO and IOMMUFD are becoming an
increasingly critical component of running KVM-based VMs in cloud
environments. Virtualized networking and storage are increasingly being
offloaded to smart NICs/cards, and demand for high performance
networking, storage, and AI are also leading to NICs, SSDs, and GPUs
being directly attached to VMs via VFIO.

VFIO selftests increases our ability to test in several ways.

  - It enables developers sending VFIO, IOMMUFD, etc. commits upstream to
    test their changes against all existing VFIO selftests, reducing the
    probability of regressions.

  - It enables developers sending VFIO, IOMMUFD, etc. commits upstream to
    include tests alongside their changes, increasing the quality of the
    code that is merged.

  - It enables testing the interaction between VFIO and KVM. There are
    some paths in KVM that are only exercised through VFIO, such as IRQ
    bypass. VFIO selftests provides a helper library to enable KVM
    developers to write KVM selftests to test those interactions [3].

Design
-----------------------------------------------------------------------

VFIO selftests are designed around interacting with with VFIO-managed PCI
devices. As such, the core data struture is struct vfio_pci_device, which
represents a single PCI device.

   struct vfio_pci_device *device;

   device = vfio_pci_device_init("0000:6a:01.0", iommu_mode);

   ...

   vfio_pci_device_cleanup(device);

vfio_pci_device_init() sets up a container or iommufd, depending on the
iommu_mode argument, to manage DMA mappings, fetches information about
the device and what interrupts it supports from VFIO and caches it, and
mmap()s all mappable BARs for the test to use.

There are helper methods that operate on struct vfio_pci_device to do
things like read and write to PCI config space, enable/disable IRQs, and
map memory for DMA,

struct vfio_pci_device and its methods do not care about what device
they are actually interacting with. It can be a GPU, a NIC, an SSD, etc.

To keep things simple initially, VFIO selftests only support a single
device per group and per container/iommufd. But it should be possible to
relax those restrictions in the future, e.g. to enable testing with
multiple devices in the same container/iommufd.

Driver Framework
-----------------------------------------------------------------------

In order to support VFIO selftests where a device is generating DMA and
interrupts on command, the VFIO selftests supports a driver framework.

This framework abstracts away device-specific details allowing VFIO
selftests to be written in a generic way, and then run against different
devices depending on what hardware developers have access to.

The framework also aims to support carrying drivers out-of-tree, e.g.
so that companies can run VFIO selftests with custom/test hardware.
> Drivers must implement the following methods:

  - probe():        Check if the driver supports a given device.
  - init():         Initialize the driver.
  - remove():       Deinitialize the driver and reset the device.
  - memcpy_start(): Kick off a series of repeated memcpys (DMA reads and
                    DMA writes).
  - memcpy_wait():  Wait for a memcpy operation to complete.
  - send_msi():     Make the device send an MSI interrupt.

memcpy_start/wait() are for generating DMA. We separate the operation
into 2 steps so that tests can trigger a long-running DMA operation. We
expect to use this to stress test Live Updates by kicking off a
long-running mempcy operation and then performing a Live Update. These
methods are required to not generate any interrupts.

send_msi() is used for testing MSI and MSI-x interrupts. The driver
tells the test which MSI it will be using via device->driver.msi.

It's the responsibility of the test to set up a region of memory
and map it into the device for use by the driver, e.g. for in-memory
descriptors, before calling init().

A demo of the driver framework can be found in
tools/testing/selftests/vfio/vfio_pci_driver_test.c.

In addition, this series introduces a new KVM selftest to demonstrate
delivering a device MSI directly into a guest, which can be found in
tools/testing/selftests/kvm/vfio_pci_device_irq_test.c.

Tests
-----------------------------------------------------------------------

There are 5 tests in this series, mostly to demonstrate as a
proof-of-concept:

  - tools/testing/selftests/vfio/vfio_pci_device_test.c
  - tools/testing/selftests/vfio/vfio_pci_driver_test.c
  - tools/testing/selftests/vfio/vfio_iommufd_setup_test.c
  - tools/testing/selftests/vfio/vfio_dma_mapping_test.c
  - tools/testing/selftests/kvm/vfio_pci_device_irq_test.c

Integrating with KVM selftests
-----------------------------------------------------------------------

To support testing the interactions between VFIO and KVM, the VFIO
selftests support sharing its library with the KVM selftest. The patches
at the end of this series demonstrate how that works.

Essentially, we allow the KVM selftests to build their own copy of
tools/testing/selftests/vfio/lib/ and link it into KVM selftests
binaries. This requires minimal changes to the KVM selftests Makefile.

Future Areas of Development
-----------------------------------------------------------------------

Library:

  - Driver support for devices that can be used on AMD, ARM, and other
    platforms.
  - Driver support for a device available in QEMU VMs.

The QEMU igb and igbvf devices are good candidates.

I have been using these in QEMU VMs to test a few scenarios, IOMMUFD
and also VFIO migration with a custom VFIO PCI igbvf variant driver,
with dummy get/set handlers.

We also have the mdev mtty device driver but I think it is less useful.
Having a PCI device is more interesting for test coverage.

Anyhow, this is an excellent proposal. I plan to give it a try as soon
as possible, once the recent QEMU proposals for VFIO have made progress.

  - Support for tests that use multiple devices.
  - Support for IOMMU groups with multiple devices.
  - Support for multiple devices sharing the same container/iommufd.
  - Sharing TEST_ASSERT() macros and other common code between KVM
    and VFIO selftests.

Tests:

  - DMA mapping performance tests for BARs/HugeTLB/etc.


Thanks,

C.




  - Live Update selftests.
  - Porting Sean's KVM selftest for posted interrupts to use the VFIO
    selftests library [3]

This series can also be found on GitHub:

   https://github.com/dmatlack/linux/tree/vfio/selftests/rfc

Cc: Alex Williamson <alex.williamson@xxxxxxxxxx>
Cc: Jason Gunthorpe <jgg@xxxxxxxxxx>
Cc: Kevin Tian <kevin.tian@xxxxxxxxx>
Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Cc: Sean Christopherson <seanjc@xxxxxxxxxx>
Cc: Vipin Sharma <vipinsh@xxxxxxxxxx>
Cc: Josh Hilke <jrhilke@xxxxxxxxxx>
Cc: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>
Cc: Saeed Mahameed <saeedm@xxxxxxxxxx>
Cc: Saeed Mahameed <saeedm@xxxxxxxxxx>
Cc: Adithya Jayachandran <ajayachandra@xxxxxxxxxx>
Cc: Parav Pandit <parav@xxxxxxxxxx>
Cc: Leon Romanovsky <leonro@xxxxxxxxxx>
Cc: Vinicius Costa Gomes <vinicius.gomes@xxxxxxxxx>
Cc: Dave Jiang <dave.jiang@xxxxxxxxx>
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>

[1] https://lore.kernel.org/all/f35359d5-63e1-8390-619f-67961443bfe1@xxxxxxxxxx/
[2] https://lore.kernel.org/all/20250515182322.117840-1-pasha.tatashin@xxxxxxxxxx/
[3] https://lore.kernel.org/kvm/20250404193923.1413163-68-seanjc@xxxxxxxxxx/

David Matlack (28):
   selftests: Create tools/testing/selftests/vfio
   vfio: selftests: Add a helper library for VFIO selftests
   vfio: selftests: Introduce vfio_pci_device_test
   tools headers: Add stub definition for __iomem
   tools headers: Import asm-generic MMIO helpers
   tools headers: Import x86 MMIO helper overrides
   tools headers: Import iosubmit_cmds512()
   tools headers: Import drivers/dma/ioat/{hw.h,registers.h}
   tools headers: Import drivers/dma/idxd/registers.h
   tools headers: Import linux/pci_ids.h
   vfio: selftests: Keep track of DMA regions mapped into the device
   vfio: selftests: Enable asserting MSI eventfds not firing
   vfio: selftests: Add a helper for matching vendor+device IDs
   vfio: selftests: Add driver framework
   vfio: sefltests: Add vfio_pci_driver_test
   vfio: selftests: Add driver for Intel CBDMA
   vfio: selftests: Add driver for Intel DSA
   vfio: selftests: Move helper to get cdev path to libvfio
   vfio: selftests: Encapsulate IOMMU mode
   vfio: selftests: Add [-i iommu_mode] option to all tests
   vfio: selftests: Add vfio_type1v2_mode
   vfio: selftests: Add iommufd_compat_type1{,v2} modes
   vfio: selftests: Add iommufd mode
   vfio: selftests: Make iommufd the default iommu_mode
   vfio: selftests: Add a script to help with running VFIO selftests
   KVM: selftests: Build and link sefltests/vfio/lib into KVM selftests
   KVM: selftests: Test sending a vfio-pci device IRQ to a VM
   KVM: selftests: Use real device MSIs in vfio_pci_device_irq_test

Josh Hilke (5):
   vfio: selftests: Test basic VFIO and IOMMUFD integration
   vfio: selftests: Move vfio dma mapping test to their own file
   vfio: selftests: Add test to reset vfio device.
   vfio: selftests: Use command line to set hugepage size for DMA mapping
     test
   vfio: selftests: Validate 2M/1G HugeTLB are mapped as 2M/1G in IOMMU

  MAINTAINERS                                   |    7 +
  tools/arch/x86/include/asm/io.h               |  101 +
  tools/arch/x86/include/asm/special_insns.h    |   27 +
  tools/include/asm-generic/io.h                |  482 +++
  tools/include/asm/io.h                        |   11 +
  tools/include/drivers/dma/idxd/registers.h    |  601 +++
  tools/include/drivers/dma/ioat/hw.h           |  270 ++
  tools/include/drivers/dma/ioat/registers.h    |  251 ++
  tools/include/linux/compiler.h                |    4 +
  tools/include/linux/io.h                      |    4 +-
  tools/include/linux/pci_ids.h                 | 3212 +++++++++++++++++
  tools/testing/selftests/Makefile              |    1 +
  tools/testing/selftests/kvm/Makefile.kvm      |    6 +-
  .../testing/selftests/kvm/include/kvm_util.h  |    4 +
  tools/testing/selftests/kvm/lib/kvm_util.c    |   21 +
  .../selftests/kvm/vfio_pci_device_irq_test.c  |  173 +
  tools/testing/selftests/vfio/.gitignore       |    7 +
  tools/testing/selftests/vfio/Makefile         |   20 +
  .../testing/selftests/vfio/lib/drivers/dsa.c  |  416 +++
  .../testing/selftests/vfio/lib/drivers/ioat.c |  235 ++
  .../selftests/vfio/lib/include/vfio_util.h    |  271 ++
  tools/testing/selftests/vfio/lib/libvfio.mk   |   26 +
  .../selftests/vfio/lib/vfio_pci_device.c      |  573 +++
  .../selftests/vfio/lib/vfio_pci_driver.c      |  126 +
  tools/testing/selftests/vfio/run.sh           |  110 +
  .../selftests/vfio/vfio_dma_mapping_test.c    |  239 ++
  .../selftests/vfio/vfio_iommufd_setup_test.c  |  133 +
  .../selftests/vfio/vfio_pci_device_test.c     |  195 +
  .../selftests/vfio/vfio_pci_driver_test.c     |  256 ++
  29 files changed, 7780 insertions(+), 2 deletions(-)
  create mode 100644 tools/arch/x86/include/asm/io.h
  create mode 100644 tools/arch/x86/include/asm/special_insns.h
  create mode 100644 tools/include/asm-generic/io.h
  create mode 100644 tools/include/asm/io.h
  create mode 100644 tools/include/drivers/dma/idxd/registers.h
  create mode 100644 tools/include/drivers/dma/ioat/hw.h
  create mode 100644 tools/include/drivers/dma/ioat/registers.h
  create mode 100644 tools/include/linux/pci_ids.h
  create mode 100644 tools/testing/selftests/kvm/vfio_pci_device_irq_test.c
  create mode 100644 tools/testing/selftests/vfio/.gitignore
  create mode 100644 tools/testing/selftests/vfio/Makefile
  create mode 100644 tools/testing/selftests/vfio/lib/drivers/dsa.c
  create mode 100644 tools/testing/selftests/vfio/lib/drivers/ioat.c
  create mode 100644 tools/testing/selftests/vfio/lib/include/vfio_util.h
  create mode 100644 tools/testing/selftests/vfio/lib/libvfio.mk
  create mode 100644 tools/testing/selftests/vfio/lib/vfio_pci_device.c
  create mode 100644 tools/testing/selftests/vfio/lib/vfio_pci_driver.c
  create mode 100755 tools/testing/selftests/vfio/run.sh
  create mode 100644 tools/testing/selftests/vfio/vfio_dma_mapping_test.c
  create mode 100644 tools/testing/selftests/vfio/vfio_iommufd_setup_test.c
  create mode 100644 tools/testing/selftests/vfio/vfio_pci_device_test.c
  create mode 100644 tools/testing/selftests/vfio/vfio_pci_driver_test.c


base-commit: a11a72229881d8ac1d52ea727101bc9c744189c1
prerequisite-patch-id: 3bae97c9e1093148763235f47a84fa040b512d04





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux