Extending iommufd support with vIOMMU, vDEVICE, vEVENTQ and HW_QUEUE - #11
Extending iommufd support with vIOMMU, vDEVICE, vEVENTQ and HW_QUEUE#11sboeuf wants to merge 7 commits into
Conversation
defb15e to
a3b5cab
Compare
| #[allow( | ||
| non_camel_case_types, | ||
| non_upper_case_globals, | ||
| clippy::undocumented_unsafe_blocks |
There was a problem hiding this comment.
Does rust-bindgen generate this?
Maybe I'm too pedantic, I'd like to split auto-generated code from manual edit.
There was a problem hiding this comment.
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.
| data_uptr: data as *mut _ as u64, | ||
| ..Default::default() | ||
| }, | ||
| IommufdHwInfoData::Vtd(_) => return Err(IommufdError::VtdUnsupported), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
Because we pass 0 for type, Is this dead execution path?
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Are those generic or smmuv3 specific. I wonder if we should cleanly split generic part and hardware specific part.
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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?
| #[derive(Debug, Copy, Clone)] | ||
| pub enum IommufdHwInfoData { | ||
| Smmuv3(iommu_hw_info_arm_smmuv3), | ||
| Vtd(iommu_hw_info_vtd), |
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
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.
| }) | ||
| } | ||
|
|
||
| pub fn allocate_s1_hwpt(&mut self, hwpt_data: &IommufdHwptData) -> Result<u32> { |
| #[error("Intel VT-d is not supported")] | ||
| VtdUnsupported, | ||
| #[error("AMD IOMMU is not supported")] | ||
| AmdUnsupported, |
There was a problem hiding this comment.
Do we want to define for all type? Other approach is to carry type in the error.
There was a problem hiding this comment.
Yes I can create a IommuTypeUnsupported(IommuKind).
|
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.. |
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>
|
@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. |
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.