diff --git a/src/lib.rs b/src/lib.rs index c7b22c81d..296d0103f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,8 +27,6 @@ pub mod params; #[cfg(target_os = "linux")] pub mod shared_queue; mod vcpu; -pub mod virtio; -pub mod virtqueue; pub mod vm; pub use arch::*; @@ -37,3 +35,4 @@ pub type HypervisorResult = Result; pub mod net; mod pci; +mod virtio; diff --git a/src/linux/x86_64/kvm_cpu.rs b/src/linux/x86_64/kvm_cpu.rs index b74c87f0a..526c9eac7 100644 --- a/src/linux/x86_64/kvm_cpu.rs +++ b/src/linux/x86_64/kvm_cpu.rs @@ -11,12 +11,12 @@ use crate::{ consts::*, hypercall, linux::KVM, - net::virtio::{ + pci::PciDevice, + vcpu::{VcpuStopReason, VirtualCPU}, + virtio::{ capabilities::{ComCfg, IsrStatus, NetDevCfg}, pci::{ConfigAddress, MEM_NOTIFY, MEM_NOTIFY_1}, }, - vcpu::{VcpuStopReason, VirtualCPU}, - virtio::*, vm::UhyveVm, HypervisorError, HypervisorResult, }; diff --git a/src/net/mod.rs b/src/net/mod.rs index ab67476ff..73d6d91c9 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -1,6 +1,4 @@ -pub use crate::{ - consts::{UHYVE_NET_MTU, UHYVE_QUEUE_SIZE}, -}; +pub use crate::consts::{UHYVE_NET_MTU, UHYVE_QUEUE_SIZE}; pub const BROADCAST_MAC_ADDR: [u8; 6] = [0xff; 6]; pub const PCI_ETHERNET_CLASS_CODE: u8 = 0x2; @@ -15,5 +13,3 @@ pub const UHYVE_PCI_CLASS_INFO: [u8; 3] = [ ]; pub mod tap; - -pub mod virtio; diff --git a/src/net/virtio/config.rs b/src/net/virtio/config.rs deleted file mode 100644 index f26748f4c..000000000 --- a/src/net/virtio/config.rs +++ /dev/null @@ -1,72 +0,0 @@ -/// Virtio device status field. See section 2.1 virtio v1.2 -pub mod status { - /// Despite not being a valid virtio Flag, 0 represents an uninitialized or reset device. - pub const UNINITIALIZED: u8 = 0; - /// Indicates the guest has found the device and recognises it as valid. - pub const ACKNOWLEDGE: u8 = 1; - - /// Indicates the guest knows how to drive the device. - pub const DRIVER: u8 = 2; - - /// Indicates the driver is set up and ready to drive the device. - pub const DRIVER_OK: u8 = 4; - - /// indicates the driver has acknowledged the features it understands and negotiation is - /// complete. - pub const FEATURES_OK: u8 = 8; - - /// Indicates that the device has experienced an error from which it can’t recover. - pub const DEVICE_NEEDS_RESET: u8 = 64; - - /// Indicates that the PCI capabilities pointer points to a linked list at register address - /// 0x34. - /// - /// See: PCI-to-PCI bridge architechture, section 3.2.4.4 - pub const PCI_CAPABILITIES_LIST_ENABLE: u8 = 16; - - /// Failed to initialize. - pub const FAILED: u8 = 128; -} - -/// Virtio ISR status flags. See section 4.1.4.5 virtio v1.2 -pub mod interrupt { - /// Notify that the buffers/Virtqueues have been changed - pub const NOTIFY_USED_BUFFER: u8 = 1 << 0; - /// Notify that the device configuration has been changed. - /// - /// *Note: libhermit-rs does not support configuration changes at this time.* - pub const NOTIFY_CONFIGURUTION_CHANGED: u8 = 1 << 1; -} -/// Virtio Device IDs. -/// -/// The device is calculated by adding 0x1040 to the virtio device ID as in section 5, or have a -/// transitional device ID. -/// -/// See sections 4.1.2.1 and 5 virtio v1.2 -pub mod device_id { - const ROOT_DEVICE_ID: u16 = 0x1040; - pub const NET_DEVICE: u16 = ROOT_DEVICE_ID + 1; - const _BLOCK_DEVICE: u16 = ROOT_DEVICE_ID + 2; - const _CONSOLE_DEVICE: u16 = ROOT_DEVICE_ID + 3; - const _SOCKET_DEVICE: u16 = ROOT_DEVICE_ID + 19; - // const TRANSITIONAL_NETWORK_CARD: u32 = 0x1000; -} - -/// Virtio capability type IDs. See section 4.1.4 virtio v1.2 -pub mod cfg_type { - pub const INVALID_CFG: u8 = 0x00; - /// Common configuration - pub const COMMON_CFG: u8 = 0x01; - /// Notifications - pub const NOTIFY_CFG: u8 = 0x02; - /// ISR status - pub const ISR_CFG: u8 = 0x03; - /// Device-specific configuration - pub const DEVICE_CFG: u8 = 0x04; - /// PCI configuration access - pub const PCI_CFG: u8 = 0x05; - /// Shared memory region - const _SHARED_MEMORY_CFG: u8 = 0x08; - /// Vendor-specific data - pub const VENDOR_CFG: u8 = 0x09; -} diff --git a/src/pci.rs b/src/pci.rs index 9d0048805..d06cd11f8 100644 --- a/src/pci.rs +++ b/src/pci.rs @@ -3,16 +3,19 @@ use zerocopy::AsBytes; use crate::{ consts::GUEST_PAGE_SIZE, - net::{ - virtio::{DeviceStatus, VIRTIO_VENDOR_ID}, - PCI_ETHERNET_REVISION_ID, UHYVE_PCI_CLASS_INFO, - }, + net::{PCI_ETHERNET_REVISION_ID, UHYVE_PCI_CLASS_INFO}, + virtio::{DeviceStatus, VIRTIO_VENDOR_ID}, }; /// For now, use an address large enough to be outside of kvm_userspace, /// as IO/MMIO writes are otherwise dismissed. pub const IOBASE: u32 = 0xFE000000; +pub trait PciDevice { + fn handle_read(&self, address: u32, dest: &mut [u8]); + fn handle_write(&mut self, address: u32, src: &[u8]); +} + #[derive(Error, Debug)] pub enum PciError { #[error("Trying to write to read_only memory (PCI space address: {0:#p})")] diff --git a/src/net/virtio/capabilities.rs b/src/virtio/capabilities.rs similarity index 97% rename from src/net/virtio/capabilities.rs rename to src/virtio/capabilities.rs index cd8165c1c..1e08c7079 100644 --- a/src/net/virtio/capabilities.rs +++ b/src/virtio/capabilities.rs @@ -4,20 +4,18 @@ use bitflags::bitflags; use zerocopy::AsBytes; use crate::{ - virtqueue::VirtqueueNotification, - net::{ - virtio::pci::{ - get_offset, ConfigAddress, COMMON_CFG_START, DEVICE_CFG_START, ISR_CFG_START, - }, - BROADCAST_MAC_ADDR, UHYVE_NET_MTU, UHYVE_QUEUE_SIZE, - }, + net::{BROADCAST_MAC_ADDR, UHYVE_NET_MTU, UHYVE_QUEUE_SIZE}, pci::PciError, + virtio::{ + pci::{get_offset, ConfigAddress, COMMON_CFG_START, DEVICE_CFG_START, ISR_CFG_START}, + virtqueue::VirtqueueNotification, + }, }; /// Virtio capability type IDs. See section 4.1.4 virtio v1.2 #[derive(Debug, Clone, Copy, AsBytes, PartialEq, Eq)] #[repr(u8)] -#[allow(non_camel_case_types)] +#[allow(non_camel_case_types, dead_code)] pub enum CfgType { INVALID_CFG = 0x00, /// Common configuration @@ -134,7 +132,7 @@ bitflags! { } // TODO: Replace with virtio_bindings::Virtio_net_config? -/// Virtio device configuration layout. +/// Virtio device configuration layout. Virtio v1.2 Section 5.1.4 #[derive(Clone, Debug)] #[repr(C)] pub struct NetDevCfg { @@ -209,7 +207,6 @@ impl IsrStatus { /// See section 4.1.4.4.1 virtio v1.2 #[derive(AsBytes, Clone, Debug)] #[repr(C)] -// TODO: Rename Notif -> Notify pub struct NotifyCap { pub cap: PciCap, /// Combind with queue_notify_off to derive the Queue Notify address @@ -234,6 +231,7 @@ impl NotifyCap { _ => Err(PciError::InvalidAddress(address as u32)), } } + #[allow(dead_code)] pub fn write(&mut self, address: u8, _data: &[u8]) -> Result<(), PciError> { Err(PciError::ReadOnlyAccess(address as u32)) } @@ -259,6 +257,7 @@ impl Default for NotifyCap { /// All data should be treated as little-endian. #[derive(AsBytes, Clone, Copy, Debug)] #[repr(C)] +#[allow(dead_code)] pub struct ComCfg { /// **read-write**: The driver uses this to select device_feature. /// @@ -340,6 +339,7 @@ pub struct ComCfg { _padding: [u8; 4], } +#[allow(dead_code)] impl ComCfg { pub const DEVICE_FEATURE_SELECT: ConfigAddress = get_offset!(COMMON_CFG_START, Self, device_feature_select); diff --git a/src/net/virtio/mod.rs b/src/virtio/mod.rs similarity index 89% rename from src/net/virtio/mod.rs rename to src/virtio/mod.rs index 6c1ef7986..126fa0544 100644 --- a/src/net/virtio/mod.rs +++ b/src/virtio/mod.rs @@ -1,11 +1,9 @@ -pub mod capabilities; -pub mod pci; +//! Virtio Datastructures and constants. - -pub use virtio_bindings::{ - bindings::virtio_net::{VIRTIO_NET_F_MAC, VIRTIO_NET_F_MTU, VIRTIO_NET_F_STATUS}, - virtio_config::{VIRTIO_F_RING_RESET, VIRTIO_F_VERSION_1}, -}; +pub(crate) mod capabilities; +pub(crate) mod net; +pub(crate) mod pci; +pub(crate) mod virtqueue; pub mod features { use virtio_bindings::{ @@ -19,7 +17,6 @@ pub mod features { } use bitflags::bitflags; -pub use virtio_bindings::bindings::virtio_net::{VIRTIO_NET_HDR_GSO_NONE, VIRTIO_NET_S_LINK_UP}; use zerocopy::AsBytes; /// Virtio device status field. See section 2.1 virtio v1.2 diff --git a/src/virtio.rs b/src/virtio/net.rs similarity index 95% rename from src/virtio.rs rename to src/virtio/net.rs index 9beeba733..9da701af6 100644 --- a/src/virtio.rs +++ b/src/virtio/net.rs @@ -21,31 +21,23 @@ use vmm_sys_util::eventfd::EventFd; use crate::{ consts::{UHYVE_IRQ_NET, UHYVE_NET_MTU}, - net::{ - tap::Tap, - virtio::{ - capabilities::IsrStatus, - features::{UHYVE_NET_FEATURES_HIGH, UHYVE_NET_FEATURES_LOW}, - pci::{HeaderConf, MEM_NOTIFY, MEM_NOTIFY_1}, - DeviceStatus, IOBASE, NET_DEVICE_ID, - }, + net::tap::Tap, + pci::{MemoryBar64, PciDevice}, + virtio::{ + capabilities::IsrStatus, + features::{UHYVE_NET_FEATURES_HIGH, UHYVE_NET_FEATURES_LOW}, + pci::{HeaderConf, MEM_NOTIFY, MEM_NOTIFY_1}, + virtqueue::{self, QUEUE_LIMIT}, + DeviceStatus, IOBASE, NET_DEVICE_ID, }, - virtqueue::{self, QUEUE_LIMIT}, - pci::MemoryBar64, }; const VIRTIO_NET_HEADER_SZ: usize = mem::size_of::(); const RX_QUEUE: u16 = 0; const TX_QUEUE: u16 = 1; -pub const VIRTIO_PCI_MEM_BAR_PFN: u16 = 1 << 3; -use crate::net::virtio::capabilities::{FeatureSelector, NetDevStatus}; - -pub trait PciDevice { - fn handle_read(&self, address: u32, dest: &mut [u8]); - fn handle_write(&mut self, address: u32, src: &[u8]); -} +use crate::virtio::capabilities::{FeatureSelector, NetDevStatus}; /// Struct to manage uhyve's network device. pub struct VirtioNetPciDevice { @@ -495,22 +487,12 @@ impl VirtioNetPciDevice { impl PciDevice for VirtioNetPciDevice { fn handle_read(&self, address: u32, dest: &mut [u8]) { - // println!( - // "VirtioPCI: reading {} bytes from {address:#x}: {:?}", - // dest.len(), - // &self.config_space.slice[address as usize..(address as usize + dest.len())] - // ); if let Err(e) = self.header_caps.read(address, dest) { error!("PCI Read error: {e:?}"); } } fn handle_write(&mut self, address: u32, data: &[u8]) { - // println!( - // "VirtioPCI: writing {} bytes to {address:#x}: {:?}", - // data.len(), - // data - // ); if let Err(e) = self.header_caps.write(address, data) { error!("PCI Write error: {e:?}"); } diff --git a/src/net/virtio/pci.rs b/src/virtio/pci.rs similarity index 94% rename from src/net/virtio/pci.rs rename to src/virtio/pci.rs index 3f7189d45..6c76045d2 100644 --- a/src/net/virtio/pci.rs +++ b/src/virtio/pci.rs @@ -1,10 +1,10 @@ +//! Configuration Structures for Virtio PCI devices + use std::{mem::size_of, ops::Add}; -/// Configuration Structures for Virtio PCI devices use crate::{ - net::virtio::capabilities::*, pci::{PciError, PciType0ConfigSpaceHeader, IOBASE}, - virtqueue::VirtqueueNotification, + virtio::{capabilities::*, virtqueue::VirtqueueNotification}, }; pub const HDR_END: u8 = size_of::() as u8 - 1; @@ -40,18 +40,6 @@ pub const NOTIFY_REGION_END: u8 = pub const DEVICE_CFG_START: u8 = NOTIFY_REGION_END + 1; pub const DEVICE_CFG_END: u8 = DEVICE_CFG_START + size_of::() as u8 - 1; -pub const MAC_ADDRESS: ConfigAddress = - ConfigAddress::from_configuration_address(DEVICE_CAP_START as u32); - -/// Contains immutable offsets of uhyve's virtio configuration. -// pub mod offsets { -// use super::capabilities::{ -// ComCfg, IsrStatus, NetDevCfg, -// }; -// use crate::net::virtio::ConfigAddress; - -// mod offsets { - /// An address in the PCI configuration space. #[derive(Eq, PartialEq, Clone, Copy, Debug)] pub struct ConfigAddress(pub(crate) u32); diff --git a/src/virtqueue.rs b/src/virtio/virtqueue.rs similarity index 95% rename from src/virtqueue.rs rename to src/virtio/virtqueue.rs index a2021cb8e..8747d887e 100644 --- a/src/virtqueue.rs +++ b/src/virtio/virtqueue.rs @@ -1,3 +1,6 @@ +// TODO: replace with https://crates.io/crates/virtio-queue +#![allow(dead_code)] + use std::{ marker::PhantomData, mem, @@ -9,14 +12,10 @@ use uhyve_interface::GuestPhysAddr; use crate::consts::PAGE_SIZE; -pub const QUEUE_LIMIT: usize = 256; -pub const VIRTQ_DESC_F_AVAIL: u16 = 1 << 7; -pub const VIRTQ_DESC_F_USED: u16 = 1 << 15; +pub(crate) const QUEUE_LIMIT: usize = 256; use virtio_bindings::bindings::virtio_ring::VRING_AVAIL_F_NO_INTERRUPT; -pub use virtio_bindings::bindings::virtio_ring::{ - VRING_DESC_F_INDIRECT, VRING_DESC_F_NEXT, VRING_DESC_F_WRITE, -}; +pub use virtio_bindings::bindings::virtio_ring::VRING_DESC_F_WRITE; // A virtqueue notification as described in the Virtio standard v1.2 Sec. 2.9 & 4.1.5.2. #[repr(C)] diff --git a/src/vm.rs b/src/vm.rs index dfc93fccf..6da6b0180 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -26,7 +26,10 @@ use crate::arch::x86_64::{ }; #[cfg(all(target_arch = "x86_64", target_os = "linux"))] use crate::linux::x86_64::kvm_cpu::initialize_kvm; -use crate::{arch, consts::*, os::HypervisorError, params::Params, vcpu::VirtualCPU, virtio::*}; +use crate::{ + arch, consts::*, os::HypervisorError, params::Params, vcpu::VirtualCPU, + virtio::net::VirtioNetPciDevice, +}; pub type HypervisorResult = Result;