From 5dc961c1f910a1cd34eed939b1f403c24da69fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 10:03:21 +0200 Subject: [PATCH 01/10] refactor(virtqueue/packed): migrate from `zerocopy::little_endian` to `virtio-spec` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- Cargo.lock | 1 - Cargo.toml | 2 +- src/drivers/virtio/virtqueue/packed.rs | 46 +++++++++++++++----------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c78d45abb..a36da41841 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1829,7 +1829,6 @@ version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ - "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index b60dfef45f..e041181e70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index f2f1b4b53b..036136d830 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -12,7 +12,7 @@ use core::{ops, ptr}; use align_address::Align; use virtio::pci::NotificationData; -use zerocopy::little_endian; +use virtio::{le16, le32, le64}; #[cfg(not(feature = "pci"))] use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; @@ -302,7 +302,7 @@ impl DescriptorRing { // See Virtio specfification v1.1. - 2.7.21 fence(Ordering::SeqCst); self.ring[usize::from(first_ctrl_settings.0)].flags |= - first_ctrl_settings.2.as_flags_avail().into(); + le16::from_ne(first_ctrl_settings.2.as_flags_avail()); RingIdx { off: self.write_index, @@ -469,10 +469,16 @@ impl<'a> ReadCtrl<'a> { /// updating the queue and returns the respective TransferToken. fn poll_next(&mut self) -> Option> { // Check if descriptor has been marked used. - if self.desc_ring.ring[usize::from(self.position)].flags.get() & WrapCount::flag_mask() + if self.desc_ring.ring[usize::from(self.position)] + .flags + .to_ne() & WrapCount::flag_mask() == self.desc_ring.dev_wc.as_flags_used() { - let buff_id = usize::from(self.desc_ring.ring[usize::from(self.position)].buff_id); + let buff_id = usize::from( + self.desc_ring.ring[usize::from(self.position)] + .buff_id + .to_ne(), + ); let mut tkn = self.desc_ring.tkn_ref_ring[buff_id].take().expect( "The buff_id is incorrect or the reference to the TransferToken was misplaced.", ); @@ -578,11 +584,11 @@ impl<'a> ReadCtrl<'a> { if write_len >= ring_desc.len.into() { // Complete length has been written but reduce len_written for next one - write_len -= ring_desc.len.get(); + write_len -= ring_desc.len.to_ne(); } else { ring_desc.len = (write_len).into(); desc.len = write_len as usize; - write_len -= ring_desc.len.get(); + write_len -= ring_desc.len.to_ne(); assert_eq!(write_len, 0); } } @@ -630,11 +636,11 @@ impl<'a> ReadCtrl<'a> { if write_len >= ring_desc.len.into() { // Complete length has been written but reduce len_written for next one - write_len -= ring_desc.len.get(); + write_len -= ring_desc.len.to_ne(); } else { ring_desc.len = write_len.into(); desc.len = write_len as usize; - write_len -= ring_desc.len.get(); + write_len -= ring_desc.len.to_ne(); assert_eq!(write_len, 0); } } @@ -766,9 +772,9 @@ impl<'a> WriteCtrl<'a> { // descriptor. if self.start == self.position { let desc_ref = &mut self.desc_ring.ring[usize::from(self.position)]; - desc_ref - .address - .set(paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)).into()); + desc_ref.address = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) + .as_u64() + .into(); desc_ref.len = (mem_desc.len as u32).into(); desc_ref.buff_id = (mem_desc.id.as_ref().unwrap().0).into(); // Remove possibly set avail and used flags @@ -780,9 +786,9 @@ impl<'a> WriteCtrl<'a> { self.incrmt(); } else { let desc_ref = &mut self.desc_ring.ring[usize::from(self.position)]; - desc_ref - .address - .set(paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)).into()); + desc_ref.address = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) + .as_u64() + .into(); desc_ref.len = (mem_desc.len as u32).into(); desc_ref.buff_id = (self.buff_id).into(); // Remove possibly set avail and used flags and then set avail and used @@ -808,17 +814,17 @@ impl<'a> WriteCtrl<'a> { // See Virtio specfification v1.1. - 2.7.21 fence(Ordering::SeqCst); self.desc_ring.ring[usize::from(self.start)].flags |= - self.wrap_at_init.as_flags_avail().into(); + le16::from_ne(self.wrap_at_init.as_flags_avail()); } } #[derive(Clone, Copy)] -#[repr(C, align(16))] +#[repr(C)] struct Descriptor { - address: little_endian::U64, - len: little_endian::U32, - buff_id: little_endian::U16, - flags: little_endian::U16, + address: le64, + len: le32, + buff_id: le16, + flags: le16, } impl Descriptor { From e33b8ba8d50e11fd1adfc196fb37ffcccceec665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 11:01:55 +0200 Subject: [PATCH 02/10] feat(virtio-spec): add `virtq::DescF` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/lib.rs | 1 + virtio-spec/src/virtq.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 virtio-spec/src/virtq.rs diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index d520f173bd..84da687337 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -14,6 +14,7 @@ pub mod fs; pub mod mmio; pub mod net; pub mod pci; +pub mod virtq; pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64}; use num_enum::{FromPrimitive, IntoPrimitive}; diff --git a/virtio-spec/src/virtq.rs b/virtio-spec/src/virtq.rs new file mode 100644 index 0000000000..e66e1b42e4 --- /dev/null +++ b/virtio-spec/src/virtq.rs @@ -0,0 +1,27 @@ +//! Virtqueue definitions + +use endian_num::le16; + +endian_bitflags! { + /// Virtqueue descriptor flags + #[doc(alias = "VIRTQ_DESC_F")] + pub struct DescF: le16 { + /// This marks a buffer as continuing via the next field. + #[doc(alias = "VIRTQ_DESC_F_NEXT")] + const NEXT = 1; + + /// This marks a buffer as device write-only (otherwise device read-only). + #[doc(alias = "VIRTQ_DESC_F_WRITE")] + const WRITE = 2; + + /// This means the buffer contains a list of buffer descriptors. + #[doc(alias = "VIRTQ_DESC_F_INDIRECT")] + const INDIRECT = 4; + + #[doc(alias = "VIRTQ_DESC_F_AVAIL")] + const AVAIL = 1 << 7; + + #[doc(alias = "VIRTQ_DESC_F_USED")] + const USED = 1 << 15; + } +} From ed87942798e44c8d5337b7f03e1ada80f2bb4cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 11:02:54 +0200 Subject: [PATCH 03/10] refactor(virtqueue): migrate to `DescrFlags` to virtio-spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/virtqueue/mod.rs | 77 +--------------- src/drivers/virtio/virtqueue/packed.rs | 116 ++++++++++--------------- src/drivers/virtio/virtqueue/split.rs | 38 ++++---- 3 files changed, 67 insertions(+), 164 deletions(-) diff --git a/src/drivers/virtio/virtqueue/mod.rs b/src/drivers/virtio/virtqueue/mod.rs index 69269bc251..e80e198450 100644 --- a/src/drivers/virtio/virtqueue/mod.rs +++ b/src/drivers/virtio/virtqueue/mod.rs @@ -18,7 +18,7 @@ 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; @@ -2460,81 +2460,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 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 for u16 { - type Output = u16; - - fn bitand(self, rhs: DescrFlags) -> Self::Output { - self & u16::from(rhs) - } -} - -impl PartialEq for u16 { - fn eq(&self, other: &DescrFlags) -> bool { - *self == u16::from(*other) - } -} - -impl From 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 diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index 036136d830..66d0435d53 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -12,7 +12,7 @@ use core::{ops, ptr}; use align_address::Align; use virtio::pci::NotificationData; -use virtio::{le16, le32, le64}; +use virtio::{le16, le32, le64, virtq}; #[cfg(not(feature = "pci"))] use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; @@ -20,8 +20,8 @@ use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; use super::super::transport::pci::{ComCfg, NotifCfg, NotifCtrl}; use super::error::VirtqError; use super::{ - BuffSpec, Buffer, BufferToken, BufferType, Bytes, DescrFlags, MemDescr, MemPool, TransferToken, - Virtq, VirtqPrivate, VqIndex, VqSize, + BuffSpec, Buffer, BufferToken, BufferType, Bytes, MemDescr, MemPool, TransferToken, Virtq, + VirtqPrivate, VqIndex, VqSize, }; use crate::arch::mm::paging::{BasePageSize, PageSize}; use crate::arch::mm::{paging, VirtAddr}; @@ -60,8 +60,8 @@ struct WrapCount(bool); impl WrapCount { /// Masks all other bits, besides the wrap count specific ones. - fn flag_mask() -> u16 { - 1 << 7 | 1 << 15 + fn flag_mask() -> virtq::DescF { + virtq::DescF::AVAIL | virtq::DescF::USED } /// Returns a new WrapCount struct initialized to true or 1. @@ -84,11 +84,11 @@ impl WrapCount { /// /// I.e.: Set avail flag to match the WrapCount and the used flag /// to NOT match the WrapCount. - fn as_flags_avail(&self) -> u16 { + fn as_flags_avail(&self) -> virtq::DescF { if self.0 { - 1 << 7 + virtq::DescF::AVAIL } else { - 1 << 15 + virtq::DescF::USED } } @@ -97,11 +97,11 @@ impl WrapCount { /// /// I.e.: Set avail flag to match the WrapCount and the used flag /// to also match the WrapCount. - fn as_flags_used(&self) -> u16 { + fn as_flags_used(&self) -> virtq::DescF { if self.0 { - 1 << 7 | 1 << 15 + virtq::DescF::AVAIL | virtq::DescF::USED } else { - 0 + virtq::DescF::empty() } } } @@ -202,7 +202,7 @@ impl DescriptorRing { match (send_buff.get_ctrl_desc(), recv_buff.get_ctrl_desc()) { (Some(ctrl_desc), Some(_)) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } (None, None) => { let mut buff_len = @@ -210,22 +210,18 @@ impl DescriptorRing { for desc in send_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_NEXT.into()); + ctrl.write_desc(desc, virtq::DescF::NEXT); } else { - ctrl.write_desc(desc, 0); + ctrl.write_desc(desc, virtq::DescF::empty()); } buff_len -= 1; } for desc in recv_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc( - desc, - DescrFlags::VIRTQ_DESC_F_NEXT - | DescrFlags::VIRTQ_DESC_F_WRITE, - ); + ctrl.write_desc(desc, virtq::DescF::NEXT | virtq::DescF::WRITE); } else { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_WRITE.into()); + ctrl.write_desc(desc, virtq::DescF::WRITE); } buff_len -= 1; } @@ -242,16 +238,16 @@ impl DescriptorRing { match send_buff.get_ctrl_desc() { Some(ctrl_desc) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } None => { let mut buff_len = send_buff.as_slice().len(); for desc in send_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_NEXT.into()); + ctrl.write_desc(desc, virtq::DescF::NEXT); } else { - ctrl.write_desc(desc, 0); + ctrl.write_desc(desc, virtq::DescF::empty()); } buff_len -= 1; } @@ -262,20 +258,16 @@ impl DescriptorRing { match recv_buff.get_ctrl_desc() { Some(ctrl_desc) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } None => { let mut buff_len = recv_buff.as_slice().len(); for desc in recv_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc( - desc, - DescrFlags::VIRTQ_DESC_F_NEXT - | DescrFlags::VIRTQ_DESC_F_WRITE, - ); + ctrl.write_desc(desc, virtq::DescF::NEXT | virtq::DescF::WRITE); } else { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_WRITE.into()); + ctrl.write_desc(desc, virtq::DescF::WRITE); } buff_len -= 1; } @@ -302,7 +294,7 @@ impl DescriptorRing { // See Virtio specfification v1.1. - 2.7.21 fence(Ordering::SeqCst); self.ring[usize::from(first_ctrl_settings.0)].flags |= - le16::from_ne(first_ctrl_settings.2.as_flags_avail()); + first_ctrl_settings.2.as_flags_avail(); RingIdx { off: self.write_index, @@ -337,28 +329,25 @@ impl DescriptorRing { match (send_buff.get_ctrl_desc(), recv_buff.get_ctrl_desc()) { (Some(ctrl_desc), Some(_)) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } (None, None) => { let mut buff_len = send_buff.as_slice().len() + recv_buff.as_slice().len(); for desc in send_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_NEXT.into()); + ctrl.write_desc(desc, virtq::DescF::NEXT); } else { - ctrl.write_desc(desc, 0); + ctrl.write_desc(desc, virtq::DescF::empty()); } buff_len -= 1; } for desc in recv_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc( - desc, - DescrFlags::VIRTQ_DESC_F_NEXT | DescrFlags::VIRTQ_DESC_F_WRITE, - ); + ctrl.write_desc(desc, virtq::DescF::NEXT | virtq::DescF::WRITE); } else { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_WRITE.into()); + ctrl.write_desc(desc, virtq::DescF::WRITE); } buff_len -= 1; } @@ -371,16 +360,16 @@ impl DescriptorRing { match send_buff.get_ctrl_desc() { Some(ctrl_desc) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } None => { let mut buff_len = send_buff.as_slice().len(); for desc in send_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_NEXT.into()); + ctrl.write_desc(desc, virtq::DescF::NEXT); } else { - ctrl.write_desc(desc, 0); + ctrl.write_desc(desc, virtq::DescF::empty()); } buff_len -= 1; } @@ -391,19 +380,16 @@ impl DescriptorRing { match recv_buff.get_ctrl_desc() { Some(ctrl_desc) => { // One indirect descriptor with only flag indirect set - ctrl.write_desc(ctrl_desc, DescrFlags::VIRTQ_DESC_F_INDIRECT.into()); + ctrl.write_desc(ctrl_desc, virtq::DescF::INDIRECT); } None => { let mut buff_len = recv_buff.as_slice().len(); for desc in recv_buff.as_slice() { if buff_len > 1 { - ctrl.write_desc( - desc, - DescrFlags::VIRTQ_DESC_F_NEXT | DescrFlags::VIRTQ_DESC_F_WRITE, - ); + ctrl.write_desc(desc, virtq::DescF::NEXT | virtq::DescF::WRITE); } else { - ctrl.write_desc(desc, DescrFlags::VIRTQ_DESC_F_WRITE.into()); + ctrl.write_desc(desc, virtq::DescF::WRITE); } buff_len -= 1; } @@ -469,9 +455,7 @@ impl<'a> ReadCtrl<'a> { /// updating the queue and returns the respective TransferToken. fn poll_next(&mut self) -> Option> { // Check if descriptor has been marked used. - if self.desc_ring.ring[usize::from(self.position)] - .flags - .to_ne() & WrapCount::flag_mask() + if self.desc_ring.ring[usize::from(self.position)].flags & WrapCount::flag_mask() == self.desc_ring.dev_wc.as_flags_used() { let buff_id = usize::from( @@ -662,7 +646,7 @@ impl<'a> ReadCtrl<'a> { // self.desc_ring.ring[self.position].len = 0; // self.desc_ring.ring[self.position].buff_id = 0; self.desc_ring.ring[usize::from(self.position)].flags = - self.desc_ring.dev_wc.as_flags_used().into(); + self.desc_ring.dev_wc.as_flags_used(); } /// Updates the accessible len of the memory areas accessible by the drivers to be consistent with @@ -767,7 +751,7 @@ impl<'a> WriteCtrl<'a> { /// with the given flags. /// * Flags for avail and used will be set by the queue itself. /// * -> Only set different flags here. - fn write_desc(&mut self, mem_desc: &MemDescr, flags: u16) { + fn write_desc(&mut self, mem_desc: &MemDescr, flags: virtq::DescF) { // This also sets the buff_id for the WriteCtrl struct to the ID of the first // descriptor. if self.start == self.position { @@ -778,9 +762,7 @@ impl<'a> WriteCtrl<'a> { desc_ref.len = (mem_desc.len as u32).into(); desc_ref.buff_id = (mem_desc.id.as_ref().unwrap().0).into(); // Remove possibly set avail and used flags - desc_ref.flags = - (flags & !(DescrFlags::VIRTQ_DESC_F_AVAIL) & !(DescrFlags::VIRTQ_DESC_F_USED)) - .into(); + desc_ref.flags = flags - virtq::DescF::AVAIL - virtq::DescF::USED; self.buff_id = mem_desc.id.as_ref().unwrap().0; self.incrmt(); @@ -793,10 +775,7 @@ impl<'a> WriteCtrl<'a> { desc_ref.buff_id = (self.buff_id).into(); // Remove possibly set avail and used flags and then set avail and used // according to the current WrapCount. - desc_ref.flags = - ((flags & !(DescrFlags::VIRTQ_DESC_F_AVAIL) & !(DescrFlags::VIRTQ_DESC_F_USED)) - | self.desc_ring.drv_wc.as_flags_avail()) - .into(); + desc_ref.flags = flags - virtq::DescF::AVAIL - virtq::DescF::USED; self.incrmt() } @@ -813,8 +792,7 @@ impl<'a> WriteCtrl<'a> { // The driver performs a suitable memory barrier to ensure the device sees the updated descriptor table and available ring before the next step. // See Virtio specfification v1.1. - 2.7.21 fence(Ordering::SeqCst); - self.desc_ring.ring[usize::from(self.start)].flags |= - le16::from_ne(self.wrap_at_init.as_flags_avail()); + self.desc_ring.ring[usize::from(self.start)].flags |= self.wrap_at_init.as_flags_avail(); } } @@ -824,16 +802,16 @@ struct Descriptor { address: le64, len: le32, buff_id: le16, - flags: le16, + flags: virtq::DescF, } impl Descriptor { - fn new(add: u64, len: u32, id: u16, flags: u16) -> Self { + fn new(add: u64, len: u32, id: u16, flags: virtq::DescF) -> Self { Descriptor { address: add.into(), len: len.into(), buff_id: id.into(), - flags: flags.into(), + flags, } } } @@ -1241,7 +1219,7 @@ impl VirtqPrivate for PackedVq { paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, 0, - DescrFlags::VIRTQ_DESC_F_WRITE.into(), + virtq::DescF::WRITE, ); crtl_desc_iter += 1; @@ -1255,7 +1233,7 @@ impl VirtqPrivate for PackedVq { paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, 0, - 0, + virtq::DescF::empty(), ); crtl_desc_iter += 1; @@ -1269,7 +1247,7 @@ impl VirtqPrivate for PackedVq { paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, 0, - 0, + virtq::DescF::empty(), ); crtl_desc_iter += 1; @@ -1280,7 +1258,7 @@ impl VirtqPrivate for PackedVq { paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, 0, - DescrFlags::VIRTQ_DESC_F_WRITE.into(), + virtq::DescF::WRITE, ); crtl_desc_iter += 1; diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index c2a8488693..e7c75b9566 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -11,7 +11,7 @@ use core::mem::{size_of, MaybeUninit}; use core::ptr::{self, NonNull}; use virtio::pci::NotificationData; -use virtio::{le16, le32, le64}; +use virtio::{le16, le32, le64, virtq}; use volatile::access::ReadOnly; use volatile::{map_field, VolatilePtr, VolatileRef}; @@ -21,7 +21,7 @@ use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; use super::super::transport::pci::{ComCfg, NotifCfg, NotifCtrl}; use super::error::VirtqError; use super::{ - BuffSpec, BufferToken, BufferType, Bytes, DescrFlags, MemDescr, MemPool, TransferToken, Virtq, + BuffSpec, BufferToken, BufferType, Bytes, MemDescr, MemPool, TransferToken, Virtq, VirtqPrivate, VqIndex, VqSize, }; use crate::arch::memory_barrier; @@ -33,16 +33,16 @@ use crate::mm::device_alloc::DeviceAlloc; struct Descriptor { address: le64, len: le32, - flags: le16, + flags: virtq::DescF, next: le16, } impl Descriptor { - fn new(addr: u64, len: u32, flags: u16, next: u16) -> Self { + fn new(addr: u64, len: u32, flags: virtq::DescF, next: u16) -> Self { Descriptor { address: addr.into(), len: len.into(), - flags: flags.into(), + flags, next: next.into(), } } @@ -203,14 +203,14 @@ impl DescrRing { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_INDIRECT | DescrFlags::VIRTQ_DESC_F_WRITE, + virtq::DescF::INDIRECT | virtq::DescF::WRITE, 0, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_INDIRECT.into(), + virtq::DescF::INDIRECT, 0, ) } @@ -224,14 +224,14 @@ impl DescrRing { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE | DescrFlags::VIRTQ_DESC_F_NEXT, + virtq::DescF::WRITE | virtq::DescF::NEXT, next_index, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_NEXT.into(), + virtq::DescF::NEXT, next_index, ) } @@ -239,14 +239,14 @@ impl DescrRing { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE.into(), + virtq::DescF::WRITE, 0, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - 0, + virtq::DescF::empty(), 0, ) }; @@ -573,14 +573,14 @@ impl VirtqPrivate for SplitVq { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE | DescrFlags::VIRTQ_DESC_F_NEXT, + virtq::DescF::WRITE | virtq::DescF::NEXT, (crtl_desc_iter + 1) as u16, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE.into(), + virtq::DescF::WRITE, 0, ) }; @@ -597,14 +597,14 @@ impl VirtqPrivate for SplitVq { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_NEXT.into(), + virtq::DescF::NEXT, (crtl_desc_iter + 1) as u16, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - 0, + virtq::DescF::empty(), 0, ) }; @@ -621,14 +621,14 @@ impl VirtqPrivate for SplitVq { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_NEXT.into(), + virtq::DescF::NEXT, (crtl_desc_iter + 1) as u16, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - 0, + virtq::DescF::empty(), 0, ) }; @@ -642,14 +642,14 @@ impl VirtqPrivate for SplitVq { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE | DescrFlags::VIRTQ_DESC_F_NEXT, + virtq::DescF::WRITE | virtq::DescF::NEXT, (crtl_desc_iter + 1) as u16, ) } else { Descriptor::new( paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), desc.len as u32, - DescrFlags::VIRTQ_DESC_F_WRITE.into(), + virtq::DescF::WRITE, 0, ) }; From cef1d2fe1dbbb2152030e6c3427cf9a82d7ca355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 14:25:16 +0200 Subject: [PATCH 04/10] feat(virtio-spec): add `virtq::Desc` and `pvirtq::Desc` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/lib.rs | 1 + virtio-spec/src/pvirtq.rs | 20 ++++++++++++++++++++ virtio-spec/src/virtq.rs | 20 +++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 virtio-spec/src/pvirtq.rs diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index 84da687337..554cdca63c 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -14,6 +14,7 @@ pub mod fs; pub mod mmio; pub mod net; pub mod pci; +pub mod pvirtq; pub mod virtq; pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64}; diff --git a/virtio-spec/src/pvirtq.rs b/virtio-spec/src/pvirtq.rs new file mode 100644 index 0000000000..07525e3d90 --- /dev/null +++ b/virtio-spec/src/pvirtq.rs @@ -0,0 +1,20 @@ +use endian_num::{le16, le32, le64}; + +use crate::virtq; + +/// Packed Virtqueue Descriptor +#[doc(alias = "pvirtq_desc")] +#[repr(C)] +pub struct Desc { + /// Buffer Address. + pub addr: le64, + + /// Buffer Length. + pub len: le32, + + /// Buffer ID. + pub id: le16, + + /// The flags depending on descriptor type. + pub flags: virtq::DescF, +} diff --git a/virtio-spec/src/virtq.rs b/virtio-spec/src/virtq.rs index e66e1b42e4..f05ff2209f 100644 --- a/virtio-spec/src/virtq.rs +++ b/virtio-spec/src/virtq.rs @@ -1,6 +1,24 @@ //! Virtqueue definitions -use endian_num::le16; +use endian_num::{le16, le32, le64}; + +/// Split Virtqueue Descriptor +#[doc(alias = "virtq_desc")] +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct Desc { + /// Address (guest-physical). + pub addr: le64, + + /// Length. + pub len: le32, + + /// The flags as indicated in [`DescF`]. + pub flags: DescF, + + /// Next field if flags & NEXT + pub next: le16, +} endian_bitflags! { /// Virtqueue descriptor flags From a388ee7ed7e715972ca42806283dd70ca0b312e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 14:26:22 +0200 Subject: [PATCH 05/10] refactor(virtqueue): migrate `Descriptor` to virtio-spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/virtqueue/packed.rs | 119 ++++++------- src/drivers/virtio/virtqueue/split.rs | 232 +++++++++++++------------ 2 files changed, 173 insertions(+), 178 deletions(-) diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index 66d0435d53..76c29560eb 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -12,7 +12,7 @@ use core::{ops, ptr}; use align_address::Align; use virtio::pci::NotificationData; -use virtio::{le16, le32, le64, virtq}; +use virtio::{pvirtq, virtq}; #[cfg(not(feature = "pci"))] use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; @@ -108,7 +108,7 @@ impl WrapCount { /// Structure which allows to control raw ring and operate easily on it struct DescriptorRing { - ring: &'static mut [Descriptor], + ring: &'static mut [pvirtq::Desc], tkn_ref_ring: Box<[Option>]>, // Controlling variables for the ring @@ -127,11 +127,11 @@ struct DescriptorRing { impl DescriptorRing { fn new(size: u16) -> Self { // Allocate heap memory via a vec, leak and cast - let _mem_len = (usize::from(size) * core::mem::size_of::()) + let _mem_len = (usize::from(size) * core::mem::size_of::()) .align_up(BasePageSize::SIZE as usize); let ptr = ptr::with_exposed_provenance_mut(crate::mm::allocate(_mem_len, true).0 as usize); - let ring: &'static mut [Descriptor] = + let ring: &'static mut [pvirtq::Desc] = unsafe { core::slice::from_raw_parts_mut(ptr, size.into()) }; // Descriptor ID's run from 1 to size_of_queue. In order to index directly into the @@ -458,11 +458,7 @@ impl<'a> ReadCtrl<'a> { if self.desc_ring.ring[usize::from(self.position)].flags & WrapCount::flag_mask() == self.desc_ring.dev_wc.as_flags_used() { - let buff_id = usize::from( - self.desc_ring.ring[usize::from(self.position)] - .buff_id - .to_ne(), - ); + let buff_id = usize::from(self.desc_ring.ring[usize::from(self.position)].id.to_ne()); let mut tkn = self.desc_ring.tkn_ref_ring[buff_id].take().expect( "The buff_id is incorrect or the reference to the TransferToken was misplaced.", ); @@ -546,9 +542,9 @@ impl<'a> ReadCtrl<'a> { // This should read the descriptors inside the ctrl desc memory and update the memory // accordingly let desc_slice = unsafe { - let size = core::mem::size_of::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut pvirtq::Desc, ctrl_desc.len / size, ) }; @@ -583,9 +579,9 @@ impl<'a> ReadCtrl<'a> { // This should read the descriptors inside the ctrl desc memory and update the memory // accordingly let desc_slice = unsafe { - let size = core::mem::size_of::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut pvirtq::Desc, ctrl_desc.len / size, ) }; @@ -603,9 +599,9 @@ impl<'a> ReadCtrl<'a> { // This should read the descriptors inside the ctrl desc memory and update the memory // accordingly let desc_slice = unsafe { - let size = core::mem::size_of::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut pvirtq::Desc, ctrl_desc.len / size, ) }; @@ -756,11 +752,11 @@ impl<'a> WriteCtrl<'a> { // descriptor. if self.start == self.position { let desc_ref = &mut self.desc_ring.ring[usize::from(self.position)]; - desc_ref.address = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) + desc_ref.addr = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) .as_u64() .into(); desc_ref.len = (mem_desc.len as u32).into(); - desc_ref.buff_id = (mem_desc.id.as_ref().unwrap().0).into(); + desc_ref.id = (mem_desc.id.as_ref().unwrap().0).into(); // Remove possibly set avail and used flags desc_ref.flags = flags - virtq::DescF::AVAIL - virtq::DescF::USED; @@ -768,11 +764,11 @@ impl<'a> WriteCtrl<'a> { self.incrmt(); } else { let desc_ref = &mut self.desc_ring.ring[usize::from(self.position)]; - desc_ref.address = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) + desc_ref.addr = paging::virt_to_phys(VirtAddr::from(mem_desc.ptr as u64)) .as_u64() .into(); desc_ref.len = (mem_desc.len as u32).into(); - desc_ref.buff_id = (self.buff_id).into(); + desc_ref.id = (self.buff_id).into(); // Remove possibly set avail and used flags and then set avail and used // according to the current WrapCount. desc_ref.flags = flags - virtq::DescF::AVAIL - virtq::DescF::USED; @@ -796,26 +792,6 @@ impl<'a> WriteCtrl<'a> { } } -#[derive(Clone, Copy)] -#[repr(C)] -struct Descriptor { - address: le64, - len: le32, - buff_id: le16, - flags: virtq::DescF, -} - -impl Descriptor { - fn new(add: u64, len: u32, id: u16, flags: virtq::DescF) -> Self { - Descriptor { - address: add.into(), - len: len.into(), - buff_id: id.into(), - flags, - } - } -} - /// Driver and device event suppression struct used in packed virtqueues. /// /// Structure layout see Virtio specification v1.1. - 2.7.14 @@ -1189,7 +1165,7 @@ impl VirtqPrivate for PackedVq { (Some(send_desc_lst), Some(recv_desc_lst)) => send_desc_lst.len() + recv_desc_lst.len(), }; - let sz_indrct_lst = match Bytes::new(core::mem::size_of::() * len) { + let sz_indrct_lst = match Bytes::new(core::mem::size_of::() * len) { Some(bytes) => bytes, None => return Err(VirtqError::BufferToLarge), }; @@ -1206,8 +1182,11 @@ impl VirtqPrivate for PackedVq { let mut crtl_desc_iter = 0usize; let desc_slice = unsafe { - let size = core::mem::size_of::(); - core::slice::from_raw_parts_mut(ctrl_desc.ptr as *mut Descriptor, ctrl_desc.len / size) + let size = core::mem::size_of::(); + core::slice::from_raw_parts_mut( + ctrl_desc.ptr as *mut pvirtq::Desc, + ctrl_desc.len / size, + ) }; match (send, recv) { @@ -1215,12 +1194,14 @@ impl VirtqPrivate for PackedVq { // Only recving descriptorsn (those are writabel by device) (None, Some(recv_desc_lst)) => { for desc in recv_desc_lst { - desc_slice[crtl_desc_iter] = Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - 0, - virtq::DescF::WRITE, - ); + desc_slice[crtl_desc_iter] = pvirtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + id: 0.into(), + flags: virtq::DescF::WRITE, + }; crtl_desc_iter += 1; } @@ -1229,12 +1210,14 @@ impl VirtqPrivate for PackedVq { // Only sending descriptors (Some(send_desc_lst), None) => { for desc in send_desc_lst { - desc_slice[crtl_desc_iter] = Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - 0, - virtq::DescF::empty(), - ); + desc_slice[crtl_desc_iter] = pvirtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + id: 0.into(), + flags: virtq::DescF::empty(), + }; crtl_desc_iter += 1; } @@ -1243,23 +1226,27 @@ impl VirtqPrivate for PackedVq { (Some(send_desc_lst), Some(recv_desc_lst)) => { // Send descriptors ALWAYS before receiving ones. for desc in send_desc_lst { - desc_slice[crtl_desc_iter] = Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - 0, - virtq::DescF::empty(), - ); + desc_slice[crtl_desc_iter] = pvirtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + id: 0.into(), + flags: virtq::DescF::empty(), + }; crtl_desc_iter += 1; } for desc in recv_desc_lst { - desc_slice[crtl_desc_iter] = Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - 0, - virtq::DescF::WRITE, - ); + desc_slice[crtl_desc_iter] = pvirtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + id: 0.into(), + flags: virtq::DescF::WRITE, + }; crtl_desc_iter += 1; } diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index e7c75b9566..fac4f88fc3 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -11,7 +11,7 @@ use core::mem::{size_of, MaybeUninit}; use core::ptr::{self, NonNull}; use virtio::pci::NotificationData; -use virtio::{le16, le32, le64, virtq}; +use virtio::{le16, le32, virtq}; use volatile::access::ReadOnly; use volatile::{map_field, VolatilePtr, VolatileRef}; @@ -28,26 +28,6 @@ use crate::arch::memory_barrier; use crate::arch::mm::{paging, VirtAddr}; use crate::mm::device_alloc::DeviceAlloc; -#[repr(C)] -#[derive(Copy, Clone)] -struct Descriptor { - address: le64, - len: le32, - flags: virtq::DescF, - next: le16, -} - -impl Descriptor { - fn new(addr: u64, len: u32, flags: virtq::DescF, next: u16) -> Self { - Descriptor { - address: addr.into(), - len: len.into(), - flags, - next: next.into(), - } - } -} - // The generic structure eases the creation of the layout for the statically // sized portion of [AvailRing] and [UsedRing]. This way, to be allocated they // only need to be extended with the dynamic portion. @@ -132,13 +112,13 @@ struct DescrRing { /// /// These tables may only be accessed via volatile operations. /// See the corresponding method for a safe wrapper. - descr_table_cell: Box]>, DeviceAlloc>, + descr_table_cell: Box]>, DeviceAlloc>, avail_ring_cell: Box, DeviceAlloc>, used_ring_cell: Box, DeviceAlloc>, } impl DescrRing { - fn descr_table_ref(&mut self) -> VolatileRef<'_, [MaybeUninit]> { + fn descr_table_ref(&mut self) -> VolatileRef<'_, [MaybeUninit]> { unsafe { VolatileRef::new(NonNull::new(self.descr_table_cell.get_mut()).unwrap()) } } fn avail_ring_ref(&mut self) -> VolatileRef<'_, AvailRing> { @@ -200,19 +180,23 @@ impl DescrRing { let descriptor = if is_indirect { assert!(len == 1); if is_write { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::INDIRECT | virtq::DescF::WRITE, - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::INDIRECT | virtq::DescF::WRITE, + next: 0.into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::INDIRECT, - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::INDIRECT, + next: 0.into(), + } } } else if len > 1 { let next_index = { @@ -221,34 +205,42 @@ impl DescrRing { }; if is_write { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE | virtq::DescF::NEXT, - next_index, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE | virtq::DescF::NEXT, + next: next_index.into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::NEXT, - next_index, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::NEXT, + next: next_index.into(), + } } } else if is_write { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE, - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE, + next: 0.into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::empty(), - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::empty(), + next: 0.into(), + } }; self.descr_table_ref() @@ -409,8 +401,8 @@ impl Virtq for SplitVq { let descr_table_cell = unsafe { core::mem::transmute::< - Box<[MaybeUninit], DeviceAlloc>, - Box]>, DeviceAlloc>, + Box<[MaybeUninit], DeviceAlloc>, + Box]>, DeviceAlloc>, >(Box::new_uninit_slice_in(size.into(), ALLOCATOR)) }; @@ -542,7 +534,7 @@ impl VirtqPrivate for SplitVq { (Some(send_desc_lst), Some(recv_desc_lst)) => send_desc_lst.len() + recv_desc_lst.len(), }; - let sz_indrct_lst = match Bytes::new(core::mem::size_of::() * len) { + let sz_indrct_lst = match Bytes::new(core::mem::size_of::() * len) { Some(bytes) => bytes, None => return Err(VirtqError::BufferToLarge), }; @@ -560,8 +552,8 @@ impl VirtqPrivate for SplitVq { let mut desc_lst_len = len; let desc_slice = unsafe { - let size = core::mem::size_of::(); - core::slice::from_raw_parts_mut(ctrl_desc.ptr as *mut Descriptor, ctrl_desc.len / size) + let size = core::mem::size_of::(); + core::slice::from_raw_parts_mut(ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size) }; match (send, recv) { @@ -570,19 +562,23 @@ impl VirtqPrivate for SplitVq { (None, Some(recv_desc_lst)) => { for desc in recv_desc_lst { desc_slice[crtl_desc_iter] = if desc_lst_len > 1 { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE | virtq::DescF::NEXT, - (crtl_desc_iter + 1) as u16, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE | virtq::DescF::NEXT, + next: ((crtl_desc_iter + 1) as u16).into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE, - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE, + next: 0.into(), + } }; desc_lst_len -= 1; @@ -594,19 +590,23 @@ impl VirtqPrivate for SplitVq { (Some(send_desc_lst), None) => { for desc in send_desc_lst { desc_slice[crtl_desc_iter] = if desc_lst_len > 1 { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::NEXT, - (crtl_desc_iter + 1) as u16, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::NEXT, + next: ((crtl_desc_iter + 1) as u16).into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::empty(), - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::empty(), + next: 0.into(), + } }; desc_lst_len -= 1; @@ -618,19 +618,23 @@ impl VirtqPrivate for SplitVq { // Send descriptors ALWAYS before receiving ones. for desc in send_desc_lst { desc_slice[crtl_desc_iter] = if desc_lst_len > 1 { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::NEXT, - (crtl_desc_iter + 1) as u16, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::NEXT, + next: ((crtl_desc_iter + 1) as u16).into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::empty(), - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::empty(), + next: 0.into(), + } }; desc_lst_len -= 1; @@ -639,19 +643,23 @@ impl VirtqPrivate for SplitVq { for desc in recv_desc_lst { desc_slice[crtl_desc_iter] = if desc_lst_len > 1 { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE | virtq::DescF::NEXT, - (crtl_desc_iter + 1) as u16, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE | virtq::DescF::NEXT, + next: ((crtl_desc_iter + 1) as u16).into(), + } } else { - Descriptor::new( - paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)).into(), - desc.len as u32, - virtq::DescF::WRITE, - 0, - ) + virtq::Desc { + addr: paging::virt_to_phys(VirtAddr::from(desc.ptr as u64)) + .as_u64() + .into(), + len: (desc.len as u32).into(), + flags: virtq::DescF::WRITE, + next: 0.into(), + } }; desc_lst_len -= 1; From 74a783aa027aabaf800d2a1271bda690883a6168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 16:58:12 +0200 Subject: [PATCH 06/10] feat(virtio-spec): add `virtq::UsedElem` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/virtq.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/virtio-spec/src/virtq.rs b/virtio-spec/src/virtq.rs index f05ff2209f..b21d90bf90 100644 --- a/virtio-spec/src/virtq.rs +++ b/virtio-spec/src/virtq.rs @@ -43,3 +43,18 @@ endian_bitflags! { const USED = 1 << 15; } } + +/// Used Ring Entry +#[doc(alias = "virtq_used_elem")] +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct UsedElem { + /// Index of start of used descriptor chain. + /// + /// le32 is used here for ids for padding reasons. + pub id: le32, + + /// The number of bytes written into the device writable portion of + /// the buffer described by the descriptor chain. + pub len: le32, +} From 70e666072e8ad01b024d2e8a94f7e61bb42c2027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 16:58:50 +0200 Subject: [PATCH 07/10] refactor(virtqueue/split): migrate `UsedElem` to virtio-spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/virtqueue/split.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index fac4f88fc3..09bc4b99e9 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -11,7 +11,7 @@ use core::mem::{size_of, MaybeUninit}; use core::ptr::{self, NonNull}; use virtio::pci::NotificationData; -use virtio::{le16, le32, virtq}; +use virtio::{le16, virtq}; use volatile::access::ReadOnly; use volatile::{map_field, VolatilePtr, VolatileRef}; @@ -71,13 +71,17 @@ type UsedRing = GenericRing<[u8]>; impl UsedRing { fn ring_ptr( volatile_self: VolatilePtr<'_, Self, A>, - ) -> VolatilePtr<'_, [UsedElem], A> { + ) -> VolatilePtr<'_, [virtq::UsedElem], A> { let ring_and_event_ptr = map_field!(volatile_self.ring_and_event); - let ring_len = (ring_and_event_ptr.len() - size_of::()) / size_of::(); + let ring_len = + (ring_and_event_ptr.len() - size_of::()) / size_of::(); unsafe { ring_and_event_ptr.map(|ring_and_event_ptr| { - NonNull::slice_from_raw_parts(ring_and_event_ptr.cast::(), ring_len) + NonNull::slice_from_raw_parts( + ring_and_event_ptr.cast::(), + ring_len, + ) }) } } @@ -95,13 +99,6 @@ impl UsedRing { } } -#[repr(C)] -#[derive(Copy, Clone)] -struct UsedElem { - id: le32, - len: le32, -} - struct DescrRing { read_idx: u16, token_ring: Box<[Option>]>, @@ -427,7 +424,7 @@ impl Virtq for SplitVq { }; let used_ring_cell = { - let ring_and_event_layout = Layout::array::(size.into()) + let ring_and_event_layout = Layout::array::(size.into()) .unwrap() .extend(Layout::new::()) // for event .unwrap() From a9ef02b3e549c4554330855aefa587bfee130988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 22:21:31 +0200 Subject: [PATCH 08/10] feat(virtio-spec): add `pvirtq::EventSuppress` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- virtio-spec/src/lib.rs | 41 ++++++++++++++++++++++++++++++++++++++- virtio-spec/src/pvirtq.rs | 36 +++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/virtio-spec/src/lib.rs b/virtio-spec/src/lib.rs index 554cdca63c..eb1040cbe1 100644 --- a/virtio-spec/src/lib.rs +++ b/virtio-spec/src/lib.rs @@ -18,7 +18,7 @@ pub mod pvirtq; pub mod virtq; pub use endian_num::{be128, be16, be32, be64, le128, le16, le32, le64}; -use num_enum::{FromPrimitive, IntoPrimitive}; +use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive}; pub use self::features::{FeatureBits, F}; @@ -201,3 +201,42 @@ pub enum Id { #[num_enum(catch_all)] Unknown(u8), } + +/// Descriptor Ring Change Event Flags +#[doc(alias = "RING_EVENT_FLAGS")] +#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq, Clone, Copy, Debug)] +#[non_exhaustive] +#[repr(u8)] +pub enum RingEventFlags { + /// Enable events + #[doc(alias = "RING_EVENT_FLAGS_ENABLE")] + Enable = 0x0, + + /// Disable events + #[doc(alias = "RING_EVENT_FLAGS_DISABLE")] + Disable = 0x1, + + /// Enable events for a specific descriptor + /// (as specified by Descriptor Ring Change Event Offset/Wrap Counter). + /// Only valid if VIRTIO_F_EVENT_IDX has been negotiated. + #[doc(alias = "RING_EVENT_FLAGS_DESC")] + Desc = 0x2, + + Reserved = 0x3, +} + +impl RingEventFlags { + const fn from_bits(bits: u8) -> Self { + match bits { + 0x0 => Self::Enable, + 0x1 => Self::Disable, + 0x2 => Self::Desc, + 0x3 => Self::Reserved, + _ => unreachable!(), + } + } + + const fn into_bits(self) -> u8 { + self as u8 + } +} diff --git a/virtio-spec/src/pvirtq.rs b/virtio-spec/src/pvirtq.rs index 07525e3d90..e03685a49b 100644 --- a/virtio-spec/src/pvirtq.rs +++ b/virtio-spec/src/pvirtq.rs @@ -1,6 +1,8 @@ +/// Packed virtqueue definitions +use bitfield_struct::bitfield; use endian_num::{le16, le32, le64}; -use crate::virtq; +use crate::{virtq, RingEventFlags}; /// Packed Virtqueue Descriptor #[doc(alias = "pvirtq_desc")] @@ -18,3 +20,35 @@ pub struct Desc { /// The flags depending on descriptor type. pub flags: virtq::DescF, } + +/// Event Suppression Descriptor +#[doc(alias = "pvirtq_event_suppress")] +#[repr(C)] +pub struct EventSuppress { + /// If desc_event_flags set to RING_EVENT_FLAGS_DESC + pub desc: EventSuppressDesc, + pub flags: EventSuppressFlags, +} + +/// Event Suppression Flags +#[bitfield(u16, repr = le16, from = le16::from_ne, into = le16::to_ne)] +pub struct EventSuppressDesc { + /// Descriptor Ring Change Event Offset + #[bits(15)] + pub desc_event_off: u16, + + /// Descriptor Ring Change Event Wrap Counter + #[bits(1)] + pub desc_event_wrap: u8, +} + +#[bitfield(u16, repr = le16, from = le16::from_ne, into = le16::to_ne)] +pub struct EventSuppressFlags { + /// Descriptor Ring Change Event Flags + #[bits(2)] + pub desc_event_flags: RingEventFlags, + + /// Reserved, set to 0 + #[bits(14)] + pub reserved: u16, +} From c6de1c59fa9b16a7eb38a06da58614397ccc0a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 22:22:14 +0200 Subject: [PATCH 09/10] refactor(virtqueue/packed): migrate `EventSuppr` to virtio-spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/virtqueue/packed.rs | 71 +++++++------------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index 76c29560eb..71baf9d85c 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -12,7 +12,8 @@ use core::{ops, ptr}; use align_address::Align; use virtio::pci::NotificationData; -use virtio::{pvirtq, virtq}; +use virtio::pvirtq::{EventSuppressDesc, EventSuppressFlags}; +use virtio::{pvirtq, virtq, RingEventFlags}; #[cfg(not(feature = "pci"))] use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl}; @@ -792,38 +793,6 @@ impl<'a> WriteCtrl<'a> { } } -/// Driver and device event suppression struct used in packed virtqueues. -/// -/// Structure layout see Virtio specification v1.1. - 2.7.14 -/// Alignment see Virtio specification v1.1. - 2.7.10.1 -/// -// /* Enable events */ -// #define RING_EVENT_FLAGS_ENABLE 0x0 -// /* Disable events */ -// #define RING_EVENT_FLAGS_DISABLE 0x1 -// /* -// * Enable events for a specific descriptor -// * (as specified by Descriptor Ring Change Event Offset/Wrap Counter). * Only valid if VIRTIO_F_RING_EVENT_IDX has been negotiated. -// */ -// #define RING_EVENT_FLAGS_DESC 0x2 -// /* The value 0x3 is reserved */ -// -// struct pvirtq_event_suppress { -// le16 { -// desc_event_off : 15; /* Descriptor Ring Change Event Offset */ -// desc_event_wrap : 1; /* Descriptor Ring Change Event Wrap Counter */ -// } desc; /* If desc_event_flags set to RING_EVENT_FLAGS_DESC */ -> For a single descriptor notification settings -// le16 { -// desc_event_flags : 2, /* Descriptor Ring Change Event Flags */ -> General notification on/off -// reserved : 14; /* Reserved, set to 0 */ -// } flags; -// }; -#[repr(C, align(4))] -struct EventSuppr { - event: u16, - flags: u16, -} - /// A newtype in order to implement the correct functionality upon /// the `EventSuppr` structure for driver notifications settings. /// The Driver Event Suppression structure is read-only by the device @@ -832,7 +801,7 @@ struct DrvNotif { /// Indicates if VIRTIO_F_RING_EVENT_IDX has been negotiated f_notif_idx: bool, /// Actual structure to read from, if device wants notifs - raw: &'static mut EventSuppr, + raw: &'static mut pvirtq::EventSuppress, } /// A newtype in order to implement the correct functionality upon @@ -843,35 +812,30 @@ struct DevNotif { /// Indicates if VIRTIO_F_RING_EVENT_IDX has been negotiated f_notif_idx: bool, /// Actual structure to read from, if device wants notifs - raw: &'static mut EventSuppr, -} - -impl EventSuppr { - /// Returns a zero initialized EventSuppr structure - fn new() -> Self { - EventSuppr { event: 0, flags: 0 } - } + raw: &'static mut pvirtq::EventSuppress, } impl DrvNotif { /// Enables notifications by unsetting the LSB. /// See Virito specification v1.1. - 2.7.10 fn enable_notif(&mut self) { - self.raw.flags = 0; + self.raw.flags = EventSuppressFlags::new().with_desc_event_flags(RingEventFlags::Enable); } /// Disables notifications by setting the LSB. /// See Virtio specification v1.1. - 2.7.10 fn disable_notif(&mut self) { - self.raw.flags = 1; + self.raw.flags = EventSuppressFlags::new().with_desc_event_flags(RingEventFlags::Disable); } /// Enables a notification by the device for a specific descriptor. fn enable_specific(&mut self, idx: RingIdx) { // Check if VIRTIO_F_RING_EVENT_IDX has been negotiated if self.f_notif_idx { - self.raw.flags = 2; - self.raw.event = idx.off & !(1 << 15) | (idx.wrap as u16) << 15; + self.raw.flags = EventSuppressFlags::new().with_desc_event_flags(RingEventFlags::Desc); + self.raw.desc = EventSuppressDesc::new() + .with_desc_event_off(idx.off) + .with_desc_event_wrap(idx.wrap); } } } @@ -885,7 +849,7 @@ impl DevNotif { /// Reads notification bit (i.e. LSB) and returns value. /// If notifications are enabled returns true, else false. fn is_notif(&self) -> bool { - self.raw.flags & 0b11 == 0 + self.raw.flags.desc_event_flags() == RingEventFlags::Enable } fn notif_specific(&self) -> Option { @@ -893,12 +857,12 @@ impl DevNotif { return None; } - if self.raw.flags & 0b11 != 2 { + if self.raw.flags.desc_event_flags() != RingEventFlags::Desc { return None; } - let off = self.raw.event & !(1 << 15); - let wrap = (self.raw.event >> 15) as u8; + let off = self.raw.desc.desc_event_off(); + let wrap = self.raw.desc.desc_event_wrap(); Some(RingIdx { off, wrap }) } @@ -1067,7 +1031,8 @@ impl Virtq for PackedVq { let descr_ring = RefCell::new(DescriptorRing::new(vq_size)); // Allocate heap memory via a vec, leak and cast - let _mem_len = core::mem::size_of::().align_up(BasePageSize::SIZE as usize); + let _mem_len = + core::mem::size_of::().align_up(BasePageSize::SIZE as usize); let drv_event_ptr = ptr::with_exposed_provenance_mut(crate::mm::allocate(_mem_len, true).0 as usize); @@ -1082,9 +1047,9 @@ impl Virtq for PackedVq { vq_handler.set_drv_ctrl_addr(paging::virt_to_phys(VirtAddr::from(drv_event_ptr as u64))); vq_handler.set_dev_ctrl_addr(paging::virt_to_phys(VirtAddr::from(dev_event_ptr as u64))); - let drv_event: &'static mut EventSuppr = unsafe { &mut *(drv_event_ptr) }; + let drv_event: &'static mut pvirtq::EventSuppress = unsafe { &mut *(drv_event_ptr) }; - let dev_event: &'static mut EventSuppr = unsafe { &mut *(dev_event_ptr) }; + let dev_event: &'static mut pvirtq::EventSuppress = unsafe { &mut *(dev_event_ptr) }; let drv_event = RefCell::new(DrvNotif { f_notif_idx: false, From 2f5c7340be264ca26a332ca75a17e3db8560e7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 12 Jun 2024 22:48:44 +0200 Subject: [PATCH 10/10] refactor(virtqueue): migrate `Descriptor` to virtio-spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/virtqueue/mod.rs | 50 ++++++++++++----------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/src/drivers/virtio/virtqueue/mod.rs b/src/drivers/virtio/virtqueue/mod.rs index e80e198450..e06da5ef19 100644 --- a/src/drivers/virtio/virtqueue/mod.rs +++ b/src/drivers/virtio/virtqueue/mod.rs @@ -23,6 +23,7 @@ use core::ptr; use align_address::Align; use async_channel::TryRecvError; +use virtio::{le32, virtq}; use zerocopy::AsBytes; use self::error::{BufferError, VirtqError}; @@ -91,15 +92,6 @@ impl From 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>; // Public interface of Virtq @@ -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::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; @@ -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::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; @@ -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::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; } @@ -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::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; } @@ -1399,9 +1391,9 @@ impl BufferToken { return Err(VirtqError::General); } else { let ind_desc_lst = unsafe { - let size = core::mem::size_of::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; } @@ -1474,9 +1466,9 @@ impl BufferToken { return Err(VirtqError::General); } else { let ind_desc_lst = unsafe { - let size = core::mem::size_of::(); + let size = core::mem::size_of::(); core::slice::from_raw_parts_mut( - ctrl_desc.ptr as *mut Descriptor, + ctrl_desc.ptr as *mut virtq::Desc, ctrl_desc.len / size, ) }; @@ -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; }