diff --git a/crates/vm-core/src/arch/aarch64/vm_exit.rs b/crates/vm-core/src/arch/aarch64/vm_exit.rs index ca26075..32ad972 100644 --- a/crates/vm-core/src/arch/aarch64/vm_exit.rs +++ b/crates/vm-core/src/arch/aarch64/vm_exit.rs @@ -54,7 +54,7 @@ pub fn handle_vm_exit( vcpu: &dyn AArch64Vcpu, exit_reason: VmExitReason, psci: Arc>, - device: Arc>, + device: Arc, ) -> Result { trace!(?exit_reason); @@ -62,8 +62,6 @@ pub fn handle_vm_exit( VmExitReason::Unknown => Ok(HandleVmExitResult::Continue), VmExitReason::Wf => Ok(HandleVmExitResult::NextInstruction), VmExitReason::MMIORead { gpa, srt, len } => { - let device = device.lock().unwrap(); - let mut buf = [0; 8]; device .mmio_read(gpa, len, &mut buf[0..len]) @@ -73,8 +71,6 @@ pub fn handle_vm_exit( Ok(HandleVmExitResult::NextInstruction) } VmExitReason::MMIOWrite { gpa, buf, len } => { - let device = device.lock().unwrap(); - device .mmio_write(gpa, len, &buf) .map_err(|err| Error::MmioErr(err.to_string()))?; diff --git a/crates/vm-core/src/device.rs b/crates/vm-core/src/device.rs index d4c654c..e51461b 100644 --- a/crates/vm-core/src/device.rs +++ b/crates/vm-core/src/device.rs @@ -24,12 +24,10 @@ pub enum Error { mmio_len: usize, addr: u64, }, - #[error("irq_chip already exists")] - IrqChipAlreadyExists, } pub type Result = core::result::Result; -pub trait Device: Send { +pub trait Device: Send + Sync { fn name(&self) -> String; } diff --git a/crates/vm-core/src/device/device_manager.rs b/crates/vm-core/src/device/device_manager.rs index 5041301..0799ea0 100644 --- a/crates/vm-core/src/device/device_manager.rs +++ b/crates/vm-core/src/device/device_manager.rs @@ -1,8 +1,6 @@ -use std::cell::OnceCell; use std::slice::Iter; use std::sync::Arc; -use crate::arch::irq::InterruptController; use crate::device::Error; use crate::device::Result; use crate::device::mmio::MmioLayout; @@ -13,7 +11,6 @@ use crate::device::pio::pio_device::PioDevice; use crate::device::vm_exit::DeviceVmExitHandler; pub struct DeviceManager { - irq_chip: OnceCell>, pio_manager: PioAddressSpaceManager, mmio_manager: MmioAddressSpaceManager, } @@ -99,22 +96,11 @@ impl DeviceVmExitHandler for DeviceManager { impl DeviceManager { pub fn new(mmio_layout: MmioLayout) -> Self { DeviceManager { - irq_chip: Default::default(), pio_manager: PioAddressSpaceManager::default(), mmio_manager: MmioAddressSpaceManager::new(mmio_layout), } } - pub fn register_irq_chip(&mut self, irq_chip: Arc) -> Result<()> { - self.irq_chip - .set(irq_chip) - .map_err(|_| Error::IrqChipAlreadyExists) - } - - pub fn get_irq_chip(&self) -> Option> { - self.irq_chip.get().cloned() - } - pub fn register_pio_device(&mut self, device: Box) -> Result<()> { self.pio_manager.register(device) } diff --git a/crates/vm-core/src/device/mmio/mmio_device.rs b/crates/vm-core/src/device/mmio/mmio_device.rs index 20a1d01..b5293d0 100644 --- a/crates/vm-core/src/device/mmio/mmio_device.rs +++ b/crates/vm-core/src/device/mmio/mmio_device.rs @@ -3,7 +3,7 @@ use vm_fdt::FdtWriter; use crate::device::Device; use crate::device::mmio::MmioRange; -pub trait MmioHandler: Send { +pub trait MmioHandler: Send + Sync { fn mmio_range(&self) -> MmioRange; fn mmio_read(&self, offset: u64, len: usize, data: &mut [u8]); diff --git a/crates/vm-core/src/device/vm_exit.rs b/crates/vm-core/src/device/vm_exit.rs index 3526a78..96d153f 100644 --- a/crates/vm-core/src/device/vm_exit.rs +++ b/crates/vm-core/src/device/vm_exit.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use crate::device::Result; use crate::device::mmio::MmioLayout; -pub trait DeviceVmExitHandler: Send { +pub trait DeviceVmExitHandler: Send + Sync { fn io_in(&mut self, port: u16, data: &mut [u8]) -> Result<()>; fn io_out(&mut self, port: u16, data: &[u8]) -> Result<()>; fn mmio_read(&self, addr: u64, len: usize, data: &mut [u8]) -> Result<()>; diff --git a/crates/vm-core/src/virt.rs b/crates/vm-core/src/virt.rs index bc65a99..8c25864 100644 --- a/crates/vm-core/src/virt.rs +++ b/crates/vm-core/src/virt.rs @@ -1,5 +1,4 @@ use std::sync::Arc; -use std::sync::Mutex; use vm_mm::allocator::MemoryContainer; use vm_mm::manager::MemoryAddressSpace; @@ -38,5 +37,5 @@ pub trait Virt: Sized { fn get_vcpus(&self) -> Result<&Vec>; fn get_vcpus_mut(&mut self) -> Result<&mut Vec>; - fn run(&mut self, device_manager: Arc>) -> Result<()>; + fn run(&mut self, device_manager: Arc) -> Result<()>; } diff --git a/crates/vm-core/src/virt/hvp.rs b/crates/vm-core/src/virt/hvp.rs index 500c77b..c45f5c2 100644 --- a/crates/vm-core/src/virt/hvp.rs +++ b/crates/vm-core/src/virt/hvp.rs @@ -322,8 +322,8 @@ impl Virt for Hvp { .ok_or_else(|| Error::Internal("vcpu is not initialized".to_string())) } - fn run(&mut self, device_manager: Arc>) -> Result<()> { - let mmio_layout = device_manager.lock().unwrap().mmio_layout(); + fn run(&mut self, device_manager: Arc) -> Result<()> { + let mmio_layout = device_manager.mmio_layout(); thread::scope(|s| { let cpu_on_receiver = self.cpu_on_receiver.take().unwrap(); diff --git a/crates/vm-core/src/virt/kvm.rs b/crates/vm-core/src/virt/kvm.rs index 436272d..5137afe 100644 --- a/crates/vm-core/src/virt/kvm.rs +++ b/crates/vm-core/src/virt/kvm.rs @@ -1,7 +1,6 @@ use std::cell::OnceCell; use std::marker::PhantomData; use std::sync::Arc; -use std::sync::Mutex; use kvm_ioctls::*; use memmap2::MmapMut; @@ -102,7 +101,7 @@ where .ok_or_else(|| Error::Internal("vcpus is not init".to_string())) } - fn run(&mut self, device: Arc>) -> Result<()> { + fn run(&mut self, device: Arc) -> Result<()> { let vcpus = self .vcpus .get_mut() @@ -110,7 +109,7 @@ where assert_eq!(vcpus.len(), 1); - let mmio_layout = device.lock().unwrap().mmio_layout(); + let mmio_layout = device.mmio_layout(); vcpus.get_mut(0).unwrap().run(mmio_layout.as_ref())?; diff --git a/crates/vm-machine/src/device.rs b/crates/vm-machine/src/device.rs index b074ff7..551f815 100644 --- a/crates/vm-machine/src/device.rs +++ b/crates/vm-machine/src/device.rs @@ -4,7 +4,6 @@ use vm_core::arch::irq::InterruptController; use vm_core::device::device_manager::DeviceManager; use vm_core::device::mmio::MmioRange; use vm_device::device::Device; -use vm_device::device::gic_v3::GicV3; use vm_device::device::virtio::virtio_blk::VirtIoBlkDevice; use vm_device::device::virtio::virtio_blk::VirtIoMmioBlkDevice; use vm_mm::allocator::MemoryContainer; @@ -19,7 +18,7 @@ pub trait InitDevice { &mut self, mm: Arc>, devices: Vec, - irq_chip: Option>, + irq_chip: Arc, ) -> Result<(), Error> where C: MemoryContainer; @@ -29,28 +28,12 @@ impl InitDevice for DeviceManager { fn init_devices( &mut self, mm: Arc>, - devices: Vec, - irq_chip: Option>, + _devices: Vec, + irq_chip: Arc, ) -> Result<(), Error> where C: MemoryContainer, { - let irq_chip = match irq_chip { - Some(irq_chip) => irq_chip, - None => { - let irq_chip = devices - .iter() - .find(|dev| dev.is_irq_chip()) - .ok_or(Error::NoIrqChipSpecified)?; - - match irq_chip { - Device::GicV3 => Arc::new(GicV3::default()), - } - } - }; - - self.register_irq_chip(irq_chip.clone())?; - { let pci_rc = PciRootComplexMmio::new( MmioRange { diff --git a/crates/vm-machine/src/vm.rs b/crates/vm-machine/src/vm.rs index f8ef894..6989ef6 100644 --- a/crates/vm-machine/src/vm.rs +++ b/crates/vm-machine/src/vm.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use std::sync::Mutex; use vm_bootloader::boot_loader::BootLoader; +use vm_core::arch::irq::InterruptController; use vm_core::debug::gdbstub::GdbStub; use vm_core::device::device_manager::DeviceManager; use vm_core::virt::Virt; @@ -13,7 +13,8 @@ use crate::error::Result; pub struct Vm { pub(crate) memory: Arc>, pub(crate) virt: V, - pub(crate) device_manager: Arc>, + pub(crate) irq_chip: Arc, + pub(crate) device_manager: Arc, pub(crate) gdb_stub: Option, } @@ -22,19 +23,12 @@ where V: Virt, { pub fn run(&mut self, boot_loader: &dyn BootLoader) -> Result<()> { - { - let device_manager = self.device_manager.lock().unwrap(); - - boot_loader.load( - &mut self.virt, - &self.memory, - device_manager - .get_irq_chip() - .ok_or_else(|| Error::InitIrqchip("irq_chip is not exists".to_string()))? - .as_ref(), - device_manager.mmio_devices(), - )?; - } + boot_loader.load( + &mut self.virt, + &self.memory, + self.irq_chip.as_ref(), + self.device_manager.mmio_devices(), + )?; if let Some(gdb_stub) = &self.gdb_stub { gdb_stub diff --git a/crates/vm-machine/src/vm_builder.rs b/crates/vm-machine/src/vm_builder.rs index a176184..46ab716 100644 --- a/crates/vm-machine/src/vm_builder.rs +++ b/crates/vm-machine/src/vm_builder.rs @@ -1,5 +1,4 @@ use std::sync::Arc; -use std::sync::Mutex; use vm_core::arch::layout::MemoryLayout; use vm_core::debug::gdbstub::GdbStub; @@ -49,18 +48,19 @@ impl VmBuilder { let mmio_layout = MmioLayout::new(layout.get_mmio_start(), layout.get_mmio_len()); let irq_chip = if !self.devices.iter().any(Device::is_irq_chip) { - Some(virt.init_irq()?) + virt.init_irq()? } else { - None + todo!() }; let mut device_manager = DeviceManager::new(mmio_layout); - device_manager.init_devices(memory.clone(), self.devices, irq_chip)?; + device_manager.init_devices(memory.clone(), self.devices, irq_chip.clone())?; let vm = Vm { memory, virt, - device_manager: Arc::new(Mutex::new(device_manager)), + irq_chip, + device_manager: Arc::new(device_manager), gdb_stub: self.gdb_port.map(GdbStub::new), }; diff --git a/crates/vm-pci/src/device/function.rs b/crates/vm-pci/src/device/function.rs index 8b67970..72eeb19 100644 --- a/crates/vm-pci/src/device/function.rs +++ b/crates/vm-pci/src/device/function.rs @@ -3,7 +3,7 @@ use crate::types::configuration_space::ConfigurationSpace; pub mod type0; -pub trait BarHandler: Send { +pub trait BarHandler: Send + Sync { fn read(&self, offset: u64, data: &mut [u8]); fn write(&self, offset: u64, data: &[u8]); diff --git a/crates/vm-pci/src/types/function.rs b/crates/vm-pci/src/types/function.rs index 0392878..0ecfed0 100644 --- a/crates/vm-pci/src/types/function.rs +++ b/crates/vm-pci/src/types/function.rs @@ -13,7 +13,7 @@ pub enum EcamUpdateCallback { }, } -pub trait PciFunction: PciFunctionArch + Send { +pub trait PciFunction: PciFunctionArch + Send + Sync { fn ecam_read(&self, offset: u16, buf: &mut [u8]); fn ecam_write(&self, offset: u16, buf: &[u8]) -> Option; diff --git a/crates/vm-virtio/src/device.rs b/crates/vm-virtio/src/device.rs index 1159000..5d5ebcd 100644 --- a/crates/vm-virtio/src/device.rs +++ b/crates/vm-virtio/src/device.rs @@ -15,7 +15,7 @@ pub trait VirtQueueHandler { async fn handler(&self, virt_queue: &mut VirtQueue); } -pub trait VirtIoDevice: Sized + Send + 'static { +pub trait VirtIoDevice: Sized + Send + Sync + 'static { const NAME: &str; const DEVICE_ID: u32; const VIRT_QUEUES_SIZE_MAX: &[u32];