diff --git a/Cargo.lock b/Cargo.lock index 61a7e75..b84ca1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bao-virtio" @@ -164,9 +164,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linked-hash-map" @@ -203,9 +203,9 @@ checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -230,9 +230,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "seccompiler" @@ -245,24 +245,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -289,9 +289,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.58" +version = "2.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" dependencies = [ "proc-macro2", "quote", @@ -315,18 +315,18 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -386,6 +386,7 @@ dependencies = [ "vhost-user-frontend", "virtio-bindings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "virtio-blk", + "virtio-console", "virtio-device", "virtio-queue", "virtio-vsock", @@ -418,6 +419,16 @@ dependencies = [ "vmm-sys-util", ] +[[package]] +name = "virtio-console" +version = "0.1.0" +source = "git+https://github.com/joaopeixoto13/vm-virtio?branch=bao-hypervisor#eec91192f87f1107fa9b94524c352f5351747513" +dependencies = [ + "virtio-bindings 0.2.2 (git+https://github.com/joaopeixoto13/vm-virtio?branch=bao-hypervisor)", + "virtio-queue", + "vm-memory", +] + [[package]] name = "virtio-device" version = "0.1.0" @@ -507,11 +518,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys", ] [[package]] @@ -520,6 +531,79 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/src/virtio/Cargo.toml b/src/virtio/Cargo.toml index fbe056d..a6a5dac 100644 --- a/src/virtio/Cargo.toml +++ b/src/virtio/Cargo.toml @@ -18,6 +18,7 @@ vmm-sys-util = "0.12.1" virtio-device = { git = "https://github.com/joaopeixoto13/vm-virtio", branch = "bao-hypervisor" } virtio-blk = { git = "https://github.com/joaopeixoto13/vm-virtio", branch = "bao-hypervisor", features = ["backend-stdio"] } virtio-vsock = { git = "https://github.com/joaopeixoto13/vm-virtio", branch = "bao-hypervisor" } +virtio-console = { git = "https://github.com/joaopeixoto13/vm-virtio", branch = "bao-hypervisor" } vhost = { version = "0.10.0", features = ["vhost-user-frontend", "vhost-kern", "vhost-user-backend", "vhost-vsock", "vhost-net"] } vhost-user-frontend = { git = "https://github.com/joaopeixoto13/vhost", branch = "vhost-user-frontend" } vm-memory = { version = "0.14.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] } diff --git a/src/virtio/src/console/README.md b/src/virtio/src/console/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/virtio/src/console/mod.rs b/src/virtio/src/console/mod.rs new file mode 100644 index 0000000..d43f304 --- /dev/null +++ b/src/virtio/src/console/mod.rs @@ -0,0 +1 @@ +pub mod virtio; diff --git a/src/virtio/src/console/virtio/README.md b/src/virtio/src/console/virtio/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/virtio/src/console/virtio/console_handler.rs b/src/virtio/src/console/virtio/console_handler.rs new file mode 100644 index 0000000..090a195 --- /dev/null +++ b/src/virtio/src/console/virtio/console_handler.rs @@ -0,0 +1,118 @@ +use super::queue_handler::{INPUT_QUEUE_INDEX, OUTPUT_QUEUE_INDEX}; +use crate::device::SignalUsedQueue; +use std::io::Stdout; +use std::result; +use virtio_console::console::{Console, Error as ConsoleError}; +use virtio_queue::{Queue, QueueOwnedT, QueueT}; +use vm_memory::bitmap::AtomicBitmap; + +type GuestMemoryMmap = vm_memory::GuestMemoryMmap; + +pub struct ConsoleQueueHandler { + pub driver_notify: S, + pub mem: GuestMemoryMmap, + pub input_queue: Queue, + pub output_queue: Queue, + pub console: Console, +} + +impl ConsoleQueueHandler +where + S: SignalUsedQueue, +{ + /* + * Each port of virtio console device has one receive + * queue. One or more empty buffers are placed by the + * driver in the receive queue for incoming data. Here, + * we place the input data to these empty buffers. + */ + pub fn process_input_queue(&mut self) -> result::Result<(), Error> { + // To see why this is done in a loop, please look at the `Queue::enable_notification` + // comments in `virtio_queue`. + loop { + // Disable the notifications. + self.input_queue.disable_notification(&self.mem)?; + + // Process the queue. + while let Some(mut chain) = self.input_queue.iter(&self.mem.clone())?.next() { + let sent_bytes = self.console.process_receiveq_chain(&mut chain)?; + //println!("Sent bytes: {}", sent_bytes); + + if sent_bytes > 0 { + println!("process_input_queue bytes: {}", sent_bytes); + self.input_queue + .add_used(chain.memory(), chain.head_index(), sent_bytes)?; + + if self.input_queue.needs_notification(&self.mem)? { + self.driver_notify.signal_used_queue(INPUT_QUEUE_INDEX); + } + } + } + + // Enable the notifications. + if !self.input_queue.enable_notification(&self.mem)? { + break; + } + } + Ok(()) + } + + /* + * Each port of virtio console device has one transmit + * queue. For outgoing data, characters are placed in + * the transmit queue by the driver. Therefore, here + * we read data from the transmit queue and flush them + * to the referenced address. + */ + pub fn process_output_queue(&mut self) -> result::Result<(), Error> { + // To see why this is done in a loop, please look at the `Queue::enable_notification` + // comments in `virtio_queue`. + loop { + // Disable the notifications. + self.output_queue.disable_notification(&self.mem)?; + + // Process the queue. + while let Some(mut chain) = self.output_queue.iter(&self.mem.clone())?.next() { + self.console.process_transmitq_chain(&mut chain)?; + + self.output_queue + .add_used(chain.memory(), chain.head_index(), 0)?; + + if self.output_queue.needs_notification(&self.mem)? { + self.driver_notify.signal_used_queue(OUTPUT_QUEUE_INDEX); + } + } + + // Enable the notifications. + if !self.output_queue.enable_notification(&self.mem)? { + break; + } + } + Ok(()) + } +} + +#[derive(Debug)] +pub enum Error { + GuestMemory(vm_memory::GuestMemoryError), + Queue(virtio_queue::Error), + ConsoleError(ConsoleError), +} + +impl From for Error { + fn from(e: vm_memory::GuestMemoryError) -> Self { + Error::GuestMemory(e) + } +} + +impl From for Error { + fn from(e: virtio_queue::Error) -> Self { + Error::Queue(e) + } +} + +impl From for Error { + fn from(e: ConsoleError) -> Self { + Error::ConsoleError(e) + } +} diff --git a/src/virtio/src/console/virtio/device.rs b/src/virtio/src/console/virtio/device.rs new file mode 100644 index 0000000..a372921 --- /dev/null +++ b/src/virtio/src/console/virtio/device.rs @@ -0,0 +1,176 @@ +use super::console_handler::ConsoleQueueHandler; +use super::queue_handler::QueueHandler; +use crate::device::{SingleFdSignalQueue, Subscriber, VirtioDeviceT}; +use crate::device::{VirtioDevType, VirtioDeviceCommon}; +use api::device_model::BaoDeviceModel; +use api::error::{Error, Result}; +use api::types::DeviceConfig; +use event_manager::{ + EventManager, MutEventSubscriber, RemoteEndpoint, Result as EvmgrResult, SubscriberId, +}; +use std::borrow::{Borrow, BorrowMut}; +use std::sync::{Arc, Mutex}; +use virtio_console::console::Console; +use virtio_device::{VirtioConfig, VirtioDeviceActions, VirtioDeviceType, VirtioMmioDevice}; +use virtio_queue::Queue; +use vm_device::bus::MmioAddress; +use vm_device::device_manager::{IoManager, MmioManager}; +use vm_device::MutDeviceMmio; + +/// Virtio console device. +/// +/// # Attributes +/// +/// * `common` - Virtio common device. +/// * `endpoint` - The remote subscriber endpoint. +pub struct VirtioConsole { + pub common: VirtioDeviceCommon, + pub endpoint: RemoteEndpoint, +} + +impl VirtioDeviceT for VirtioConsole { + fn new( + config: &DeviceConfig, + device_manager: Arc>, + event_manager: Option>>>>>, + device_model: Arc>, + ) -> Result>> { + // Extract the generic features and queues. + let (common_features, queues) = Self::initialize(&config).unwrap(); + + // Update the device features. + let device_features = common_features | Self::device_features(&config).unwrap(); + + // Update the configuration space. + let config_space = Self::config_space(&config).unwrap(); + + // Create a VirtioConfig object. + let virtio_cfg = VirtioConfig::new(device_features, queues, config_space); + + // Create the generic device. + let common_device = VirtioDeviceCommon::new(config, device_model, virtio_cfg).unwrap(); + + // Create a remote endpoint object, that allows interacting with the VM EventManager from a different thread. + let remote_endpoint = event_manager.unwrap().lock().unwrap().remote_endpoint(); + + // Create the console device. + let console = Arc::new(Mutex::new(VirtioConsole { + common: common_device, + endpoint: remote_endpoint, + })); + + // Register the MMIO device within the device manager with the specified range. + device_manager + .lock() + .unwrap() + .register_mmio( + console.clone().lock().unwrap().common.mmio.range, + console.clone(), + ) + .unwrap(); + + // Return the console device. + Ok(console) + } + + fn device_features(_config: &DeviceConfig) -> Result { + Ok(0) + } + + fn config_space(_config: &DeviceConfig) -> Result> { + // https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html#x1-3210003 + Ok(Vec::new()) + } +} + +impl Borrow> for VirtioConsole { + fn borrow(&self) -> &VirtioConfig { + &self.common.config + } +} + +impl BorrowMut> for VirtioConsole { + fn borrow_mut(&mut self) -> &mut VirtioConfig { + &mut self.common.config + } +} + +impl VirtioDeviceType for VirtioConsole { + fn device_type(&self) -> u32 { + VirtioDevType::Console as u32 + } +} + +/// Implement the `VirtioDeviceActions` trait to add our custom device actions. +impl VirtioDeviceActions for VirtioConsole { + type E = Error; + + fn activate(&mut self) -> Result<()> { + // Create the backend. + let console = Console::default(); + + // Create the driver notify object. + let driver_notify = SingleFdSignalQueue { + irqfd: self.common.irqfd.try_clone().unwrap(), + interrupt_status: self.common.config.interrupt_status.clone(), + }; + + // Prepare the activation by calling the generic `prepare_activate` method. + let mut ioevents = self.common.prepare_activate().unwrap(); + + // Create the inner handler. + let inner = ConsoleQueueHandler { + driver_notify, + mem: self.common.mem(), + input_queue: self.common.config.queues.remove(0), + output_queue: self.common.config.queues.remove(0), + console, + }; + + // Create the queue handler. + let handler = Arc::new(Mutex::new(QueueHandler { + inner, + input_ioeventfd: ioevents.remove(0), + output_ioeventfd: ioevents.remove(0), + })); + + // Register the queue handler with the `EventManager`. We could record the `sub_id` + // (and/or keep a handler clone) for further interaction (i.e. to remove the subscriber at + // a later time, retrieve state, etc). + let _sub_id = self + .endpoint + .call_blocking(move |mgr| -> EvmgrResult { + Ok(mgr.add_subscriber(handler)) + }) + .unwrap(); + + // Set the device as activated. + self.common.config.device_activated = true; + + Ok(()) + } + + fn reset(&mut self) -> Result<()> { + // Not implemented for now. + Ok(()) + } +} + +/// Implement the `VirtioMmioDevice` trait to add VirtIO MMIO support to our device. +impl VirtioMmioDevice for VirtioConsole { + fn queue_notify(&mut self, _val: u32) { + // Do nothing for now. + } +} + +/// Implement the `DeviceMmio` mutable trait to add MMIO support to our device. +/// Otherwise we could not register the device within the device manager. +impl MutDeviceMmio for VirtioConsole { + fn mmio_read(&mut self, _base: MmioAddress, offset: u64, data: &mut [u8]) { + self.read(offset, data); + } + + fn mmio_write(&mut self, _base: MmioAddress, offset: u64, data: &[u8]) { + self.write(offset, data); + } +} diff --git a/src/virtio/src/console/virtio/mod.rs b/src/virtio/src/console/virtio/mod.rs new file mode 100644 index 0000000..5b45c5a --- /dev/null +++ b/src/virtio/src/console/virtio/mod.rs @@ -0,0 +1,3 @@ +pub mod console_handler; +pub mod device; +pub mod queue_handler; diff --git a/src/virtio/src/console/virtio/queue_handler.rs b/src/virtio/src/console/virtio/queue_handler.rs new file mode 100644 index 0000000..bc26280 --- /dev/null +++ b/src/virtio/src/console/virtio/queue_handler.rs @@ -0,0 +1,81 @@ +use event_manager::{EventOps, Events, MutEventSubscriber}; +use log::error; +use vmm_sys_util::epoll::EventSet; +use vmm_sys_util::eventfd::EventFd; + +use crate::console::virtio::console_handler::ConsoleQueueHandler; +use crate::device::SingleFdSignalQueue; + +pub const INPUT_QUEUE_INDEX: u16 = 0; +pub const OUTPUT_QUEUE_INDEX: u16 = 1; + +const INPUT_IOEVENT_DATA: u32 = INPUT_QUEUE_INDEX as u32; +const OUTPUT_IOEVENT_DATA: u32 = OUTPUT_QUEUE_INDEX as u32; + +// This object simply combines the more generic `ConsoleQueueHandler` with a concrete queue +// signalling implementation based on `EventFd`s, and then also implements `MutEventSubscriber` +// to interact with the event manager. `ioeventfd` is the `EventFd` connected to queue +// notifications coming from the driver. +pub(crate) struct QueueHandler { + pub inner: ConsoleQueueHandler, + pub input_ioeventfd: EventFd, + pub output_ioeventfd: EventFd, +} + +impl QueueHandler { + // Helper method that receives an error message to be logged and the `ops` handle + // which is used to unregister all events. + fn handle_error>(&self, s: S, ops: &mut EventOps) { + error!("{}", s.as_ref()); + ops.remove(Events::empty(&self.input_ioeventfd)) + .expect("Failed to remove input ioeventfd"); + ops.remove(Events::empty(&self.output_ioeventfd)) + .expect("Failed to remove output ioeventfd"); + } +} + +/// Implement the `MutEventSubscriber` trait for `QueueHandler` to handle the dispatched +/// events (Ioeventfds) from the event manager. +impl MutEventSubscriber for QueueHandler { + fn process(&mut self, events: Events, ops: &mut EventOps) { + if events.event_set() != EventSet::IN { + self.handle_error("Unexpected event_set", ops); + return; + } + + match events.data() { + INPUT_IOEVENT_DATA => { + if self.input_ioeventfd.read().is_err() { + self.handle_error("Input ioeventfd read", ops); + } else if let Err(e) = self.inner.process_input_queue() { + self.handle_error(format!("Process input queue error {:?}", e), ops); + } + } + OUTPUT_IOEVENT_DATA => { + if self.output_ioeventfd.read().is_err() { + self.handle_error("Output ioeventfd read", ops); + } + if let Err(e) = self.inner.process_output_queue() { + self.handle_error(format!("Process output queue error {:?}", e), ops); + } + } + _ => self.handle_error("Unexpected ioeventfd", ops), + } + } + + fn init(&mut self, ops: &mut EventOps) { + ops.add(Events::with_data( + &self.input_ioeventfd, + INPUT_IOEVENT_DATA, + EventSet::IN, + )) + .expect("Failed to init input queue handler"); + + ops.add(Events::with_data( + &self.output_ioeventfd, + OUTPUT_IOEVENT_DATA, + EventSet::IN, + )) + .expect("Failed to init output queue handler"); + } +} diff --git a/src/virtio/src/device.rs b/src/virtio/src/device.rs index af4f290..73331bd 100644 --- a/src/virtio/src/device.rs +++ b/src/virtio/src/device.rs @@ -1,4 +1,5 @@ use super::block::virtio::device::VirtioBlock; +use super::console::virtio::device::VirtioConsole; use super::fs::vhost_user::device::VhostUserFs; use super::mmio::MmioConfig; use super::mmio::VIRTIO_MMIO_INT_VRING; @@ -45,6 +46,7 @@ pub enum VirtioDeviceType { VhostNet(Arc>), VhostUserVsock(Arc>), VirtioNet(Arc>), + VirtioConsole(Arc>), Unknown, } @@ -481,7 +483,7 @@ impl VirtioDevType { match *self { VirtioDevType::Net => (2, 1024), VirtioDevType::Block => (1, 256), - VirtioDevType::Console => (0, 0), + VirtioDevType::Console => (2, 1024), VirtioDevType::Rng => (1, 1024), VirtioDevType::Balloon => (0, 0), VirtioDevType::Gpu => (0, 0), diff --git a/src/virtio/src/lib.rs b/src/virtio/src/lib.rs index 3229f92..0efc08d 100644 --- a/src/virtio/src/lib.rs +++ b/src/virtio/src/lib.rs @@ -1,4 +1,5 @@ pub mod block; +pub mod console; pub mod device; pub mod fs; pub mod mmio; diff --git a/src/vmm/src/vm.rs b/src/vmm/src/vm.rs index f34a793..c75784a 100644 --- a/src/vmm/src/vm.rs +++ b/src/vmm/src/vm.rs @@ -5,6 +5,7 @@ use api::types::DeviceConfig; use event_manager::{EventManager, MutEventSubscriber}; use std::sync::{Arc, Mutex}; use virtio::block::virtio::device::VirtioBlock; +use virtio::console::virtio::device::VirtioConsole; use virtio::device::VirtioDeviceT; use virtio::device::{VirtioDataPlane, VirtioDevType, VirtioDeviceType}; use virtio::fs::vhost_user::device::VhostUserFs; @@ -145,6 +146,17 @@ impl Vm { VirtioDataPlane::to_string(&data_plane), )), }, + // Console device. + VirtioDevType::Console => match data_plane { + VirtioDataPlane::Virtio => Ok(VirtioDeviceType::VirtioConsole( + VirtioConsole::new(config, device_manager, event_manager, device_model) + .unwrap(), + )), + _ => Err(Error::WrongDeviceConfiguration( + VirtioDevType::to_string(&device_type), + VirtioDataPlane::to_string(&data_plane), + )), + }, // Other device types. _ => Err(Error::WrongDeviceConfiguration( VirtioDevType::to_string(&device_type),