mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: hypervisor: Add a new interface to setup GICR for vcpus
For MSHV arm64 guest, there is an in-hypervisor GICv2M emulation and for that to work, it needs to be enlightened with the base address of GIC redistributor exposed to guest via FDT. Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
@@ -590,7 +590,13 @@ pub trait Vcpu: Send + Sync {
|
||||
fn set_sev_control_register(&self, _reg: u64) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
///
|
||||
/// Sets the value of GIC redistributor address
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn set_gic_redistributor_addr(&self, _gicr_base_addr: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Trigger NMI interrupt
|
||||
|
||||
@@ -1603,6 +1603,24 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
.request_virtual_interrupt(&cfg)
|
||||
.map_err(|e| cpu::HypervisorCpuError::Nmi(e.into()))
|
||||
}
|
||||
///
|
||||
/// Set the GICR base address for the vcpu.
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn set_gic_redistributor_addr(&self, gicr_base_addr: u64) -> cpu::Result<()> {
|
||||
debug!(
|
||||
"Setting GICR base address to: {:#x}, for vp_index: {:?}",
|
||||
gicr_base_addr, self.vp_index
|
||||
);
|
||||
let arr_reg_name_value = [(
|
||||
hv_register_name_HV_ARM64_REGISTER_GICR_BASE_GPA,
|
||||
gicr_base_addr,
|
||||
)];
|
||||
set_registers_64!(self.fd, arr_reg_name_value)
|
||||
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl MshvVcpu {
|
||||
|
||||
@@ -147,6 +147,10 @@ pub enum Error {
|
||||
#[error("Error finalising vCPU: {0}")]
|
||||
VcpuArmFinalize(#[source] hypervisor::HypervisorCpuError),
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[error("Error initialising GICR base address: {0}")]
|
||||
VcpuSetGicrBaseAddr(#[source] hypervisor::HypervisorCpuError),
|
||||
|
||||
#[error("Failed to join on vCPU threads: {0:?}")]
|
||||
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||
|
||||
@@ -463,6 +467,23 @@ impl Vcpu {
|
||||
.set_sev_control_register(vmsa_pfn)
|
||||
.map_err(Error::SetSevControlRegister)
|
||||
}
|
||||
|
||||
///
|
||||
/// Sets the vCPU's GIC redistributor base address.
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn set_gic_redistributor_addr(
|
||||
&self,
|
||||
base_redist_addr: u64,
|
||||
redist_size: u64,
|
||||
) -> Result<()> {
|
||||
let gicr_base = base_redist_addr + (arch::layout::GIC_V3_REDIST_SIZE * self.id as u64);
|
||||
assert!(gicr_base + arch::layout::GIC_V3_REDIST_SIZE <= base_redist_addr + redist_size);
|
||||
self.vcpu
|
||||
.set_gic_redistributor_addr(gicr_base)
|
||||
.map_err(Error::VcpuSetGicrBaseAddr)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Pausable for Vcpu {}
|
||||
|
||||
@@ -2203,6 +2203,21 @@ impl Vm {
|
||||
#[cfg(feature = "tdx")]
|
||||
let tdx_enabled = self.config.lock().unwrap().is_tdx_enabled();
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let vgic = self
|
||||
.device_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_interrupt_controller()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_vgic()
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
let redist_addr = vgic.lock().unwrap().device_properties();
|
||||
|
||||
// Configure the vcpus that have been created
|
||||
let vcpus = self.cpu_manager.lock().unwrap().vcpus();
|
||||
for vcpu in vcpus {
|
||||
@@ -2211,7 +2226,13 @@ impl Vm {
|
||||
self.cpu_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.configure_vcpu(vcpu, boot_setup)
|
||||
.configure_vcpu(vcpu.clone(), boot_setup)
|
||||
.map_err(Error::CpuManager)?;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
vcpu.lock()
|
||||
.unwrap()
|
||||
.set_gic_redistributor_addr(redist_addr[2], redist_addr[3])
|
||||
.map_err(Error::CpuManager)?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user