Skip to content

Commit

Permalink
virtio: use endianness-specified numbers from virtio-def
Browse files Browse the repository at this point in the history
Endianness-specified numbers from zerocopy, as opposed to the ones from virtio-def, do not guarantee appropriate alignment.
  • Loading branch information
cagatay-y committed May 2, 2024
1 parent 5c3e05f commit 880bf76
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ shell = ["simple-shell"]

[dependencies]
hermit-macro = { path = "hermit-macro" }
virtio-def = { path = "virtio-def" }
virtio-def = { path = "virtio-def", features = ["zerocopy"] }
ahash = { version = "0.8", default-features = false }
align-address = "0.1"
bit_field = "0.10"
Expand Down
41 changes: 21 additions & 20 deletions src/drivers/virtio/virtqueue/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use core::cell::RefCell;
use core::mem::{size_of, MaybeUninit};
use core::ptr;

use zerocopy::{little_endian, FromBytes, FromZeroes};
use virtio_def::num::{le16, le32, le64};
use zerocopy::{FromBytes, FromZeroes};

#[cfg(not(feature = "pci"))]
use super::super::transport::mmio::{ComCfg, NotifCfg, NotifCtrl};
Expand All @@ -29,10 +30,10 @@ use crate::mm::device_alloc::DeviceAlloc;
#[repr(C)]
#[derive(Copy, Clone)]
struct Descriptor {
address: little_endian::U64,
len: little_endian::U32,
flags: little_endian::U16,
next: little_endian::U16,
address: le64,
len: le32,
flags: le16,
next: le16,
}

impl Descriptor {
Expand All @@ -51,8 +52,8 @@ impl Descriptor {
// only need to be extended with the dynamic portion.
#[repr(C)]
struct GenericRing<T: ?Sized> {
flags: little_endian::U16,
index: little_endian::U16,
flags: le16,
index: le16,

// Rust does not allow a field other than the last one to be unsized.
// Unfortunately, this is not the case with the layout in the specification.
Expand All @@ -63,28 +64,28 @@ struct GenericRing<T: ?Sized> {

const RING_AND_EVENT_ERROR: &str = "ring_and_event should have at least enough elements for the event. It seems to be allocated incorrectly.";

type AvailRing = GenericRing<[MaybeUninit<little_endian::U16>]>;
type AvailRing = GenericRing<[MaybeUninit<le16>]>;

impl AvailRing {
fn ring_ref(&self) -> &[MaybeUninit<little_endian::U16>] {
fn ring_ref(&self) -> &[MaybeUninit<le16>] {
self.ring_and_event
.split_last()
.expect(RING_AND_EVENT_ERROR)
.1
}

fn ring_mut(&mut self) -> &mut [MaybeUninit<little_endian::U16>] {
fn ring_mut(&mut self) -> &mut [MaybeUninit<le16>] {
self.ring_and_event
.split_last_mut()
.expect(RING_AND_EVENT_ERROR)
.1
}

fn event_ref(&self) -> &MaybeUninit<little_endian::U16> {
fn event_ref(&self) -> &MaybeUninit<le16> {
self.ring_and_event.last().expect(RING_AND_EVENT_ERROR)
}

fn event_mut(&mut self) -> &MaybeUninit<little_endian::U16> {
fn event_mut(&mut self) -> &MaybeUninit<le16> {
self.ring_and_event.last_mut().expect(RING_AND_EVENT_ERROR)
}
}
Expand All @@ -98,21 +99,21 @@ impl UsedRing {
fn ring_ref(&self) -> &[UsedElem] {
// The last two bytes belong to the event field
UsedElem::slice_from(
&self.ring_and_event[..(self.ring_and_event.len() - size_of::<little_endian::U16>())],
&self.ring_and_event[..(self.ring_and_event.len() - size_of::<le16>())],
)
.expect(RING_AND_EVENT_ERROR)
}

fn event_ref(&self) -> &little_endian::U16 {
little_endian::U16::ref_from_suffix(&self.ring_and_event).expect(RING_AND_EVENT_ERROR)
fn event_ref(&self) -> &le16 {
le16::ref_from_suffix(&self.ring_and_event).expect(RING_AND_EVENT_ERROR)
}
}

#[repr(C)]
#[derive(Copy, Clone, FromZeroes, FromBytes)]
struct UsedElem {
id: little_endian::U32,
len: little_endian::U32,
id: le32,
len: le32,
}

struct DescrRing {
Expand Down Expand Up @@ -283,7 +284,7 @@ impl DescrRing {
}

fn dev_is_notif(&self) -> bool {
self.used_ring.flags & 1.into() == little_endian::U16::new(0)
self.used_ring.flags.get() & 1 == 0
}
}

Expand Down Expand Up @@ -381,7 +382,7 @@ impl Virtq for SplitVq {
let allocation = ALLOCATOR
.allocate(
Layout::new::<GenericRing<()>>() // flags
.extend(Layout::array::<little_endian::U16>(ring_and_event_len).unwrap()) // +1 for event
.extend(Layout::array::<le16>(ring_and_event_len).unwrap()) // +1 for event
.unwrap()
.0
.pad_to_align(),
Expand All @@ -399,7 +400,7 @@ impl Virtq for SplitVq {
let used_ring = {
let ring_and_event_layout = Layout::array::<UsedElem>(size.into())
.unwrap()
.extend(Layout::new::<little_endian::U16>()) // for event
.extend(Layout::new::<le16>()) // for event
.unwrap()
.0;
let allocation = ALLOCATOR
Expand Down

0 comments on commit 880bf76

Please sign in to comment.