Skip to content

Commit

Permalink
Fixes KVM_CAP_ONE_REG is not supported on x86-64 (#1000)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed Sep 28, 2024
1 parent 80dde69 commit 165fd9d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/core/src/vmm/hv/linux/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<KvmOneReg<()>>(KVMIO, 0xab);
#[cfg(target_arch = "aarch64")]
pub const KVM_ARM_VCPU_INIT: c_ulong = _IOW::<KvmVcpuInit>(KVMIO, 0xae);
Expand All @@ -14,6 +15,7 @@ pub const KVM_ARM_PREFERRED_TARGET: c_ulong = _IOR::<KvmVcpuInit>(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;
Expand Down Expand Up @@ -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,
Expand Down
19 changes: 12 additions & 7 deletions src/core/src/vmm/hv/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -48,9 +47,15 @@ pub fn new(cpu: usize, ram: Ram) -> Result<impl Hypervisor, VmmError> {
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);
}

Expand Down Expand Up @@ -189,7 +194,7 @@ impl Hypervisor for Kvm {

#[cfg(target_arch = "aarch64")]
fn cpu_features(&mut self) -> Result<CpuFeats, Self::CpuErr> {
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;

Expand Down
2 changes: 1 addition & 1 deletion src/core/src/vmm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down

0 comments on commit 165fd9d

Please sign in to comment.