mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
@@ -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)?;
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user