diff --git a/arch/src/aarch64/gic/mod.rs b/arch/src/aarch64/gic/mod.rs index 63263a190..c39b79864 100644 --- a/arch/src/aarch64/gic/mod.rs +++ b/arch/src/aarch64/gic/mod.rs @@ -26,7 +26,7 @@ pub enum Error { } type Result = result::Result; -pub trait GICDevice { +pub trait GICDevice: Send { /// Returns the hypervisor agnostic Device of the GIC device fn device(&self) -> &Arc; diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 30559d349..7a7019ac0 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -14,6 +14,7 @@ pub mod regs; pub use self::fdt::DeviceInfoForFDT; use crate::DeviceType; use crate::RegionType; +use aarch64::gic::GICDevice; use hypervisor::kvm::kvm_bindings; use std::collections::HashMap; use std::ffi::CStr; @@ -146,7 +147,7 @@ pub fn configure_system, initrd: &Option, pci_space_address: &Option<(u64, u64)>, -) -> super::Result<()> { +) -> super::Result> { // If pci_space_address is present, it means PCI devices are used ("pci" feature enabled). // Then GITv3-ITS is required for MSI messaging. // Otherwise ("mmio" feature enabled), any version of GIC is OK. @@ -164,7 +165,7 @@ pub fn configure_system>>, + #[cfg(target_arch = "aarch64")] + gic_device_entity: Option>>>, + // Things to be added to the commandline (i.e. for virtio-mmio) cmdline_additions: Vec, @@ -853,6 +858,8 @@ impl DeviceManager { address_manager: Arc::clone(&address_manager), console: Arc::new(Console::default()), interrupt_controller: None, + #[cfg(target_arch = "aarch64")] + gic_device_entity: None, cmdline_additions: Vec::new(), #[cfg(feature = "acpi")] ged_notification_device: None, @@ -1155,6 +1162,16 @@ impl DeviceManager { Ok(interrupt_controller) } + #[cfg(target_arch = "aarch64")] + pub fn set_gic_device_entity(&mut self, device_entity: Arc>>) { + self.gic_device_entity = Some(device_entity); + } + + #[cfg(target_arch = "aarch64")] + pub fn get_gic_device_entity(&self) -> Option<&Arc>>> { + self.gic_device_entity.as_ref() + } + #[cfg(target_arch = "aarch64")] pub fn enable_interrupt_controller(&self) -> DeviceManagerResult<()> { if let Some(interrupt_controller) = &self.interrupt_controller { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 6d83067db..31ec772d5 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -801,7 +801,9 @@ impl Vm { None }; - arch::configure_system( + // Call `configure_system` and pass the GIC devices out, so that + // we can register the GIC device to the device manager. + let gic_device = arch::configure_system( &self.memory_manager.lock().as_ref().unwrap().vm, &mem, &cmdline_cstring, @@ -813,6 +815,12 @@ impl Vm { ) .map_err(Error::ConfigureSystem)?; + // Update the GIC entity in device manager + self.device_manager + .lock() + .unwrap() + .set_gic_device_entity(Arc::new(Mutex::new(gic_device))); + self.device_manager .lock() .unwrap()