group.rs0.00%
1
// Copyright 2024 Google LLC2
//3
// Licensed under the Apache License, Version 2.0 (the "License");4
// you may not use this file except in compliance with the License.5
// You may obtain a copy of the License at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// distributed under the License is distributed on an "AS IS" BASIS,11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12
// See the License for the specific language governing permissions and13
// limitations under the License.14
15
use std::ffi::CString;16
use std::fs::File;17
use std::os::fd::{AsRawFd, FromRawFd};18
use std::path::Path;19
use std::sync::Arc;20
21
use snafu::ResultExt;22
23
use crate::sys::vfio::{24
VfioIommu, vfio_group_get_device_fd, vfio_group_set_container, vfio_group_unset_container,25
};26
use crate::vfio::container::Container;27
use crate::vfio::device::Device;28
use crate::vfio::{Result, error};29
30
#[derive(Debug)]31
pub struct Group {32
container: Option<Arc<Container>>,33
fd: File,34
}35
36
impl Group {37
pub fn new(path: &Path) -> Result<Self> {38
let fd = File::open(path).context(error::AccessDevice { path })?;39
Ok(Group {40
fd,41
container: None,42
})43
}44
45
pub fn attach(&mut self, container: Arc<Container>, iommu: VfioIommu) -> Result<()> {46
unsafe { vfio_group_set_container(&self.fd, &container.fd().as_raw_fd()) }?;47
container.set_iommu(iommu)?;48
self.container.replace(container);49
Ok(())50
}51
52
pub fn detach(&mut self) -> Result<()> {53
if self.container.is_none() {54
return Ok(());55
}56
unsafe { vfio_group_unset_container(&self.fd) }?;57
self.container = None;58
Ok(())59
}60
}61
62
impl Drop for Group {63
fn drop(&mut self) {64
if let Err(e) = self.detach() {65
log::error!(66
"Group-{}: detaching from container: {e:?}",67
self.fd.as_raw_fd()68
);69
}70
}71
}72
73
#[derive(Debug)]74
pub struct DevFd {75
fd: File,76
_group: Arc<Group>,77
}78
79
impl DevFd {80
pub fn new(group: Arc<Group>, id: &str) -> Result<Self> {81
let id_c = CString::new(id).unwrap();82
let fd = unsafe { vfio_group_get_device_fd(&group.fd, id_c.as_ptr()) }?;83
Ok(DevFd {84
fd: unsafe { File::from_raw_fd(fd) },85
_group: group,86
})87
}88
}89
90
impl Device for DevFd {91
fn fd(&self) -> &File {92
&self.fd93
}94
}95