arch: Switch to new GIC interface

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao 2022-05-31 19:53:22 +08:00 committed by Xin Wang
parent b8dbb26647
commit 04949755c0
6 changed files with 41 additions and 81 deletions

View File

@ -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<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
vcpu_mpidr: Vec<u64>,
vcpu_topology: Option<(u8, u8, u8)>,
device_info: &HashMap<(DeviceType, String), T, S>,
gic_device: &dyn GicDevice,
gic_device: &dyn Vgic,
initrd: &Option<InitramfsConfig>,
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")?;

View File

@ -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 {}

View File

@ -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<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
initrd: &Option<super::InitramfsConfig>,
pci_space_info: &[PciSpaceInfo],
virtio_iommu_bdf: Option<u32>,
gic_device: &dyn GicDevice,
gic_device: &gic::GicDevice,
numa_nodes: &NumaNodes,
pmu_supported: bool,
) -> super::Result<()> {
@ -153,7 +152,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
vcpu_mpidr,
vcpu_topology,
device_info,
gic_device,
gic_device.get_vgic(),
initrd,
pci_space_info,
numa_nodes,

View File

@ -27,7 +27,7 @@ pub const IRQ_LEGACY_COUNT: usize = 32;
// 2. Move this file and ioapic.rs to arch/, as they are architecture specific.
pub struct Gic {
interrupt_source_group: Arc<dyn InterruptSourceGroup>,
gic_device: Option<Arc<Mutex<Box<dyn GicDevice>>>>,
gic_device: Option<Arc<Mutex<GicDevice>>>,
}
impl Gic {
@ -48,11 +48,11 @@ impl Gic {
})
}
pub fn set_gic_device(&mut self, gic_device: Arc<Mutex<Box<dyn GicDevice>>>) {
pub fn set_gic_device(&mut self, gic_device: Arc<Mutex<GicDevice>>) {
self.gic_device = Some(gic_device);
}
pub fn get_gic_device(&self) -> Option<&Arc<Mutex<Box<dyn GicDevice>>>> {
pub fn get_gic_device(&self) -> Option<&Arc<Mutex<GicDevice>>> {
self.gic_device.as_ref()
}
}

View File

@ -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::<KvmGicV3Its>()
{
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(())

View File

@ -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::<KvmGicV3Its>()
{
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::<KvmGicV3Its>()
{
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"