mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
device_manager: AArch64: add a field to set/get GIC device entity
In AArch64 systems, the state of GIC device can only be retrieved from `KVM_GET_DEVICE_ATTR` ioctl. Therefore to implement saving/restoring the GIC states, we need to make sure that the GIC object (either the file descriptor or the device itself) can be extracted after the VM is started. This commit refactors the code of GIC creation by adding a new field `gic_device_entity` in device manager and methods to set/get this field. The GIC object can be therefore saved in the device manager after calling `arch::configure_system`. Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
parent
e7acbcc184
commit
dcf6d9d731
@ -26,7 +26,7 @@ pub enum Error {
|
||||
}
|
||||
type Result<T> = result::Result<T, Error>;
|
||||
|
||||
pub trait GICDevice {
|
||||
pub trait GICDevice: Send {
|
||||
/// Returns the hypervisor agnostic Device of the GIC device
|
||||
fn device(&self) -> &Arc<dyn hypervisor::Device>;
|
||||
|
||||
|
@ -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<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::Bui
|
||||
device_info: &HashMap<(DeviceType, String), T, S>,
|
||||
initrd: &Option<super::InitramfsConfig>,
|
||||
pci_space_address: &Option<(u64, u64)>,
|
||||
) -> super::Result<()> {
|
||||
) -> super::Result<Box<dyn GICDevice>> {
|
||||
// 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<T: DeviceInfoForFDT + Clone + Debug, S: ::std::hash::Bui
|
||||
)
|
||||
.map_err(Error::SetupFDT)?;
|
||||
|
||||
Ok(())
|
||||
Ok(gic_device)
|
||||
}
|
||||
|
||||
/// Returns the memory address where the initramfs could be loaded.
|
||||
|
@ -27,6 +27,8 @@ 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::GICDevice;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use arch::aarch64::DeviceInfoForFDT;
|
||||
#[cfg(feature = "acpi")]
|
||||
use arch::layout;
|
||||
@ -727,6 +729,9 @@ pub struct DeviceManager {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
interrupt_controller: Option<Arc<Mutex<gic::Gic>>>,
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
gic_device_entity: Option<Arc<Mutex<Box<dyn GICDevice>>>>,
|
||||
|
||||
// Things to be added to the commandline (i.e. for virtio-mmio)
|
||||
cmdline_additions: Vec<String>,
|
||||
|
||||
@ -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<Mutex<Box<dyn GICDevice>>>) {
|
||||
self.gic_device_entity = Some(device_entity);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn get_gic_device_entity(&self) -> Option<&Arc<Mutex<Box<dyn GICDevice>>>> {
|
||||
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 {
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user