diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index 4649fb809..ff6738537 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -8,6 +8,7 @@ use crate::{NumaNodes, PciSpaceInfo}; use byteorder::{BigEndian, ByteOrder}; +use hypervisor::arch::aarch64::gic::Vgic; use std::cmp; use std::collections::HashMap; use std::ffi::CStr; @@ -18,7 +19,6 @@ use std::str; use super::super::DeviceType; use super::super::GuestMemoryMmap; use super::super::InitramfsConfig; -use super::gic::GicDevice; use super::layout::{ IRQ_BASE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START, PCI_HIGH_BASE, PCI_MMIO_CONFIG_SIZE_PER_SEGMENT, @@ -90,7 +90,7 @@ pub fn create_fdt, vcpu_topology: Option<(u8, u8, u8)>, device_info: &HashMap<(DeviceType, String), T, S>, - gic_device: &dyn GicDevice, + gic_device: &dyn Vgic, initrd: &Option, pci_space_info: &[PciSpaceInfo], numa_nodes: &NumaNodes, @@ -315,7 +315,7 @@ fn create_chosen_node( Ok(()) } -fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn GicDevice) -> FdtWriterResult<()> { +fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn Vgic) -> FdtWriterResult<()> { let gic_reg_prop = gic_device.device_properties(); let intc_node = fdt.begin_node("intc")?; diff --git a/arch/src/aarch64/gic.rs b/arch/src/aarch64/gic.rs index 94d1d8562..0cac35a09 100644 --- a/arch/src/aarch64/gic.rs +++ b/arch/src/aarch64/gic.rs @@ -1,11 +1,12 @@ // Copyright 2021 Arm Limited (or its affiliates). All rights reserved. +use crate::layout; +use anyhow::anyhow; use hypervisor::{arch::aarch64::gic::Vgic, CpuState}; use std::result; use std::sync::Arc; -use vm_migration::{ - Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, -}; +use vm_memory::Address; +use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; /// Errors thrown while setting up the GIC. #[derive(Debug)] @@ -35,7 +36,9 @@ impl GicDevice { Ok(GicDevice { vgic }) } - pub fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) {} + pub fn set_gicr_typers(&mut self, vcpu_states: &[CpuState]) { + self.vgic.set_gicr_typers(vcpu_states) + } pub fn get_vgic(&self) -> &dyn Vgic { &*self.vgic @@ -54,30 +57,23 @@ impl Snapshottable for GicDevice { } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.vgic.set_state(&snapshot.to_state(&self.id())?) + self.vgic + .set_state(&snapshot.to_state(&self.id())?) .map_err(|e| { MigratableError::Restore(anyhow!("Could not restore GICv3ITS state {:?}", e)) }) - Ok(()) } } impl Pausable for GicDevice { fn pause(&mut self) -> std::result::Result<(), MigratableError> { - /* - // Flush redistributors pending tables to guest RAM. - KvmGicDevice::save_pending_tables(self.device()).map_err(|e| { - MigratableError::Pause(anyhow!( - "Could not save GICv3ITS GIC pending tables {:?}", - e - )) - })?; - // Flush ITS tables to guest RAM. - gicv3_its_tables_access(self.its_device().unwrap(), true).map_err(|e| { - MigratableError::Pause(anyhow!("Could not save GICv3ITS ITS tables {:?}", e)) - })?; - */ - Ok(()) + // Flush tables to guest RAM + self.vgic.save_data_tables().map_err(|e| { + MigratableError::Pause(anyhow!( + "Could not save GICv3ITS GIC pending tables {:?}", + e + )) + }) } } impl Transportable for GicDevice {} diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 5ca825f30..b582cc751 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -15,7 +15,6 @@ pub mod uefi; pub use self::fdt::DeviceInfoForFdt; use crate::{DeviceType, GuestMemoryMmap, NumaNodes, PciSpaceInfo, RegionType}; -use gic::GicDevice; use log::{log_enabled, Level}; use std::collections::HashMap; use std::convert::TryInto; @@ -143,7 +142,7 @@ pub fn configure_system, pci_space_info: &[PciSpaceInfo], virtio_iommu_bdf: Option, - gic_device: &dyn GicDevice, + gic_device: &gic::GicDevice, numa_nodes: &NumaNodes, pmu_supported: bool, ) -> super::Result<()> { @@ -153,7 +152,7 @@ pub fn configure_system, - gic_device: Option>>>, + gic_device: Option>>, } impl Gic { @@ -48,11 +48,11 @@ impl Gic { }) } - pub fn set_gic_device(&mut self, gic_device: Arc>>) { + pub fn set_gic_device(&mut self, gic_device: Arc>) { self.gic_device = Some(gic_device); } - pub fn get_gic_device(&self) -> Option<&Arc>>> { + pub fn get_gic_device(&self) -> Option<&Arc>> { self.gic_device.as_ref() } } diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 73ccbcbee..9dcf1a738 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -29,8 +29,6 @@ use crate::PciDeviceInfo; use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID}; use acpi_tables::{aml, aml::Aml}; use anyhow::anyhow; -#[cfg(target_arch = "aarch64")] -use arch::aarch64::gic::kvm::KvmGicV3Its; use arch::layout; #[cfg(target_arch = "x86_64")] use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START}; @@ -4327,26 +4325,15 @@ impl Pausable for DeviceManager { // and ITS tables to guest RAM. #[cfg(target_arch = "aarch64")] { - let gic_device = Arc::clone( - self.get_interrupt_controller() - .unwrap() - .lock() - .unwrap() - .get_gic_device() - .unwrap(), - ); - if let Some(gicv3_its) = gic_device + self.get_interrupt_controller() + .unwrap() .lock() .unwrap() - .as_any_concrete_mut() - .downcast_mut::() - { - gicv3_its.pause()?; - } else { - return Err(MigratableError::Pause(anyhow!( - "GicDevice downcast to KvmGicV3Its failed when pausing device manager!" - ))); - }; + .get_gic_device() + .unwrap() + .lock() + .unwrap() + .pause()?; }; Ok(()) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 5d6fa08cf..d457b415b 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -38,9 +38,7 @@ use crate::{ }; use anyhow::anyhow; #[cfg(target_arch = "aarch64")] -use arch::aarch64::gic::kvm::create_gic; -#[cfg(target_arch = "aarch64")] -use arch::aarch64::gic::kvm::{KvmGicV3Its, GIC_V3_ITS_SNAPSHOT_ID}; +use arch::aarch64::gic::{GicDevice, GIC_V3_ITS_SNAPSHOT_ID}; use arch::get_host_cpu_phys_bits; #[cfg(target_arch = "x86_64")] use arch::layout::{KVM_IDENTITY_MAP_START, KVM_TSS_START}; @@ -1184,7 +1182,7 @@ impl Vm { .as_ref() .map(|(v, _)| *v); - let gic_device = create_gic( + let gic_device = GicDevice::new( &self.memory_manager.lock().as_ref().unwrap().vm, self.cpu_manager.lock().unwrap().boot_vcpus() as u64, ) @@ -1215,13 +1213,14 @@ impl Vm { &initramfs_config, &pci_space_info, virtio_iommu_bdf.map(|bdf| bdf.into()), - &*gic_device, + &gic_device, &self.numa_nodes, pmu_supported, ) .map_err(Error::ConfigureSystem)?; // Update the GIC entity in device manager + let gic_device = Arc::new(Mutex::new(gic_device)); self.device_manager .lock() .unwrap() @@ -1229,7 +1228,7 @@ impl Vm { .unwrap() .lock() .unwrap() - .set_gic_device(Arc::new(Mutex::new(gic_device))); + .set_gic_device(gic_device); // Activate gic device self.device_manager @@ -2237,20 +2236,7 @@ impl Vm { .unwrap() .set_gicr_typers(&saved_vcpu_states); - vm_snapshot.add_snapshot( - if let Some(gicv3_its) = gic_device - .lock() - .unwrap() - .as_any_concrete_mut() - .downcast_mut::() - { - gicv3_its.snapshot()? - } else { - return Err(MigratableError::Snapshot(anyhow!( - "GicDevice downcast to KvmGicV3Its failed when snapshotting VM!" - ))); - }, - ); + vm_snapshot.add_snapshot(gic_device.lock().unwrap().snapshot()?); Ok(()) } @@ -2268,7 +2254,7 @@ impl Vm { // Creating a GIC device here, as the GIC will not be created when // restoring the device manager. Note that currently only the bare GICv3 // without ITS is supported. - let mut gic_device = create_gic(&self.vm, vcpu_numbers.try_into().unwrap()) + let mut gic_device = GicDevice::new(&self.vm, vcpu_numbers.try_into().unwrap()) .map_err(|e| MigratableError::Restore(anyhow!("Could not create GIC: {:#?}", e)))?; // PMU interrupt sticks to PPI, so need to be added by 16 to get real irq number. @@ -2290,22 +2276,14 @@ impl Vm { .unwrap() .lock() .unwrap() - .set_gic_device(Arc::clone(&gic_device)); + .set_gic_device(gic_device.clone()); // Restore GIC states. if let Some(gicv3_its_snapshot) = vm_snapshot.snapshots.get(GIC_V3_ITS_SNAPSHOT_ID) { - if let Some(gicv3_its) = gic_device + gic_device .lock() .unwrap() - .as_any_concrete_mut() - .downcast_mut::() - { - gicv3_its.restore(*gicv3_its_snapshot.clone())?; - } else { - return Err(MigratableError::Restore(anyhow!( - "GicDevice downcast to KvmGicV3Its failed when restoring VM!" - ))); - }; + .restore(*gicv3_its_snapshot.clone())?; } else { return Err(MigratableError::Restore(anyhow!( "Missing GicV3Its snapshot"