Skip to content

Extending iommufd support with vIOMMU, vDEVICE, vEVENTQ and HW_QUEUE - #11

Open
sboeuf wants to merge 7 commits into
cloud-hypervisor:mainfrom
sboeuf:iommufd_rework
Open

Extending iommufd support with vIOMMU, vDEVICE, vEVENTQ and HW_QUEUE#11
sboeuf wants to merge 7 commits into
cloud-hypervisor:mainfrom
sboeuf:iommufd_rework

Conversation

@sboeuf

@sboeuf sboeuf commented Aug 18, 2026

Copy link
Copy Markdown
Member

Updated the iommufd bindings to have access to all recently merged ioctls related to the iommufd subsystem.
Introduced the support for these new ioctls in iommufd-ioctls, and also added the support for actual abstractions, making the use of these ioctls much simpler from the caller's perspective.
The list of newly support features are vIOMMU, vDEVICE, vEVENTQ and the HW_QUEUE.

This PR is preliminary work that is needed to enable SMMUv3 support through Cloud Hypervisor.

@sboeuf

sboeuf commented Aug 18, 2026

Copy link
Copy Markdown
Member Author

/cc @saravan2 @yamahata

#[allow(
non_camel_case_types,
non_upper_case_globals,
clippy::undocumented_unsafe_blocks

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does rust-bindgen generate this?
Maybe I'm too pedantic, I'd like to split auto-generated code from manual edit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem is, clippy complains without this change, and we need every commit to pass clippy.
Also, I didn't want to add the clippy allow inside the autogenerated code because that means it would need to be added again every time we regenerate the bindings.

Comment thread iommufd-bindings/Cargo.toml Outdated
Comment thread iommufd-ioctls/src/iommufd_ioctls.rs Outdated
data_uptr: data as *mut _ as u64,
..Default::default()
},
IommufdHwInfoData::Vtd(_) => return Err(IommufdError::VtdUnsupported),

@yamahata yamahata Aug 27, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In linux iommufd, other hw info types are defined. In future we may add more.
So catch call error would be better.
_ => Err().

You define AmdUnsupported too. here we don't care of amd case. Maybe catch all unsupported?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you're right, if we make the bindings evolve, we don't want this code to become incorrect. I'll add the _ => Err()

}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum IommuKind {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What scope do you try to abstract?
Linux iommufd defines the following types,iommu_hwpt_data_type, iommu_hw_info_type, iommu_hwpt_invalidate_data_type, iommu_viommu_type, iommu_veventq_type, iommu_hw_queue_type.

I guess its design is intentional. It's hard for me to determine at this point, though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well yes there are abstracted types defined by the iommufd subsystem, but we don't want to manipulate these C types directly since this is a Rust codebase.

let hw_info_type = unsafe { hw_info.__bindgen_anon_1.out_data_type };

match hw_info_type {
iommu_hw_info_type_IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV => Ok(IommuKind::Smmuv3Cmdqv),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we pass 0 for type, Is this dead execution path?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the type is 0, that would mean IOMMU_HW_INFO_TYPE_NONE, and that would be caught by _ => Err(IommufdError::UnknownIommu(hw_info_type)),

pub struct IommufdVIommu {
iommufd: Arc<IommuFd>,
viommu_id: u32,
s2_hwpt_id: u32,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those generic or smmuv3 specific. I wonder if we should cleanly split generic part and hardware specific part.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are meant to be generic. They must not be specific to SMMUv3.
If you have some better naming ideas, please share 😄

Ok(viommu)
}

pub fn alloc_s1_hwpt(&self, dev_id: u32, hwpt_data: &IommufdHwptData) -> Result<u32> {

@yamahata yamahata Aug 27, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm starting to wonder what's the good convention to identify type.
It's fine to compile all those for all arch. (and it will get error on unsupported environment).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I'm following here. The IOMMUFD subsystem is Linux generic, which means all these types should be available, no matter which arch you're running on, right?

Comment thread iommufd-ioctls/src/iommufd_ioctls.rs Outdated
#[derive(Debug, Copy, Clone)]
pub enum IommufdHwInfoData {
Smmuv3(iommu_hw_info_arm_smmuv3),
Vtd(iommu_hw_info_vtd),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see consistency or criteria for which type is defined or not-defined.
Define all that is defined in linux iommufd or just define what we will support?
(If you plan to add scalable io case, that would be great.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that's a bit inconsistent the way I've implemented some things. Let me update this patchset, I will only define and implement for Smmuv3. I will still ensure the code is generic enough to support a new type being added easily without having to rearrange everything.
This should simplify a bit the whole implementation since I'll check for Smmuv3 or Tegra, and otherwise the rest of the types will be considered unsupported.

Comment thread iommufd-ioctls/src/iommufd_ioctls.rs Outdated
})
}

pub fn allocate_s1_hwpt(&mut self, hwpt_data: &IommufdHwptData) -> Result<u32> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same discussion here.

Comment thread iommufd-ioctls/src/lib.rs Outdated
#[error("Intel VT-d is not supported")]
VtdUnsupported,
#[error("AMD IOMMU is not supported")]
AmdUnsupported,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to define for all type? Other approach is to carry type in the error.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I can create a IommuTypeUnsupported(IommuKind).

@yamahata

Copy link
Copy Markdown

Thank you for this patch series. This is great for play around with smmuv3.

I think linux iommufd has already defined the abstraction, in this patch series. I'm starting to wonder to distinguish common ones and device specific ones..

sboeuf and others added 7 commits August 28, 2026 01:36
The bindings were generated from a kernel that predates the iommufd
vIOMMU, vDevice, VEVENTQ and HW_QUEUE uAPI, so none of it can be reached
from Rust. Regenerate against v7.1, which has all of it.

Assisted-by: Claude:Opus-5
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
The crate only exposes the ioctls needed for plain IOAS based mapping,
so a consumer cannot allocate a vIOMMU, bind a vDevice, allocate a
nested HWPT, query hardware information or issue invalidations. All of
that is required to drive nested translation on behalf of a guest.

Assisted-by: Claude:Opus-5
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
The raw ioctl wrappers leave the caller to track object ids, their
parent relationships and their teardown order by hand, which is easy to
get wrong and has to be repeated by every consumer.

Wrap a vIOMMU and its vDevices in owning types so a consumer can drive
nested translation for a passthrough device without managing that
lifecycle itself.

Assisted-by: Claude:Opus-5
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Adding support for allocating a VEVENTQ so that we can forward virtual
events from the HW IOMMU all the way to the guest.

Also adding support for decoding SMMUv3 events specifically.

Assisted-by: Claude:Opus-5
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Programming nested translation means allocating a stage 1 HWPT,
attaching the device to it, and tearing the previous one down.

Given the attach operation needs to be performed at VFIO level, we
introduced a trait that can be implemented from the vfio crate to
attach a device to a HW page table.

Assisted-by: Claude:Opus-5
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
On hardware with NVIDIA's CMDQV extension a guest can own a command
queue with direct read/write access to the HW IOMMU. For instance, this
feature lets a guest submit invalidations without trapping into the VMM.

That's why we extend the ioctls support by allowing a HW queue to be
allocated from the IOMMUFD subsystem.

Assisted-by: Claude:Opus-5
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
Releasing new versions of the crates so that we can benefit from the new
bindings, and so that the ioctls crate now has nested translation
capabilities.

Assisted-by: Claude:Opus-5
Signed-off-by: Sebastien Boeuf <sboeuf@meta.com>
@sboeuf

sboeuf commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

@yamahata I've pushed a new version of this patchset based on your suggestions. Mostly, this is about removing the types that are unused/unsupported but I kept the generic enums wrapping iommufd specific types into their enum variants, and I tried to keep the internal logic generic enough so that we could add VT-d support later if we were interested.

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.

3 participants