diff --git a/src/drivers/virtio/transport/mmio.rs b/src/drivers/virtio/transport/mmio.rs index 23f88f3647..1bad406a68 100644 --- a/src/drivers/virtio/transport/mmio.rs +++ b/src/drivers/virtio/transport/mmio.rs @@ -10,7 +10,7 @@ use virtio_spec::mmio::{ DeviceRegisterVolatileFieldAccess, DeviceRegisterVolatileWideFieldAccess, DeviceRegisters, InterruptStatus, }; -use virtio_spec::DeviceStatus; +use virtio_spec::{le32, DeviceStatus}; use volatile::VolatileRef; #[cfg(any(feature = "tcp", feature = "udp"))] @@ -69,11 +69,6 @@ impl<'a> VqCfgHandler<'a> { self.raw.as_mut_ptr().queue_device().write(addr.0.into()); } - pub fn notif_off(&mut self) -> u16 { - // we don't need an offset - 0 - } - pub fn enable_queue(&mut self) { self.select_queue(); @@ -267,31 +262,18 @@ impl ComCfg { /// See Virtio specification v1.1 - 4.1.4.4 pub struct NotifCfg { /// Start addr, from where the notification addresses for the virtqueues are computed - queue_notify: *mut u32, + queue_notify: *mut le32, } impl NotifCfg { pub fn new(mut registers: VolatileRef<'_, DeviceRegisters>) -> Self { - let raw = registers - .as_mut_ptr() - .queue_notify() - .as_raw_ptr() - .as_ptr() - .cast(); + let raw = registers.as_mut_ptr().queue_notify().as_raw_ptr().as_ptr(); NotifCfg { queue_notify: raw } } - /// Returns base address of notification area as an usize - pub fn base(&self) -> usize { - self.queue_notify as usize - } - - /// Returns the multiplier, needed in order to calculate the - /// notification address for a specific queue. - pub fn multiplier(&self) -> u32 { - // we don't need a multiplier - 0 + pub fn notification_location(&self, _vq_cfg_handler: &mut VqCfgHandler<'_>) -> *mut le32 { + self.queue_notify } } @@ -301,16 +283,16 @@ pub struct NotifCtrl { /// Indicates if VIRTIO_F_NOTIFICATION_DATA has been negotiated f_notif_data: bool, /// Where to write notification - notif_addr: *mut u32, + notif_addr: *mut le32, } impl NotifCtrl { /// Returns a new controller. By default MSI-X capabilities and VIRTIO_F_NOTIFICATION_DATA /// are disabled. - pub fn new(notif_addr: *mut usize) -> Self { + pub fn new(notif_addr: *mut le32) -> Self { NotifCtrl { f_notif_data: false, - notif_addr: notif_addr as *mut u32, + notif_addr, } } diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index 27ae0ec26b..4291fc85eb 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -13,7 +13,7 @@ use virtio_spec::pci::{ CommonCfg, CommonCfgVolatileFieldAccess, CommonCfgVolatileWideFieldAccess, IsrStatus as IsrStatusRaw, }; -use virtio_spec::DeviceStatus; +use virtio_spec::{le32, DeviceStatus}; use volatile::VolatileRef; #[cfg(all(not(feature = "rtl8139"), any(feature = "tcp", feature = "udp")))] @@ -617,15 +617,10 @@ impl NotifCfg { }) } - /// Returns base address of notification area as an usize - pub fn base(&self) -> usize { - usize::from(self.base_addr) - } - - /// Returns the multiplier, needed in order to calculate the - /// notification address for a specific queue. - pub fn multiplier(&self) -> u32 { - self.notify_off_multiplier + pub fn notification_location(&self, vq_cfg_handler: &mut VqCfgHandler<'_>) -> *mut le32 { + let addend = u32::from(vq_cfg_handler.notif_off()) * self.notify_off_multiplier; + let addr = usize::from(self.base_addr) + usize::try_from(addend).unwrap(); + ptr::with_exposed_provenance_mut(addr) } } @@ -635,13 +630,13 @@ pub struct NotifCtrl { /// Indicates if VIRTIO_F_NOTIFICATION_DATA has been negotiated f_notif_data: bool, /// Where to write notification - notif_addr: *mut usize, + notif_addr: *mut le32, } impl NotifCtrl { /// Returns a new controller. By default MSI-X capabilities and VIRTIO_F_NOTIFICATION_DATA /// are disabled. - pub fn new(notif_addr: *mut usize) -> Self { + pub fn new(notif_addr: *mut le32) -> Self { NotifCtrl { f_notif_data: false, notif_addr, diff --git a/src/drivers/virtio/virtqueue/packed.rs b/src/drivers/virtio/virtqueue/packed.rs index 85b3659fec..f2e0dd0882 100644 --- a/src/drivers/virtio/virtqueue/packed.rs +++ b/src/drivers/virtio/virtqueue/packed.rs @@ -1131,11 +1131,7 @@ impl Virtq for PackedVq { raw: dev_event, }; - let mut notif_ctrl = NotifCtrl::new(ptr::with_exposed_provenance_mut( - notif_cfg.base() - + usize::from(vq_handler.notif_off()) - * usize::try_from(notif_cfg.multiplier()).unwrap(), - )); + let mut notif_ctrl = NotifCtrl::new(notif_cfg.notification_location(&mut vq_handler)); if features.contains(virtio_spec::F::NOTIFICATION_DATA) { notif_ctrl.enable_notif_data(); diff --git a/src/drivers/virtio/virtqueue/split.rs b/src/drivers/virtio/virtqueue/split.rs index 3119053d52..a379b8612d 100644 --- a/src/drivers/virtio/virtqueue/split.rs +++ b/src/drivers/virtio/virtqueue/split.rs @@ -494,11 +494,7 @@ impl Virtq for SplitVq { used_ring_cell, }; - let mut notif_ctrl = NotifCtrl::new(ptr::with_exposed_provenance_mut( - notif_cfg.base() - + usize::from(vq_handler.notif_off()) - * usize::try_from(notif_cfg.multiplier()).unwrap(), - )); + let mut notif_ctrl = NotifCtrl::new(notif_cfg.notification_location(&mut vq_handler)); if features.contains(virtio_spec::F::NOTIFICATION_DATA) { notif_ctrl.enable_notif_data();