arch, vmm: Implement GIC Pausable trait

This commit implements the GIC (including both GICv3 and GICv3ITS)
Pausable trait. The pause of device manager will trigger a "pause"
of GIC, where we flush GIC pending tables and ITS tables to the
guest RAM.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
Henry Wang
2021-08-31 22:31:15 -04:00
committed by Rob Bradford
parent 7b80709595
commit 46c60183cd
3 changed files with 50 additions and 12 deletions
+10 -4
View File
@@ -109,9 +109,6 @@ pub mod kvm {
/// Save the state of GIC.
fn state(&self, gicr_typers: &[u64]) -> Result<Gicv3State> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(self.device()).map_err(Error::SavePendingTables)?;
let gicd_ctlr =
read_ctlr(self.device()).map_err(Error::SaveDistributorCtrlRegisters)?;
@@ -255,7 +252,16 @@ pub mod kvm {
}
}
impl Pausable for KvmGicV3 {}
impl Pausable for KvmGicV3 {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(self.device()).map_err(|e| {
MigratableError::Pause(anyhow!("Could not save GICv3 GIC pending tables {:?}", e))
})?;
Ok(())
}
}
impl Transportable for KvmGicV3 {}
impl Migratable for KvmGicV3 {}
}
+17 -8
View File
@@ -191,9 +191,6 @@ pub mod kvm {
/// Save the state of GICv3ITS.
fn state(&self, gicr_typers: &[u64]) -> Result<Gicv3ItsState> {
// Flush redistributors pending tables to guest RAM.
save_pending_tables(self.device()).map_err(Error::SavePendingTables)?;
let gicd_ctlr =
read_ctlr(self.device()).map_err(Error::SaveDistributorCtrlRegisters)?;
@@ -206,10 +203,6 @@ pub mod kvm {
let icc_state =
get_icc_regs(self.device(), gicr_typers).map_err(Error::SaveIccRegisters)?;
// Save GICv3ITS registers
gicv3_its_tables_access(self.its_device().unwrap(), true)
.map_err(Error::SaveITSTables)?;
let its_baser_state: [u64; 8] = [0; 8];
for i in 0..8 {
gicv3_its_attr_access(
@@ -501,7 +494,23 @@ pub mod kvm {
}
}
impl Pausable for KvmGicV3Its {}
impl Pausable for KvmGicV3Its {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
// Flush redistributors pending tables to guest RAM.
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(())
}
}
impl Transportable for KvmGicV3Its {}
impl Migratable for KvmGicV3Its {}
}