diff --git a/src/vmm/src/core/cpu/mod.rs b/src/vmm/src/core/cpu/mod.rs index dcbe63f..9c60d44 100644 --- a/src/vmm/src/core/cpu/mod.rs +++ b/src/vmm/src/core/cpu/mod.rs @@ -17,6 +17,8 @@ mod gdt; use gdt::*; mod interrupts; use interrupts::*; + +use super::devices::serial::{CONTROL_SERIAL_PORT, CONTROL_SERIAL_PORT_LAST_REGISTER}; pub(crate) mod mpspec; pub(crate) mod mptable; pub(crate) mod msr_index; @@ -68,15 +70,23 @@ pub(crate) struct Vcpu { pub vcpu_fd: VcpuFd, serial: Arc>, + + control_serial: Arc>, } impl Vcpu { /// Create a new vCPU. - pub fn new(vm_fd: &VmFd, index: u64, serial: Arc>) -> Result { + pub fn new( + vm_fd: &VmFd, + index: u64, + serial: Arc>, + control_serial: Arc>, + ) -> Result { Ok(Vcpu { index, vcpu_fd: vm_fd.create_vcpu(index).map_err(Error::KvmIoctl)?, serial, + control_serial, }) } @@ -249,6 +259,20 @@ impl Vcpu { ) .unwrap(); } + CONTROL_SERIAL_PORT..=CONTROL_SERIAL_PORT_LAST_REGISTER => { + println!("Control serial port write"); + self.control_serial + .lock() + .unwrap() + .serial + .write( + (addr - CONTROL_SERIAL_PORT) + .try_into() + .expect("Invalid serial register offset"), + data[0], + ) + .unwrap(); + } KBD_CMD_IO_ADDR => { if data[0] == KBD_RESET_CMD { info!(?exit_reason, "Guest reset via keyboard controller. Bye!"); @@ -270,6 +294,14 @@ impl Vcpu { .expect("Invalid serial register offset"), ); } + CONTROL_SERIAL_PORT..=CONTROL_SERIAL_PORT_LAST_REGISTER => { + println!("Control serial port write"); + data[0] = self.control_serial.lock().unwrap().serial.read( + (addr - CONTROL_SERIAL_PORT) + .try_into() + .expect("Invalid serial register offset"), + ); + } _ => { warn!(address = addr, "Unsupported device read at {:x?}", addr); } diff --git a/src/vmm/src/core/devices/serial.rs b/src/vmm/src/core/devices/serial.rs index e21ca9c..4b39e7e 100644 --- a/src/vmm/src/core/devices/serial.rs +++ b/src/vmm/src/core/devices/serial.rs @@ -10,6 +10,9 @@ use vmm_sys_util::eventfd::EventFd; pub const SERIAL_PORT_BASE: u16 = 0x3f8; pub const SERIAL_PORT_LAST_REGISTER: u16 = SERIAL_PORT_BASE + 0x8; +pub const CONTROL_SERIAL_PORT: u16 = 0x2f8; +pub const CONTROL_SERIAL_PORT_LAST_REGISTER: u16 = CONTROL_SERIAL_PORT + 0x8; + pub struct EventFdTrigger(EventFd); impl Trigger for EventFdTrigger { diff --git a/src/vmm/src/core/vmm.rs b/src/vmm/src/core/vmm.rs index 023dbfb..12bbfff 100644 --- a/src/vmm/src/core/vmm.rs +++ b/src/vmm/src/core/vmm.rs @@ -30,6 +30,7 @@ pub struct VMM { _tap: Tap, serial: Arc>, + comm_serial: Arc>, epoll: EpollContext, } @@ -65,6 +66,9 @@ impl VMM { serial: Arc::new(Mutex::new( LumperSerial::new().map_err(Error::SerialCreation)?, )), + comm_serial: Arc::new(Mutex::new( + LumperSerial::new().map_err(Error::SerialCreation)?, + )), epoll, }; @@ -124,6 +128,18 @@ impl VMM { ) .map_err(Error::KvmIoctl)?; + self.vm_fd + .register_irqfd( + &self + .comm_serial + .lock() + .unwrap() + .eventfd() + .map_err(Error::IrqRegister)?, + 3, + ) + .map_err(Error::KvmIoctl)?; + Ok(()) } @@ -137,8 +153,13 @@ impl VMM { .map_err(Error::KvmIoctl)?; for index in 0..num_vcpus { - let vcpu = Vcpu::new(&self.vm_fd, index.into(), Arc::clone(&self.serial)) - .map_err(Error::Vcpu)?; + let vcpu = Vcpu::new( + &self.vm_fd, + index.into(), + Arc::clone(&self.serial), + Arc::clone(&self.comm_serial), + ) + .map_err(Error::Vcpu)?; // Set CPUID. let mut vcpu_cpuid = base_cpuid.clone();