From 2798286278447d54e942665d9b188bb051d33ef0 Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Tue, 1 Apr 2025 13:02:45 +0000 Subject: [PATCH] hypervisor: Add GICv2M support for MSHV ARM64 guest MSHV does not emulate a GICv3-ITS for guests to support MSI interrupts, instead it exposes a GICv2m device. Currently adding a skeleton code which would be modified later on with complete implementation. With this we can start compiling cloud-hypervisor for MSHV on ARM64. This will make sure that we don't regress in future in terms of basic compilation test. Signed-off-by: Jinank Jain --- hypervisor/src/arch/aarch64/gic.rs | 6 ++ hypervisor/src/kvm/aarch64/gic/mod.rs | 3 + hypervisor/src/mshv/aarch64/gic/mod.rs | 124 +++++++++++++++++++++++++ hypervisor/src/mshv/aarch64/mod.rs | 1 + 4 files changed, 134 insertions(+) create mode 100644 hypervisor/src/mshv/aarch64/gic/mod.rs diff --git a/hypervisor/src/arch/aarch64/gic.rs b/hypervisor/src/arch/aarch64/gic.rs index 20aad9807..9e2b39bb1 100644 --- a/hypervisor/src/arch/aarch64/gic.rs +++ b/hypervisor/src/arch/aarch64/gic.rs @@ -43,6 +43,8 @@ pub struct VgicConfig { pub enum GicState { #[cfg(feature = "kvm")] Kvm(crate::kvm::aarch64::gic::Gicv3ItsState), + #[cfg(feature = "mshv")] + MshvGicV2M(crate::mshv::aarch64::gic::MshvGicV2MState), } impl<'de> Deserialize<'de> for GicState { @@ -56,6 +58,8 @@ impl<'de> Deserialize<'de> for GicState { pub enum GicStateDefaultDeserialize { #[cfg(feature = "kvm")] Kvm(crate::kvm::aarch64::gic::Gicv3ItsState), + #[cfg(feature = "mshv")] + MshvGicV2M(crate::mshv::aarch64::gic::MshvGicV2MState), } const { @@ -78,6 +82,8 @@ impl<'de> Deserialize<'de> for GicState { return match gic_state_de { #[cfg(feature = "kvm")] GicStateDefaultDeserialize::Kvm(state) => Ok(GicState::Kvm(state)), + #[cfg(feature = "mshv")] + GicStateDefaultDeserialize::MshvGicV2M(state) => Ok(GicState::MshvGicV2M(state)), }; } Err(SerdeError::custom("Failed to deserialize GicState")) diff --git a/hypervisor/src/kvm/aarch64/gic/mod.rs b/hypervisor/src/kvm/aarch64/gic/mod.rs index 7df2b50b4..cf4619bd7 100644 --- a/hypervisor/src/kvm/aarch64/gic/mod.rs +++ b/hypervisor/src/kvm/aarch64/gic/mod.rs @@ -129,6 +129,9 @@ impl From for Gicv3ItsState { fn from(state: GicState) -> Self { match state { GicState::Kvm(state) => state, + /* Needed in case other hypervisors are enabled */ + #[allow(unreachable_patterns)] + _ => panic!("GicState is not valid"), } } } diff --git a/hypervisor/src/mshv/aarch64/gic/mod.rs b/hypervisor/src/mshv/aarch64/gic/mod.rs new file mode 100644 index 000000000..e904affb1 --- /dev/null +++ b/hypervisor/src/mshv/aarch64/gic/mod.rs @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +// +// Copyright © 2025, Microsoft Corporation +// +use std::any::Any; + +use serde::{Deserialize, Serialize}; + +use crate::arch::aarch64::gic::{GicState, Result, Vgic, VgicConfig}; +use crate::{CpuState, Vm}; + +pub struct MshvGicV2M { + /// GIC distributor address + pub dist_addr: u64, + + /// GIC distributor size + pub dist_size: u64, + + /// GIC re-distributors address + pub redists_addr: u64, + + /// GIC re-distributors size + pub redists_size: u64, + + /// GITS translator address + pub gits_addr: u64, + + /// GITS translator size + pub gits_size: u64, + + /// Number of CPUs handled by the device + pub vcpu_count: u64, +} + +#[derive(Clone, Default, Serialize, Deserialize)] +pub struct MshvGicV2MState {} + +impl From for MshvGicV2MState { + fn from(state: GicState) -> Self { + match state { + GicState::MshvGicV2M(state) => state, + /* Needed in case other hypervisors are enabled */ + #[allow(unreachable_patterns)] + _ => panic!("GicState is not valid"), + } + } +} + +impl From for GicState { + fn from(state: MshvGicV2MState) -> Self { + GicState::MshvGicV2M(state) + } +} + +impl MshvGicV2M { + /// Create a new GICv2m device + pub fn new(_vm: &dyn Vm, config: VgicConfig) -> Result { + let gic_device = MshvGicV2M { + dist_addr: config.dist_addr, + dist_size: config.dist_size, + redists_addr: config.redists_addr, + redists_size: config.redists_size, + gits_addr: config.msi_addr, + gits_size: config.msi_size, + vcpu_count: config.vcpu_count, + }; + Ok(gic_device) + } +} + +impl Vgic for MshvGicV2M { + fn fdt_compatibility(&self) -> &str { + "arm,gic-v3" + } + + fn msi_compatible(&self) -> bool { + true + } + + fn msi_compatibility(&self) -> &str { + "arm,gic-v2m-frame" + } + + fn fdt_maint_irq(&self) -> u32 { + 0 + } + + fn vcpu_count(&self) -> u64 { + self.vcpu_count + } + + fn msi_properties(&self) -> [u64; 2] { + [self.gits_addr, self.gits_size] + } + + fn device_properties(&self) -> [u64; 4] { + [ + self.dist_addr, + self.dist_size, + self.redists_addr, + self.redists_size, + ] + } + + fn set_gicr_typers(&mut self, _vcpu_states: &[CpuState]) { + unimplemented!() + } + + fn state(&self) -> Result { + unimplemented!() + } + + fn as_any_concrete_mut(&mut self) -> &mut dyn Any { + self + } + + fn set_state(&mut self, _state: &GicState) -> Result<()> { + unimplemented!() + } + + fn save_data_tables(&self) -> Result<()> { + unimplemented!() + } +} diff --git a/hypervisor/src/mshv/aarch64/mod.rs b/hypervisor/src/mshv/aarch64/mod.rs index 4634643c9..79da40738 100644 --- a/hypervisor/src/mshv/aarch64/mod.rs +++ b/hypervisor/src/mshv/aarch64/mod.rs @@ -2,6 +2,7 @@ // // Copyright © 2025, Microsoft Corporation // +pub mod gic; use std::fmt; ///