Skip to content

Conversation

likebreath
Copy link
Collaborator

@likebreath likebreath commented Jul 15, 2025

Summary of the PR

To support advanced hardware features, the vfio subsystem now supports multiple modes, e.g. the legacy vfio mode using container and groups, and the new vfio cdev mode (#92).

The current design and implementation of vfio-ioctls crate only supports legacy mode. Here is a proposal to refactor its design to support both modes.

Refactor internal data structure and APIs

  • Adopt 'KVM_DEV_VFIO_FILE*' uAPIs to accept vfio device files from userspace using both mode;
  • Introduce struct VfioCommon to hold common data structure used by both mode;
  • Make struct VfioDevice and struct VfioDeviceInfo mode agnostic (decoupling specifics of vfio container and groups);

Redefine public APIs (exposed to user-space)

The public APIs exposed to user-space (say VMM) now are defined via a public trait:

/// Trait to define common operations exposed to user-space drivers for
/// VFIO device wrappers that are either backed by a legacy VfioContainer or
/// a VFIO cdev device using iommufd.
pub trait VfioOps: Any + Send + Sync {
    /// Map a region of user space memory (e.g. guest memory) into an IO
    /// address space managed by IOMMU hardware to enable DMA for
    /// associated VFIO devices
    ///
    /// # Parameters
    /// * iova: IO virtual address to map the memory.
    /// * size: size of the memory region.
    /// * user_addr: user space address (e.g. host virtual address) for
    ///   the guest memory region to map.
    fn vfio_dma_map(&self, _iova: u64, _size: u64, _user_addr: u64) -> Result<()> {
        unimplemented!()
    }

    /// Unmap a region of user space memory (e.g. guest memory) from an IO
    /// address space managed by IOMMU hardware to disable DMA for
    /// associated VFIO devices
    ///
    /// # Parameters
    /// * iova: IO virtual address to unmap the memory.
    /// * size: size of the memory region.
    fn vfio_dma_unmap(&self, _iova: u64, _size: u64) -> Result<()> {
        unimplemented!()
    }

    /// Downcast to the underlying vfio wrapper type
    fn as_any(&self) -> &dyn Any {
        unimplemented!()
    }
}

Adopt the new public APIs

Each mode defines its own data structure as the vfio device wrapper, which uses different kernel uAPIs to realize the same public APIs.

For example, with legacy vfio mode, the data strcuture for vfio device wrapper (e.g. refactored struct VfioContainer) keeps using vfio container and groups while implementing pub trait VfioOps to provide common public APIs for user space.

pub struct VfioContainer {
    pub(crate) container: File,
    pub(crate) groups: Mutex<HashMap<u32, Arc<VfioGroup>>>,
    #[allow(dead_code)]
    common: VfioCommon,
}

impl VfioOps for VfioContainer {
    ...
}

Dependencies

This PR requires upgrading vfio-bindings to use kernel v6.6.0 (#104).

Requirements

Before submitting your PR, please make sure you addressed the following
requirements:

  • All commits in this PR have Signed-Off-By trailers (with
    git commit -s), and the commit message has max 60 characters for the
    summary and max 75 characters for each description line.
  • All added/changed functionality has a corresponding unit/integration
    test.
  • All added/changed public-facing functionality has entries in the "Upcoming
    Release" section of CHANGELOG.md (if no such section exists, please create one).
  • Any newly added unsafe code is properly documented.

@likebreath likebreath force-pushed the 0715/vfio_cdev_rfc branch from eeeebd9 to ae93967 Compare July 15, 2025 19:52
@likebreath likebreath marked this pull request as ready for review July 15, 2025 19:56
The 'KVM_DEV_VFIO_FILE*' uAPIs are more generic ways to accept vfio
device files from userspace, supporting both legacy vfio group fd and
the new vfio cdev fd.

For the same reason, `device_set_group()` is replaced with
`device_set_fd()` to to support both legacy vfio mode and vfio cdev
mode.

Signed-off-by: Bo Chen <[email protected]>
This is to hold common data structure used by both the legacy vfio
mode (using vfio container and groups) and the new vfio cdev mode (using
iommufd). As for now, the only shared data structure is the `device fd`
from the hypervisor (e.g. kvm or mshv).

Signed-off-by: Bo Chen <[email protected]>
This trait defines common operations exposed to user-space drivers for
vfio device wrappers that are either backed by a legacy VfioContainer
or a vfio cdev device using iommufd .

Signed-off-by: Bo Chen <[email protected]>
In this way, the refactored `get_device_info` can take a vfio device file
that is opened via either vfio group or vfio cdev, making `struct
VfioDeviceInfo` mode agnostic.

Signed-off-by: Bo Chen <[email protected]>
The refactored `struct VfioDevice` now is mode agnostic. It can support
both legacy vfio mode (using vfio container and group) and the vfio cdev
mode (using iommufd).

Signed-off-by: Bo Chen <[email protected]>
@likebreath
Copy link
Collaborator Author

Just rebased upton #104 merged. cc @liuw @rbradford

@likebreath likebreath changed the title [RFC] Refactor for supporting multiple VFIO interfaces: both legacy mode and cdev mode using iommufd Refactor for supporting multiple VFIO interfaces: both legacy mode and cdev mode using iommufd Aug 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants