From 880bf76ac24b3d97bf29d5303c5e013d8f1364e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Fatay=20Yi=C4=9Fit=20=C5=9Eahin?= Date: Thu, 2 May 2024 19:28:26 +0200 Subject: [PATCH] virtio: use endianness-specified numbers from virtio-def Endianness-specified numbers from zerocopy, as opposed to the ones from virtio-def, do not guarantee appropriate alignment. --- Cargo.toml | 2 +- src/drivers/virtio/virtqueue/split.rs | 41 ++++++++++++++------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index baa53654ef..585daec9ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index a3183d4a24..27ce815637 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -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}; @@ -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 { @@ -51,8 +52,8 @@ impl Descriptor { // only need to be extended with the dynamic portion. #[repr(C)] struct GenericRing { - 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. @@ -63,28 +64,28 @@ struct GenericRing { 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]>; +type AvailRing = GenericRing<[MaybeUninit]>; impl AvailRing { - fn ring_ref(&self) -> &[MaybeUninit] { + fn ring_ref(&self) -> &[MaybeUninit] { self.ring_and_event .split_last() .expect(RING_AND_EVENT_ERROR) .1 } - fn ring_mut(&mut self) -> &mut [MaybeUninit] { + fn ring_mut(&mut self) -> &mut [MaybeUninit] { self.ring_and_event .split_last_mut() .expect(RING_AND_EVENT_ERROR) .1 } - fn event_ref(&self) -> &MaybeUninit { + fn event_ref(&self) -> &MaybeUninit { self.ring_and_event.last().expect(RING_AND_EVENT_ERROR) } - fn event_mut(&mut self) -> &MaybeUninit { + fn event_mut(&mut self) -> &MaybeUninit { self.ring_and_event.last_mut().expect(RING_AND_EVENT_ERROR) } } @@ -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::())], + &self.ring_and_event[..(self.ring_and_event.len() - size_of::())], ) .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 { @@ -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 } } @@ -381,7 +382,7 @@ impl Virtq for SplitVq { let allocation = ALLOCATOR .allocate( Layout::new::>() // flags - .extend(Layout::array::(ring_and_event_len).unwrap()) // +1 for event + .extend(Layout::array::(ring_and_event_len).unwrap()) // +1 for event .unwrap() .0 .pad_to_align(), @@ -399,7 +400,7 @@ impl Virtq for SplitVq { let used_ring = { let ring_and_event_layout = Layout::array::(size.into()) .unwrap() - .extend(Layout::new::()) // for event + .extend(Layout::new::()) // for event .unwrap() .0; let allocation = ALLOCATOR