From 8142c823ed61d13759ab5065e09d9662bdfd5581 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 27 Feb 2020 10:29:03 +0100 Subject: [PATCH] vmm: Move DeviceManager into an Arc> In anticipation of the support for device hotplug, this commit moves the DeviceManager object into an Arc> when the DeviceManager is being created. The reason is, we need the DeviceManager to implement the BusDevice trait and then provide it to the IO bus, so that IO accesses related to device hotplug can be handled correctly. Signed-off-by: Sebastien Boeuf --- vmm/src/acpi.rs | 6 +++--- vmm/src/cpu.rs | 3 ++- vmm/src/device_manager.rs | 4 ++-- vmm/src/vm.rs | 20 +++++++++++++------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index eabb7a549..f9ebf5477 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -80,14 +80,14 @@ struct IortIdMapping { } pub fn create_dsdt_table( - device_manager: &DeviceManager, + device_manager: &Arc>, cpu_manager: &Arc>, memory_manager: &Arc>, ) -> SDT { // DSDT let mut dsdt = SDT::new(*b"DSDT", 36, 6, *b"CLOUDH", *b"CHDSDT ", 1); - dsdt.append_slice(device_manager.to_aml_bytes().as_slice()); + dsdt.append_slice(device_manager.lock().unwrap().to_aml_bytes().as_slice()); dsdt.append_slice(cpu_manager.lock().unwrap().to_aml_bytes().as_slice()); dsdt.append_slice(memory_manager.lock().unwrap().to_aml_bytes().as_slice()); @@ -96,7 +96,7 @@ pub fn create_dsdt_table( pub fn create_acpi_tables( guest_mem: &GuestMemoryMmap, - device_manager: &DeviceManager, + device_manager: &Arc>, cpu_manager: &Arc>, memory_manager: &Arc>, ) -> GuestAddress { diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 1a0b0e094..22d3972e1 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -494,7 +494,7 @@ impl CpuManager { pub fn new( boot_vcpus: u8, max_vcpus: u8, - device_manager: &DeviceManager, + device_manager: &Arc>, guest_memory: GuestMemoryAtomic, fd: Arc, cpuid: CpuId, @@ -503,6 +503,7 @@ impl CpuManager { let mut vcpu_states = Vec::with_capacity(usize::from(max_vcpus)); vcpu_states.resize_with(usize::from(max_vcpus), VcpuState::default); + let device_manager = device_manager.lock().unwrap(); let cpu_manager = Arc::new(Mutex::new(CpuManager { boot_vcpus, max_vcpus, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index b8d9f9e25..1c7470d48 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -440,7 +440,7 @@ impl DeviceManager { _exit_evt: &EventFd, reset_evt: &EventFd, vmm_path: PathBuf, - ) -> DeviceManagerResult { + ) -> DeviceManagerResult>> { let io_bus = devices::Bus::new(); let mmio_bus = devices::Bus::new(); @@ -543,7 +543,7 @@ impl DeviceManager { device_manager.virtio_devices = virtio_devices; - Ok(device_manager) + Ok(Arc::new(Mutex::new(device_manager))) } #[allow(unused_variables)] diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index db8c55207..6df079b5a 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -212,7 +212,7 @@ impl VmState { pub struct Vm { kernel: File, threads: Vec>, - devices: DeviceManager, + devices: Arc>, config: Arc>, on_tty: bool, signals: Option, @@ -384,7 +384,7 @@ impl Vm { cmdline .insert_str(self.config.lock().unwrap().cmdline.args.clone()) .map_err(Error::CmdLineInsertStr)?; - for entry in self.devices.cmdline_additions() { + for entry in self.devices.lock().unwrap().cmdline_additions() { cmdline.insert_str(entry).map_err(Error::CmdLineInsertStr)?; } @@ -513,6 +513,8 @@ impl Vm { .map_err(Error::CpuManager)? { self.devices + .lock() + .unwrap() .notify_hotplug(HotPlugNotificationFlags::CPU_DEVICES_CHANGED) .map_err(Error::DeviceManager)?; } @@ -528,6 +530,8 @@ impl Vm { .map_err(Error::MemoryManager)? { self.devices + .lock() + .unwrap() .notify_hotplug(HotPlugNotificationFlags::MEMORY_DEVICES_CHANGED) .map_err(Error::DeviceManager)?; } @@ -574,8 +578,8 @@ impl Vm { .start_boot_vcpus(entry_addr) .map_err(Error::CpuManager)?; - if self.devices.console().input_enabled() { - let console = self.devices.console().clone(); + if self.devices.lock().unwrap().console().input_enabled() { + let console = self.devices.lock().unwrap().console().clone(); let signals = Signals::new(&[SIGWINCH, SIGINT, SIGTERM]); match signals { Ok(signals) => { @@ -613,8 +617,10 @@ impl Vm { .read_raw(&mut out) .map_err(Error::Console)?; - if self.devices.console().input_enabled() { + if self.devices.lock().unwrap().console().input_enabled() { self.devices + .lock() + .unwrap() .console() .queue_input_bytes(&out[..count]) .map_err(Error::Console)?; @@ -650,7 +656,7 @@ impl Pausable for Vm { .map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {:?}", e)))?; self.cpu_manager.lock().unwrap().pause()?; - self.devices.pause()?; + self.devices.lock().unwrap().pause()?; *state = new_state; @@ -668,7 +674,7 @@ impl Pausable for Vm { .valid_transition(new_state) .map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {:?}", e)))?; - self.devices.resume()?; + self.devices.lock().unwrap().resume()?; self.cpu_manager.lock().unwrap().resume()?; // And we're back to the Running state.