diff --git a/src/core/src/vmm/hv/linux/ffi.rs b/src/core/src/vmm/hv/linux/ffi.rs index 286bfb0a..867e6647 100644 --- a/src/core/src/vmm/hv/linux/ffi.rs +++ b/src/core/src/vmm/hv/linux/ffi.rs @@ -5,6 +5,7 @@ pub const KVM_CREATE_VM: c_ulong = _IO(KVMIO, 0x01); pub const KVM_CHECK_EXTENSION: c_ulong = _IO(KVMIO, 0x03); pub const KVM_GET_VCPU_MMAP_SIZE: c_ulong = _IO(KVMIO, 0x04); pub const KVM_CREATE_VCPU: c_ulong = _IO(KVMIO, 0x41); +#[cfg(target_arch = "aarch64")] pub const KVM_GET_ONE_REG: c_ulong = _IOW::>(KVMIO, 0xab); #[cfg(target_arch = "aarch64")] pub const KVM_ARM_VCPU_INIT: c_ulong = _IOW::(KVMIO, 0xae); @@ -14,6 +15,7 @@ pub const KVM_ARM_PREFERRED_TARGET: c_ulong = _IOR::(KVMIO, 0xaf); pub const KVM_API_VERSION: c_int = 12; pub const KVM_CAP_MAX_VCPUS: c_int = 66; +#[cfg(target_arch = "aarch64")] pub const KVM_CAP_ONE_REG: c_int = 70; #[cfg(target_arch = "aarch64")] pub const KVM_CAP_ARM_VM_IPA_SIZE: c_int = 165; @@ -74,6 +76,7 @@ const fn _IOC(dir: c_ulong, ty: c_ulong, nr: c_ulong, size: c_ulong) -> c_ulong | (size << _IOC_SIZESHIFT) } +#[cfg(target_arch = "aarch64")] #[repr(C)] pub struct KvmOneReg<'a, T> { pub id: u64, diff --git a/src/core/src/vmm/hv/linux/mod.rs b/src/core/src/vmm/hv/linux/mod.rs index 9e4df296..a23eecb7 100644 --- a/src/core/src/vmm/hv/linux/mod.rs +++ b/src/core/src/vmm/hv/linux/mod.rs @@ -1,9 +1,8 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use self::cpu::KvmCpu; use self::ffi::{ - kvm_set_user_memory_region, KvmOneReg, KVM_API_VERSION, KVM_CAP_MAX_VCPUS, KVM_CAP_ONE_REG, - KVM_CHECK_EXTENSION, KVM_CREATE_VCPU, KVM_CREATE_VM, KVM_GET_API_VERSION, KVM_GET_ONE_REG, - KVM_GET_VCPU_MMAP_SIZE, + kvm_set_user_memory_region, KVM_API_VERSION, KVM_CAP_MAX_VCPUS, KVM_CHECK_EXTENSION, + KVM_CREATE_VCPU, KVM_CREATE_VM, KVM_GET_API_VERSION, KVM_GET_VCPU_MMAP_SIZE, }; use super::{CpuFeats, Hypervisor}; use crate::vmm::ram::Ram; @@ -48,9 +47,15 @@ pub fn new(cpu: usize, ram: Ram) -> Result { return Err(VmmError::MaxCpuTooLow); } - // Check KVM_CAP_ONE_REG. KVM_SET_ONE_REG and KVM_GET_ONE_REG are the only API that support all - // architectures. - if unsafe { ioctl(kvm.as_raw_fd(), KVM_CHECK_EXTENSION, KVM_CAP_ONE_REG) <= 0 } { + // On AArch64 we need KVM_SET_ONE_REG and KVM_GET_ONE_REG. + #[cfg(target_arch = "aarch64")] + if unsafe { + ioctl( + kvm.as_raw_fd(), + KVM_CHECK_EXTENSION, + self::ffi::KVM_CAP_ONE_REG, + ) <= 0 + } { return Err(VmmError::NoKvmOneReg); } @@ -189,7 +194,7 @@ impl Hypervisor for Kvm { #[cfg(target_arch = "aarch64")] fn cpu_features(&mut self) -> Result { - use self::ffi::ARM64_SYS_REG; + use self::ffi::{KvmOneReg, ARM64_SYS_REG, KVM_GET_ONE_REG}; use crate::vmm::hv::{Mmfr0, Mmfr1, Mmfr2}; use std::arch::asm; diff --git a/src/core/src/vmm/mod.rs b/src/core/src/vmm/mod.rs index 964f7466..7e06bb37 100644 --- a/src/core/src/vmm/mod.rs +++ b/src/core/src/vmm/mod.rs @@ -698,7 +698,7 @@ enum VmmError { #[error("unexpected KVM version")] KvmVersionMismatched, - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", target_arch = "aarch64"))] #[error("your OS does not support KVM_CAP_ONE_REG")] NoKvmOneReg,