mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 03:12:27 +00:00
hypervisor: Implement hypervisor agnostic variant of VcpuInit
This will help in fixing the build issue for MSHV on ARM64. Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
parent
ee0b0d43d8
commit
5b929cb277
@ -14,14 +14,14 @@ use thiserror::Error;
|
||||
#[cfg(not(target_arch = "riscv64"))]
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::aarch64::VcpuInit;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
||||
#[cfg(feature = "tdx")]
|
||||
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
use crate::RegList;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::VcpuInit;
|
||||
use crate::{CpuState, MpState, StandardRegisters};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
pub mod gic;
|
||||
|
||||
pub use kvm_bindings::kvm_vcpu_init as VcpuInit;
|
||||
use kvm_bindings::{
|
||||
kvm_mp_state, kvm_one_reg, kvm_regs, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_CORE,
|
||||
KVM_REG_SIZE_MASK, KVM_REG_SIZE_U32, KVM_REG_SIZE_U64,
|
||||
|
@ -30,8 +30,7 @@ use vmm_sys_util::eventfd::EventFd;
|
||||
use crate::aarch64::gic::KvmGicV3Its;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use crate::aarch64::{
|
||||
check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuInit,
|
||||
VcpuKvmState,
|
||||
check_required_kvm_extensions, gic::Gicv3ItsState as GicState, is_system_register, VcpuKvmState,
|
||||
};
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
||||
@ -369,6 +368,25 @@ impl From<crate::Register> for kvm_bindings::kvm_one_reg {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
impl From<kvm_bindings::kvm_vcpu_init> for crate::VcpuInit {
|
||||
fn from(s: kvm_bindings::kvm_vcpu_init) -> Self {
|
||||
crate::VcpuInit::Kvm(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
impl From<crate::VcpuInit> for kvm_bindings::kvm_vcpu_init {
|
||||
fn from(e: crate::VcpuInit) -> Self {
|
||||
match e {
|
||||
crate::VcpuInit::Kvm(e) => e,
|
||||
/* Needed in case other hypervisors are enabled */
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => panic!("VcpuInit is not valid"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
impl From<kvm_bindings::RegList> for crate::RegList {
|
||||
fn from(s: kvm_bindings::RegList) -> Self {
|
||||
@ -789,10 +807,13 @@ impl vm::Vm for KvmVm {
|
||||
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> vm::Result<()> {
|
||||
fn get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> vm::Result<()> {
|
||||
let mut kvm_kvi: kvm_bindings::kvm_vcpu_init = (*kvi).into();
|
||||
self.fd
|
||||
.get_preferred_target(kvi)
|
||||
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))
|
||||
.get_preferred_target(&mut kvm_kvi)
|
||||
.map_err(|e| vm::HypervisorVmError::GetPreferredTarget(e.into()))?;
|
||||
*kvi = kvm_kvi.into();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -2637,11 +2658,12 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn vcpu_init(&self, kvi: &VcpuInit) -> cpu::Result<()> {
|
||||
fn vcpu_init(&self, kvi: &crate::VcpuInit) -> cpu::Result<()> {
|
||||
let kvm_kvi: kvm_bindings::kvm_vcpu_init = (*kvi).into();
|
||||
self.fd
|
||||
.lock()
|
||||
.unwrap()
|
||||
.vcpu_init(kvi)
|
||||
.vcpu_init(&kvm_kvi)
|
||||
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
|
||||
}
|
||||
|
||||
|
@ -196,6 +196,12 @@ pub enum IrqRoutingEntry {
|
||||
Mshv(mshv_bindings::mshv_user_irq_entry),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum VcpuInit {
|
||||
#[cfg(all(feature = "kvm", target_arch = "aarch64"))]
|
||||
Kvm(kvm_bindings::kvm_vcpu_init),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum RegList {
|
||||
#[cfg(all(feature = "kvm", any(target_arch = "aarch64", target_arch = "riscv64")))]
|
||||
|
@ -22,8 +22,6 @@ use igvm_defs::IGVM_VHS_SNP_ID_BLOCK;
|
||||
use thiserror::Error;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::aarch64::VcpuInit;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::arch::aarch64::gic::{Vgic, VgicConfig};
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
@ -351,7 +349,7 @@ pub trait Vm: Send + Sync + Any {
|
||||
fn remove_user_memory_region(&self, user_memory_region: UserMemoryRegion) -> Result<()>;
|
||||
/// Returns the preferred CPU target type which can be emulated by KVM on underlying host.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn get_preferred_target(&self, kvi: &mut VcpuInit) -> Result<()>;
|
||||
fn get_preferred_target(&self, kvi: &mut crate::VcpuInit) -> Result<()>;
|
||||
/// Enable split Irq capability
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn enable_split_irq(&self) -> Result<()>;
|
||||
|
@ -427,7 +427,7 @@ impl Vcpu {
|
||||
let sve_supported =
|
||||
is_aarch64_feature_detected!("sve") || is_aarch64_feature_detected!("sve2");
|
||||
// This reads back the kernel's preferred target type.
|
||||
vm.get_preferred_target(&mut kvi)
|
||||
vm.get_preferred_target(&mut kvi.into())
|
||||
.map_err(Error::VcpuArmPreferredTarget)?;
|
||||
// We already checked that the capability is supported.
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
|
||||
@ -454,7 +454,9 @@ impl Vcpu {
|
||||
if self.id > 0 {
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
||||
}
|
||||
self.vcpu.vcpu_init(&kvi).map_err(Error::VcpuArmInit)?;
|
||||
self.vcpu
|
||||
.vcpu_init(&kvi.into())
|
||||
.map_err(Error::VcpuArmInit)?;
|
||||
if sve_supported {
|
||||
self.vcpu
|
||||
.vcpu_finalize(kvm_bindings::KVM_ARM_VCPU_SVE as i32)
|
||||
@ -2965,8 +2967,8 @@ mod tests {
|
||||
vcpu.setup_regs(0, 0x0, layout::FDT_START.0).unwrap_err();
|
||||
|
||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
||||
vm.get_preferred_target(&mut kvi).unwrap();
|
||||
vcpu.vcpu_init(&kvi).unwrap();
|
||||
vm.get_preferred_target(&mut kvi.into()).unwrap();
|
||||
vcpu.vcpu_init(&kvi.into()).unwrap();
|
||||
|
||||
vcpu.setup_regs(0, 0x0, layout::FDT_START.0).unwrap();
|
||||
}
|
||||
@ -2977,12 +2979,12 @@ mod tests {
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
||||
vm.get_preferred_target(&mut kvi).unwrap();
|
||||
vm.get_preferred_target(&mut kvi.into()).unwrap();
|
||||
|
||||
// Must fail when vcpu is not initialized yet.
|
||||
vcpu.get_sys_reg(regs::MPIDR_EL1).unwrap_err();
|
||||
|
||||
vcpu.vcpu_init(&kvi).unwrap();
|
||||
vcpu.vcpu_init(&kvi.into()).unwrap();
|
||||
assert_eq!(vcpu.get_sys_reg(regs::MPIDR_EL1).unwrap(), 0x80000000);
|
||||
}
|
||||
|
||||
@ -3001,7 +3003,7 @@ mod tests {
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
||||
vm.get_preferred_target(&mut kvi).unwrap();
|
||||
vm.get_preferred_target(&mut kvi.into()).unwrap();
|
||||
|
||||
// Must fail when vcpu is not initialized yet.
|
||||
assert_eq!(
|
||||
@ -3015,7 +3017,7 @@ mod tests {
|
||||
"Failed to set aarch64 core register: Exec format error (os error 8)"
|
||||
);
|
||||
|
||||
vcpu.vcpu_init(&kvi).unwrap();
|
||||
vcpu.vcpu_init(&kvi.into()).unwrap();
|
||||
state = vcpu.get_regs().unwrap();
|
||||
assert_eq!(state.get_pstate(), 0x3C5);
|
||||
|
||||
@ -3028,7 +3030,7 @@ mod tests {
|
||||
let vm = hv.create_vm().unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let mut kvi: kvm_vcpu_init = kvm_vcpu_init::default();
|
||||
vm.get_preferred_target(&mut kvi).unwrap();
|
||||
vm.get_preferred_target(&mut kvi.into()).unwrap();
|
||||
|
||||
let state = vcpu.get_mp_state().unwrap();
|
||||
vcpu.set_mp_state(state).unwrap();
|
||||
|
Loading…
x
Reference in New Issue
Block a user