Skip to content

Commit

Permalink
ref(ioctl): removed create/delete ioctls and added get dm info
Browse files Browse the repository at this point in the history
This commit removes the need of creating and deleting the device
model abstraction inside the kernel since now it is the reponsability
of the I/O Dispatcher system to manage that.
To retrive the device model information (e.g., shared memory region
and device model file descriptor), we created a dedicated ioctl.

Signed-off-by: João Peixoto <[email protected]>
  • Loading branch information
joaopeixoto13 committed Sep 19, 2024
1 parent e87590c commit 8d4e205
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 72 deletions.
51 changes: 20 additions & 31 deletions src/api/src/device_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use crate::defines::{BAO_IO_ASK, BAO_IRQFD_FLAG_ASSIGN};
use crate::error::{Error, Result};
use crate::ioctl::*;
use crate::types::{BaoIoEventFd, BaoIoRequest, BaoIrqFd};
use crate::types::{BaoDMInfo, BaoIoEventFd, BaoIoRequest, BaoIrqFd};
use libc::ioctl;
use std::os::fd::AsRawFd;
use vmm_sys_util::errno;
Expand All @@ -26,6 +26,9 @@ pub struct BaoDeviceModel {
pub fd: i32,
pub devmodel_fd: i32,
pub id: u16,
pub shmem_addr: u64,
pub shmem_size: u64,
pub irq: u32,
}

impl BaoDeviceModel {
Expand All @@ -40,52 +43,38 @@ impl BaoDeviceModel {
///
/// A `Result` containing the result of the operation.
pub fn new(fd: i32, id: u16) -> Result<Self> {
let devmodel_fd;
let mut dm_info = BaoDMInfo {
id: id as u32,
shmem_addr: 0,
shmem_size: 0,
irq: 0,
fd: 0,
};

unsafe {
devmodel_fd = ioctl(fd, BAO_IOCTL_VM_VIRTIO_BACKEND_CREATE(), &(id as i32));
let ret = ioctl(fd, BAO_IOCTL_IO_DM_GET_INFO(), &mut dm_info);

if devmodel_fd < 0 {
if ret < 0 {
return Err(Error::OpenFdFailed(
"devmodel_fd",
"dm_info",
std::io::Error::last_os_error(),
));
}
}

// Create the device model object.
let device_model = BaoDeviceModel {
fd,
devmodel_fd,
id,
fd: fd,
devmodel_fd: dm_info.fd,
id: id,
shmem_addr: dm_info.shmem_addr,
shmem_size: dm_info.shmem_size,
irq: dm_info.irq,
};

Ok(device_model)
}

/// Destroy the device model.
///
/// # Returns
///
/// A `Result` containing the result of the operation.
pub fn destroy(&self) -> Result<()> {
unsafe {
let ret = ioctl(
self.devmodel_fd,
BAO_IOCTL_VM_VIRTIO_BACKEND_DESTROY(),
&(self.id as i32),
);

if ret < 0 {
return Err(Error::OpenFdFailed(
"guest_fd",
std::io::Error::last_os_error(),
));
}
}
Ok(())
}

/// Attach the I/O client to the VM.
///
/// # Returns
Expand Down
34 changes: 14 additions & 20 deletions src/api/src/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,46 @@
#![allow(dead_code)]

use crate::types::BaoDMInfo;

use super::defines::BAO_IOCTL_TYPE;
use super::types::{BaoIoEventFd, BaoIoRequest, BaoIrqFd};
use vmm_sys_util::ioctl::{_IOC_READ, _IOC_WRITE};
use vmm_sys_util::ioctl_ioc_nr;

ioctl_ioc_nr!(
BAO_IOCTL_VM_VIRTIO_BACKEND_CREATE,
_IOC_WRITE,
BAO_IOCTL_IO_DM_GET_INFO,
_IOC_WRITE | _IOC_READ,
BAO_IOCTL_TYPE,
1 as u32,
std::mem::size_of::<u32>() as u32
);
ioctl_ioc_nr!(
BAO_IOCTL_VM_VIRTIO_BACKEND_DESTROY,
_IOC_WRITE,
BAO_IOCTL_TYPE,
2 as u32,
std::mem::size_of::<u32>() as u32
std::mem::size_of::<BaoDMInfo>() as u32
);
ioctl_ioc_nr!(
BAO_IOCTL_IO_ATTACH_CLIENT,
_IOC_WRITE | _IOC_READ,
BAO_IOCTL_TYPE,
3 as u32,
2 as u32,
std::mem::size_of::<BaoIoRequest>() as u32
);
ioctl_ioc_nr!(
BAO_IOCTL_IO_REQUEST_NOTIFY_COMPLETED,
_IOC_WRITE,
BAO_IOCTL_TYPE,
4 as u32,
3 as u32,
std::mem::size_of::<BaoIoRequest>() as u32
);
ioctl_ioc_nr!(
BAO_IOCTL_IOEVENTFD,
_IOC_WRITE,
BAO_IOCTL_TYPE,
5 as u32,
4 as u32,
std::mem::size_of::<BaoIoEventFd>() as u32
);
ioctl_ioc_nr!(
BAO_IOCTL_IRQFD,
_IOC_WRITE,
BAO_IOCTL_TYPE,
6 as u32,
5 as u32,
std::mem::size_of::<BaoIrqFd>() as u32
);

Expand All @@ -62,11 +57,10 @@ mod tests {
/// Tests the BAO IOCTLs constants.
#[test]
fn test_ioctls() {
assert_eq!(0x4004_A601, BAO_IOCTL_VM_VIRTIO_BACKEND_CREATE());
assert_eq!(0x4004_A602, BAO_IOCTL_VM_VIRTIO_BACKEND_DESTROY());
assert_eq!(0xC040_A603, BAO_IOCTL_IO_ATTACH_CLIENT());
assert_eq!(0x4040_A604, BAO_IOCTL_IO_REQUEST_NOTIFY_COMPLETED());
assert_eq!(0x4020_A605, BAO_IOCTL_IOEVENTFD());
assert_eq!(0x4008_A606, BAO_IOCTL_IRQFD());
assert_eq!(0xC040_A601, BAO_IOCTL_IO_DM_GET_INFO());
assert_eq!(0xC040_A602, BAO_IOCTL_IO_ATTACH_CLIENT());
assert_eq!(0x4040_A603, BAO_IOCTL_IO_REQUEST_NOTIFY_COMPLETED());
assert_eq!(0x4020_A604, BAO_IOCTL_IOEVENTFD());
assert_eq!(0x4008_A605, BAO_IOCTL_IRQFD());
}
}
22 changes: 18 additions & 4 deletions src/api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ pub struct BaoIrqFd {
pub flags: u32,
}

/// Struct representing a Bao device model information.
///
/// # Attributes
///
/// * `id` - Device model ID.
/// * `shmem_addr` - Shared memory address.
/// * `shmem_size` - Shared memory size.
/// * `irq` - Device model interrupt.
/// * `fd` - Device model file descriptor.
#[repr(C)]
pub struct BaoDMInfo {
pub id: u32,
pub shmem_addr: u64,
pub shmem_size: u64,
pub irq: u32,
pub fd: i32,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
/// Struct representing a Device configuration.
///
Expand All @@ -91,11 +109,7 @@ pub struct DeviceConfig {
pub id: u32,
#[serde(rename = "type")]
pub device_type: String,
pub shmem_addr: u64,
pub shmem_size: u64,
pub shmem_path: String,
pub mmio_addr: u64,
pub irq: u32,
pub data_plane: String,
// Block device specific fields
pub file_path: Option<String>,
Expand Down
34 changes: 17 additions & 17 deletions src/virtio/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ use api::types::DeviceConfig;
use event_manager::{EventManager, MutEventSubscriber};
use libc::{MAP_SHARED, PROT_READ, PROT_WRITE};
use std::fmt::{self, Debug};
use std::fs::OpenOptions;
use std::fs::File;
use std::os::fd::AsRawFd;
use std::os::unix::io::{FromRawFd, RawFd};
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::{Arc, Mutex};
use vhost_user_frontend::{GuestMemoryMmap, GuestRegionMmap};
Expand Down Expand Up @@ -85,11 +86,22 @@ impl VirtioDeviceCommon {
virtio: VirtioConfig<Queue>,
) -> Result<Self> {
// Create the MMIO configuration.
let mmio = MmioConfig::new(config.mmio_addr, 0x200, config.irq).unwrap();
let mmio = MmioConfig::new(
config.mmio_addr,
0x200,
device_model.lock().unwrap().clone().irq,
)
.unwrap();

// Create a new EventFd for the interrupt (irqfd).
let irqfd = EventFd::new(0).unwrap();

// Extract the device model fields.
let file =
unsafe { File::from_raw_fd(device_model.lock().unwrap().clone().devmodel_fd as RawFd) };
let shemem_addr = device_model.lock().unwrap().clone().shmem_addr;
let shemem_size = device_model.lock().unwrap().clone().shmem_size;

// Create the device object.
let mut device = VirtioDeviceCommon {
config: virtio,
Expand All @@ -103,12 +115,7 @@ impl VirtioDeviceCommon {
// The mmap_offset is set to 0 because the base address of Bao's shared memory driver is
// already defined statically in the backend device tree.
device
.map_region(
0,
&config.shmem_path,
config.shmem_addr,
config.shmem_size as usize,
)
.map_region(0, file, shemem_addr, shemem_size as usize)
.unwrap();

// Register the Irqfd (Host to Guest notification).
Expand Down Expand Up @@ -175,7 +182,7 @@ impl VirtioDeviceCommon {
/// # Arguments
///
/// * `mmap_offset` - Offset of the mmap region.
/// * `path` - Path to the file.
/// * `file` - File descriptor of the region.
/// * `base_addr` - Base address of the region.
/// * `size` - Size of the region.
///
Expand All @@ -185,17 +192,10 @@ impl VirtioDeviceCommon {
fn map_region(
&mut self,
mmap_offset: u64,
path: &str,
file: File,
base_addr: u64,
size: usize,
) -> Result<()> {
// Open the file.
let file = OpenOptions::new()
.read(true)
.write(true)
.open(path)
.unwrap();

// Create a mmap region with proper permissions.
let mmap_region = match MmapRegion::build(
Some(FileOffset::new(file, mmap_offset)),
Expand Down

0 comments on commit 8d4e205

Please sign in to comment.