mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
vmm: Add support for enabling SVE in vm guests
This change enables SVE automatically if the host support SVE/SVE2. Signed-off-by: Wenyu Huang <huangwenyuu@outlook.com>
This commit is contained in:
parent
2049b2c377
commit
d2a364c5c0
@ -158,6 +158,11 @@ pub enum HypervisorCpuError {
|
||||
#[error("Failed to init vcpu: {0}")]
|
||||
VcpuInit(#[source] anyhow::Error),
|
||||
///
|
||||
/// Vcpu Finalize error
|
||||
///
|
||||
#[error("Failed to finalize vcpu: {0}")]
|
||||
VcpuFinalize(#[source] anyhow::Error),
|
||||
///
|
||||
/// Setting one reg error
|
||||
///
|
||||
#[error("Failed to init vcpu: {0}")]
|
||||
@ -416,6 +421,10 @@ pub trait Vcpu: Send + Sync {
|
||||
///
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn vcpu_init(&self, kvi: &VcpuInit) -> Result<()>;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn vcpu_finalize(&self, feature: i32) -> Result<()>;
|
||||
|
||||
///
|
||||
/// Gets a list of the guest registers that are supported for the
|
||||
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
||||
|
@ -1881,6 +1881,15 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
.map_err(|e| cpu::HypervisorCpuError::VcpuInit(e.into()))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn vcpu_finalize(&self, feature: i32) -> cpu::Result<()> {
|
||||
self.fd
|
||||
.lock()
|
||||
.unwrap()
|
||||
.vcpu_finalize(&feature)
|
||||
.map_err(|e| cpu::HypervisorCpuError::VcpuFinalize(e.into()))
|
||||
}
|
||||
|
||||
///
|
||||
/// Gets a list of the guest registers that are supported for the
|
||||
/// KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
|
||||
|
@ -140,6 +140,10 @@ pub enum Error {
|
||||
#[error("Error initialising vCPU: {0}")]
|
||||
VcpuArmInit(#[source] hypervisor::HypervisorCpuError),
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[error("Error finalising vCPU: {0}")]
|
||||
VcpuArmFinalize(#[source] hypervisor::HypervisorCpuError),
|
||||
|
||||
#[error("Failed to join on vCPU threads: {0:?}")]
|
||||
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||
|
||||
@ -415,8 +419,10 @@ impl Vcpu {
|
||||
/// Initializes an aarch64 specific vcpu for booting Linux.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn init(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
|
||||
use std::arch::is_aarch64_feature_detected;
|
||||
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
|
||||
|
||||
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)
|
||||
.map_err(Error::VcpuArmPreferredTarget)?;
|
||||
@ -430,11 +436,28 @@ impl Vcpu {
|
||||
{
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
|
||||
}
|
||||
|
||||
if sve_supported
|
||||
&& vm
|
||||
.as_any()
|
||||
.downcast_ref::<hypervisor::kvm::KvmVm>()
|
||||
.unwrap()
|
||||
.check_extension(Cap::ArmSve)
|
||||
{
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_SVE;
|
||||
}
|
||||
|
||||
// Non-boot cpus are powered off initially.
|
||||
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).map_err(Error::VcpuArmInit)?;
|
||||
if sve_supported {
|
||||
self.vcpu
|
||||
.vcpu_finalize(kvm_bindings::KVM_ARM_VCPU_SVE as i32)
|
||||
.map_err(Error::VcpuArmFinalize)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Runs the VCPU until it exits, returning the reason.
|
||||
|
@ -427,12 +427,14 @@ fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>
|
||||
const KVM_ARM_PREFERRED_TARGET: u64 = 0x8020_aeaf;
|
||||
const KVM_ARM_VCPU_INIT: u64 = 0x4020_aeae;
|
||||
const KVM_SET_GUEST_DEBUG: u64 = 0x4208_ae9b;
|
||||
const KVM_ARM_VCPU_FINALIZE: u64 = 0x4004_aec2;
|
||||
|
||||
let common_rules = create_vmm_ioctl_seccomp_rule_common(HypervisorType::Kvm)?;
|
||||
let mut arch_rules = or![
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_PREFERRED_TARGET,)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_VCPU_INIT,)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_GUEST_DEBUG,)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_VCPU_FINALIZE,)?],
|
||||
];
|
||||
arch_rules.extend(common_rules);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user