Skip to content

Commit

Permalink
Merge pull request #1288 from hermit-os/virtq
Browse files Browse the repository at this point in the history
refactor(virtqueue): migrate definitions to virtio-spec
  • Loading branch information
mkroening authored Jun 20, 2024
2 parents 0aa4abc + 2f5c734 commit 9fd9dcd
Show file tree
Hide file tree
Showing 8 changed files with 425 additions and 413 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ take-static = "0.1"
talc = { version = "4" }
time = { version = "0.3", default-features = false }
volatile = { version = "0.6", features = ["unstable"] }
zerocopy = { version = "0.7", features = ["derive"] }
zerocopy = { version = "0.7", default-features = false }

[dependencies.smoltcp]
version = "0.11"
Expand Down
127 changes: 22 additions & 105 deletions src/drivers/virtio/virtqueue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ use alloc::rc::Rc;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::mem::{self, MaybeUninit};
use core::ops::{BitAnd, Deref, DerefMut};
use core::ops::{Deref, DerefMut};
use core::ptr;

use align_address::Align;
use async_channel::TryRecvError;
use virtio::{le32, virtq};
use zerocopy::AsBytes;

use self::error::{BufferError, VirtqError};
Expand Down Expand Up @@ -91,15 +92,6 @@ impl From<VqSize> for u16 {
}
}

/// The General Descriptor struct for both Packed and SplitVq.
#[repr(C, align(16))]
struct Descriptor {
address: u64,
len: u32,
buff_id: u16,
flags: u16,
}

type BufferTokenSender = async_channel::Sender<Box<BufferToken>>;

// Public interface of Virtq
Expand Down Expand Up @@ -1187,9 +1179,9 @@ impl BufferToken {
match buff.get_ctrl_desc_mut() {
Some(ctrl_desc) => {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1198,7 +1190,7 @@ impl BufferToken {
desc.len = desc._init_len;
// This is fine as the length of the descriptors is restricted
// by u32::MAX (see also Bytes::new())
ind_desc_lst[ctrl_desc_cnt].len = desc._init_len as u32;
ind_desc_lst[ctrl_desc_cnt].len = (desc._init_len as u32).into();
ctrl_desc_cnt += 1;
init_buff_len += desc._init_len;

Expand Down Expand Up @@ -1231,9 +1223,9 @@ impl BufferToken {
match buff.get_ctrl_desc_mut() {
Some(ctrl_desc) => {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1242,7 +1234,7 @@ impl BufferToken {
desc.len = desc._init_len;
// This is fine as the length of the descriptors is restricted
// by u32::MAX (see also Bytes::new())
ind_desc_lst[ctrl_desc_cnt].len = desc._init_len as u32;
ind_desc_lst[ctrl_desc_cnt].len = (desc._init_len as u32).into();
ctrl_desc_cnt += 1;
init_buff_len += desc._init_len;

Expand Down Expand Up @@ -1286,9 +1278,9 @@ impl BufferToken {
match buff.get_ctrl_desc_mut() {
Some(ctrl_desc) => {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1297,7 +1289,7 @@ impl BufferToken {
desc.len = desc._init_len;
// This is fine as the length of the descriptors is restricted
// by u32::MAX (see also Bytes::new())
ind_desc_lst[ctrl_desc_cnt].len = desc._init_len as u32;
ind_desc_lst[ctrl_desc_cnt].len = (desc._init_len as u32).into();
ctrl_desc_cnt += 1;
init_buff_len += desc._init_len;
}
Expand All @@ -1320,9 +1312,9 @@ impl BufferToken {
match buff.get_ctrl_desc_mut() {
Some(ctrl_desc) => {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1331,7 +1323,7 @@ impl BufferToken {
desc.len = desc._init_len;
// This is fine as the length of the descriptors is restricted
// by u32::MAX (see also Bytes::new())
ind_desc_lst[ctrl_desc_cnt].len = desc._init_len as u32;
ind_desc_lst[ctrl_desc_cnt].len = (desc._init_len as u32).into();
ctrl_desc_cnt += 1;
init_buff_len += desc._init_len;
}
Expand Down Expand Up @@ -1399,9 +1391,9 @@ impl BufferToken {
return Err(VirtqError::General);
} else {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1416,12 +1408,12 @@ impl BufferToken {
desc.len -= len_now - new_len;
// As u32 is save here as all buffers length is restricted by u32::MAX
ind_desc_lst[ctrl_desc_cnt].len -=
(len_now - new_len) as u32;
le32::from_ne((len_now - new_len) as u32);

rest_zero = true;
} else if rest_zero {
desc.len = 0;
ind_desc_lst[ctrl_desc_cnt].len = 0;
ind_desc_lst[ctrl_desc_cnt].len = 0.into();
}
ctrl_desc_cnt += 1;
}
Expand Down Expand Up @@ -1474,9 +1466,9 @@ impl BufferToken {
return Err(VirtqError::General);
} else {
let ind_desc_lst = unsafe {
let size = core::mem::size_of::<Descriptor>();
let size = core::mem::size_of::<virtq::Desc>();
core::slice::from_raw_parts_mut(
ctrl_desc.ptr as *mut Descriptor,
ctrl_desc.ptr as *mut virtq::Desc,
ctrl_desc.len / size,
)
};
Expand All @@ -1491,12 +1483,12 @@ impl BufferToken {
desc.len -= len_now - new_len;
// As u32 is save here as all buffers length is restricted by u32::MAX
ind_desc_lst[ctrl_desc_cnt].len -=
(len_now - new_len) as u32;
le32::from_ne((len_now - new_len) as u32);

rest_zero = true;
} else if rest_zero {
desc.len = 0;
ind_desc_lst[ctrl_desc_cnt].len = 0;
ind_desc_lst[ctrl_desc_cnt].len = 0.into();
}
ctrl_desc_cnt += 1;
}
Expand Down Expand Up @@ -2460,81 +2452,6 @@ pub enum BuffSpec<'a> {
Indirect(&'a [Bytes]),
}

/// Virtqueue descr flags as defined in the specification.
///
/// See Virtio specification v1.1. - 2.6.5
/// v1.1. - 2.7.1
///
/// INFO: `VIRQ_DESC_F_AVAIL` and `VIRTQ_DESC_F_USED` are only valid for packed
/// virtqueues.
#[allow(dead_code, non_camel_case_types)]
#[derive(Debug, Copy, Clone)]
#[repr(u16)]
pub enum DescrFlags {
VIRTQ_DESC_F_NEXT = 1 << 0,
VIRTQ_DESC_F_WRITE = 1 << 1,
VIRTQ_DESC_F_INDIRECT = 1 << 2,
VIRTQ_DESC_F_AVAIL = 1 << 7,
VIRTQ_DESC_F_USED = 1 << 15,
}
use core::ops::Not;
impl Not for DescrFlags {
type Output = u16;

fn not(self) -> Self::Output {
!(u16::from(self))
}
}

use core::ops::BitOr;
impl BitOr for DescrFlags {
type Output = u16;
fn bitor(self, rhs: DescrFlags) -> Self::Output {
u16::from(self) | u16::from(rhs)
}
}

impl BitOr<DescrFlags> for u16 {
type Output = u16;
fn bitor(self, rhs: DescrFlags) -> Self::Output {
self | u16::from(rhs)
}
}

impl BitAnd for DescrFlags {
type Output = u16;

fn bitand(self, rhs: Self) -> Self::Output {
u16::from(self) & u16::from(rhs)
}
}

impl BitAnd<DescrFlags> for u16 {
type Output = u16;

fn bitand(self, rhs: DescrFlags) -> Self::Output {
self & u16::from(rhs)
}
}

impl PartialEq<DescrFlags> for u16 {
fn eq(&self, other: &DescrFlags) -> bool {
*self == u16::from(*other)
}
}

impl From<DescrFlags> for u16 {
fn from(flag: DescrFlags) -> Self {
match flag {
DescrFlags::VIRTQ_DESC_F_NEXT => 1 << 0,
DescrFlags::VIRTQ_DESC_F_WRITE => 1 << 1,
DescrFlags::VIRTQ_DESC_F_INDIRECT => 1 << 2,
DescrFlags::VIRTQ_DESC_F_AVAIL => 1 << 7,
DescrFlags::VIRTQ_DESC_F_USED => 1 << 15,
}
}
}

/// Virtqeueus error module.
///
/// This module unifies errors provided to useres of a virtqueue, independent of the underlying
Expand Down
Loading

0 comments on commit 9fd9dcd

Please sign in to comment.