aarch64: Simplify GIC related structs definition

Combined the `GicDevice` struct in `arch` crate and the `Gic` struct in
`devices` crate.

After moving the KVM specific code for GIC in `arch`, a very thin wapper
layer `GicDevice` was left in `arch` crate. It is easy to combine it
with the `Gic` in `devices` crate.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao
2022-06-01 13:24:12 +08:00
committed by Xin Wang
parent 04949755c0
commit 957d3a7443
12 changed files with 150 additions and 161 deletions

View File

@@ -15,6 +15,7 @@ use std::ffi::CStr;
use std::fmt::Debug;
use std::result;
use std::str;
use std::sync::{Arc, Mutex};
use super::super::DeviceType;
use super::super::GuestMemoryMmap;
@@ -90,7 +91,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 Vgic,
gic_device: &Arc<Mutex<dyn Vgic>>,
initrd: &Option<InitramfsConfig>,
pci_space_info: &[PciSpaceInfo],
numa_nodes: &NumaNodes,
@@ -315,12 +316,12 @@ fn create_chosen_node(
Ok(())
}
fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn Vgic) -> FdtWriterResult<()> {
let gic_reg_prop = gic_device.device_properties();
fn create_gic_node(fdt: &mut FdtWriter, gic_device: &Arc<Mutex<dyn Vgic>>) -> FdtWriterResult<()> {
let gic_reg_prop = gic_device.lock().unwrap().device_properties();
let intc_node = fdt.begin_node("intc")?;
fdt.property_string("compatible", gic_device.fdt_compatibility())?;
fdt.property_string("compatible", gic_device.lock().unwrap().fdt_compatibility())?;
fdt.property_null("interrupt-controller")?;
// "interrupt-cells" field specifies the number of cells needed to encode an
// interrupt source. The type shall be a <u32> and the value shall be 3 if no PPI affinity description
@@ -334,17 +335,17 @@ fn create_gic_node(fdt: &mut FdtWriter, gic_device: &dyn Vgic) -> FdtWriterResul
let gic_intr_prop = [
GIC_FDT_IRQ_TYPE_PPI,
gic_device.fdt_maint_irq(),
gic_device.lock().unwrap().fdt_maint_irq(),
IRQ_TYPE_LEVEL_HI,
];
fdt.property_array_u32("interrupts", &gic_intr_prop)?;
if gic_device.msi_compatible() {
if gic_device.lock().unwrap().msi_compatible() {
let msic_node = fdt.begin_node("msic")?;
fdt.property_string("compatible", gic_device.msi_compatibility())?;
fdt.property_string("compatible", gic_device.lock().unwrap().msi_compatibility())?;
fdt.property_null("msi-controller")?;
fdt.property_u32("phandle", MSI_PHANDLE)?;
let msi_reg_prop = gic_device.msi_properties();
let msi_reg_prop = gic_device.lock().unwrap().msi_properties();
fdt.property_array_u64("reg", &msi_reg_prop)?;
fdt.end_node(msic_node)?;
}

View File

@@ -1,80 +0,0 @@
// 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_memory::Address;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
/// Errors thrown while setting up the GIC.
#[derive(Debug)]
pub enum Error {
CreateGic(hypervisor::HypervisorVmError),
}
type Result<T> = result::Result<T, Error>;
/// A wrapper around creating and using a hypervisor-agnostic vgic.
pub struct GicDevice {
// The hypervisor abstracted GIC.
vgic: Box<dyn Vgic>,
}
impl GicDevice {
pub fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<GicDevice> {
let vgic = vm
.create_vgic(
vcpu_count,
layout::GIC_V3_DIST_START.raw_value(),
layout::GIC_V3_DIST_SIZE,
layout::GIC_V3_REDIST_SIZE,
layout::GIC_V3_ITS_SIZE,
layout::IRQ_NUM,
)
.unwrap();
Ok(GicDevice { vgic })
}
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
}
}
pub const GIC_V3_ITS_SNAPSHOT_ID: &str = "gic-v3-its";
impl Snapshottable for GicDevice {
fn id(&self) -> String {
GIC_V3_ITS_SNAPSHOT_ID.to_string()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
let state = self.vgic.state().unwrap();
Snapshot::new_from_state(&self.id(), &state)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
self.vgic
.set_state(&snapshot.to_state(&self.id())?)
.map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore GICv3ITS state {:?}", e))
})
}
}
impl Pausable for GicDevice {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// 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 {}
impl Migratable for GicDevice {}

View File

@@ -4,8 +4,6 @@
/// Module for the flattened device tree.
pub mod fdt;
/// Module for the global interrupt controller configuration.
pub mod gic;
/// Layout for this aarch64 system.
pub mod layout;
/// Logic for configuring aarch64 registers.
@@ -15,11 +13,12 @@ pub mod uefi;
pub use self::fdt::DeviceInfoForFdt;
use crate::{DeviceType, GuestMemoryMmap, NumaNodes, PciSpaceInfo, RegionType};
use hypervisor::arch::aarch64::gic::Vgic;
use log::{log_enabled, Level};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt::Debug;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestUsize};
/// Errors thrown while configuring aarch64 system.
@@ -32,7 +31,7 @@ pub enum Error {
WriteFdtToMemory(fdt::Error),
/// Failed to create a GIC.
SetupGic(gic::Error),
SetupGic,
/// Failed to compute the initramfs address.
InitramfsAddress,
@@ -142,7 +141,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: &gic::GicDevice,
gic_device: &Arc<Mutex<dyn Vgic>>,
numa_nodes: &NumaNodes,
pmu_supported: bool,
) -> super::Result<()> {
@@ -152,7 +151,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
vcpu_mpidr,
vcpu_topology,
device_info,
gic_device.get_vgic(),
gic_device,
initrd,
pci_space_info,
numa_nodes,