From 2d5c85c52ee99c128efd2af9bd313cfd7d8fe107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Mon, 22 Apr 2024 14:19:42 +0200 Subject: [PATCH] refactor(virtio/pci): move `ComCfgRaw::map` to `PciCap::map_common_cfg` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/drivers/virtio/transport/pci.rs | 66 ++++++++++++++--------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index bdd3268f4e..48c5a0466b 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -219,6 +219,36 @@ impl PciCap { pub fn dev_id(&self) -> u16 { self.origin.dev_id } + + /// Returns a reference to the actual structure inside the PCI devices memory space. + fn map_common_cfg(&self) -> Option> { + if self.bar.length < u64::from(self.length + self.offset) { + error!("Common config of with id {} of device {:x}, does not fit into memory specified by bar {:x}!", + self.id, + self.origin.dev_id, + self.bar.index + ); + return None; + } + + // Using "as u32" is safe here as ComCfgRaw has a defined size smaller 2^31-1 + // Drivers MAY do this check. See Virtio specification v1.1. - 4.1.4.1 + if self.length < MemLen::from(mem::size_of::() * 8) { + error!("Common config of with id {}, does not represent actual structure specified by the standard!", self.id); + return None; + } + + let virt_addr_raw = self.bar.mem_addr + self.offset; + let ptr = NonNull::new(ptr::with_exposed_provenance_mut::( + virt_addr_raw.into(), + )) + .unwrap(); + + // Create mutable reference to the PCI structure in PCI memory + let com_cfg_raw = unsafe { VolatileRef::new(ptr) }; + + Some(com_cfg_raw) + } } /// Virtio's PCI capabilities structure. @@ -630,40 +660,6 @@ struct ComCfgRaw { queue_device: u64, // read-write } -// Common configuration raw does NOT provide a PUBLIC -// interface. -impl ComCfgRaw { - /// Returns a reference to the actual structure inside the PCI devices memory space. - fn map(cap: &PciCap) -> Option> { - if cap.bar.length < u64::from(cap.length + cap.offset) { - error!("Common config of with id {} of device {:x}, does not fit into memory specified by bar {:x}!", - cap.id, - cap.origin.dev_id, - cap.bar.index - ); - return None; - } - - // Using "as u32" is safe here as ComCfgRaw has a defined size smaller 2^31-1 - // Drivers MAY do this check. See Virtio specification v1.1. - 4.1.4.1 - if cap.length < MemLen::from(mem::size_of::() * 8) { - error!("Common config of with id {}, does not represent actual structure specified by the standard!", cap.id); - return None; - } - - let virt_addr_raw = cap.bar.mem_addr + cap.offset; - let ptr = NonNull::new(ptr::with_exposed_provenance_mut::( - virt_addr_raw.into(), - )) - .unwrap(); - - // Create mutable reference to the PCI structure in PCI memory - let com_cfg_raw = unsafe { VolatileRef::new(ptr) }; - - Some(com_cfg_raw) - } -} - /// Notification Structure to handle virtqueue notification settings. /// See Virtio specification v1.1 - 4.1.4.4 pub struct NotifCfg { @@ -1222,7 +1218,7 @@ pub(crate) fn map_caps(device: &PciDevice) -> Result match ComCfgRaw::map(&pci_cap) { + CfgType::VIRTIO_PCI_CAP_COMMON_CFG => match pci_cap.map_common_cfg() { Some(cap) => caps.add_cfg_common(ComCfg::new(cap, pci_cap.id)), None => error!( "Common config capability with id {}, of device {:x}, could not be mapped!",