Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions iommufd-ioctls/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
## Changed

## Added
- [[9]](https://github.com/cloud-hypervisor/iommufd/pull/9) Add `Iommufd::destroy_iommu_object` to release iommufd
objects explicitly.
- [[9]](https://github.com/cloud-hypervisor/iommufd/pull/9) Add `Iommufd::new_from_fd` to construct a `Iommufd` from
a pre-opened iommufd file.

## Fixed

Expand Down
33 changes: 33 additions & 0 deletions iommufd-ioctls/src/iommufd_ioctls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ impl IommuFd {
Ok(IommuFd { iommufd })
}

/// New from an already-opened `/dev/iommu` file. Caller transfers
/// ownership; closing the fd is now `IommuFd`'s responsibility.
pub fn new_from_fd(file: File) -> Self {
IommuFd { iommufd: file }
}

pub fn destroy_iommu_object(&self, id: u32) -> Result<()> {
let destroy_data = iommu_destroy {
size: std::mem::size_of::<iommu_destroy>() as u32,
id,
};
iommufd_syscall::destroy_iommu_object(self, &destroy_data)
}

pub fn alloc_iommu_ioas(&self, alloc_data: &mut iommu_ioas_alloc) -> Result<()> {
iommufd_syscall::alloc_iommu_ioas(self, alloc_data)
}
Expand All @@ -44,6 +58,7 @@ impl AsRawFd for IommuFd {
}
}

ioctl_io_nr!(IOMMU_DESTROY, IOMMUFD_TYPE as u32, IOMMUFD_CMD_DESTROY);
ioctl_io_nr!(
IOMMU_IOAS_ALLOC,
IOMMUFD_TYPE as u32,
Expand All @@ -64,6 +79,23 @@ pub(crate) mod iommufd_syscall {
use super::*;
use vmm_sys_util::ioctl::{ioctl_with_mut_ref, ioctl_with_ref};

pub(crate) fn destroy_iommu_object(
iommufd: &IommuFd,
destroy_data: &iommu_destroy,
) -> Result<()> {
// SAFETY:
// 1. The file descriptor provided by 'iommufd' is valid and open.
// 2. The 'destroy_data' points to initialized memory with expected data structure,
// and remains valid for the duration of sysca
// 3. The return value is checked.
let ret = unsafe { ioctl_with_ref(iommufd, IOMMU_DESTROY(), destroy_data) };
if ret < 0 {
Err(IommufdError::IommuDestroy(SysError::last()))
} else {
Ok(())
}
}

pub(crate) fn alloc_iommu_ioas(
iommufd: &IommuFd,
alloc_data: &mut iommu_ioas_alloc,
Expand Down Expand Up @@ -115,6 +147,7 @@ mod tests {

#[test]
fn test_iommufd_ioctl_code() {
assert_eq!(IOMMU_DESTROY(), 15232);
assert_eq!(IOMMU_IOAS_ALLOC(), 15233);
assert_eq!(IOMMU_IOAS_MAP(), 15237);
assert_eq!(IOMMU_IOAS_UNMAP(), 15238);
Expand Down
2 changes: 2 additions & 0 deletions iommufd-ioctls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub use iommufd_ioctls::*;
pub enum IommufdError {
#[error("failed to open /dev/iommufd: {0}")]
OpenIommufd(#[source] io::Error),
#[error("failed to destroy iommufd object: {0}")]
IommuDestroy(#[source] SysError),
#[error("failed to allocate IOAS: {0}")]
IommuIoasAlloc(#[source] SysError),
#[error("failed to map an IOVA range to the IOAS: {0}")]
Expand Down
Loading