diff options
-rw-r--r-- | src/cap.rs | 34 | ||||
-rw-r--r-- | src/kvm.rs | 23 | ||||
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | sysdeps/kvm.c | 26 |
4 files changed, 84 insertions, 2 deletions
diff --git a/src/cap.rs b/src/cap.rs new file mode 100644 index 0000000..672ca75 --- /dev/null +++ b/src/cap.rs @@ -0,0 +1,34 @@ +//! Definitions of KVM capabilities. + +use crate::kvm_sys; +use std::convert::Into; + +/// Definition of capabilities that return a bool value indicating whether the capability is +/// supported or not. +#[repr(u64)] +pub enum CapBool { + /// Check if capabilities can be queried on VM fds (`KVM_CAP_CHECK_EXTENSION_VM`). + CheckExtensionVm = kvm_sys::KVM_CAP_CHECK_EXTENSION_VM, +} + +impl Into<u64> for CapBool { + fn into(self) -> u64 { + self as u64 + } +} + +/// Definition of capabilities that return an integer value indicating the amount of the queried +/// capability. +#[repr(u64)] +pub enum CapInt { + /// Get the recommended max VPCUs (`KVM_CAP_NR_VCPUS`). + NrVcpus = kvm_sys::KVM_CAP_NR_VCPUS, + /// Get the possible max VPCUs (`KVM_CAP_MAX_VCPUS`). + MaxVcpus = kvm_sys::KVM_CAP_MAX_VCPUS, +} + +impl Into<u64> for CapInt { + fn into(self) -> u64 { + self as u64 + } +} @@ -4,8 +4,9 @@ use std::fs; use std::io; use std::os::unix::io::FromRawFd; -use crate::{libcret, ioctl, kvm_sys}; +use crate::cap::{CapBool, CapInt}; use crate::vm::Vm; +use crate::{ioctl, kvm_sys, libcret}; /// Wrapper for `/dev/kvm` ioctls. /// @@ -49,4 +50,24 @@ impl Kvm { Ok(Vm::new(vm, vcpu_mmap_size)) } + + /// Check availability of an extension with the [`KVM_CHECK_EXTENSION`][kvm-check-extension] + /// ioctl. + /// + /// [kvm-check-extension]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-check-extension + pub fn check_extenstion(&self, cap: CapBool) -> bool { + let ret = ioctl(&self.kvm, kvm_sys::KVM_CHECK_EXTENSION, cap.into()); + + matches!(ret, Ok(ret) if ret > 0) + } + + /// Check availability of an extension with the [`KVM_CHECK_EXTENSION`][kvm-check-extension] + /// ioctl. + /// + /// [kvm-check-extension]: https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-check-extension + pub fn check_extenstion_int(&self, cap: CapInt) -> i32 { + let ret = ioctl(&self.kvm, kvm_sys::KVM_CHECK_EXTENSION, cap.into()); + + ret.unwrap_or(0) + } } @@ -3,6 +3,7 @@ use std::io; use std::ops; use std::os::unix::io::AsRawFd; +pub mod cap; mod fmt; pub mod kvm; pub mod kvm_sys; @@ -154,7 +155,7 @@ impl ops::Drop for KvmRun { impl AsRef<kvm_sys::kvm_run> for KvmRun { fn as_ref(&self) -> &kvm_sys::kvm_run { - unsafe { & *(self.ptr as *const kvm_sys::kvm_run) } + unsafe { &*(self.ptr as *const kvm_sys::kvm_run) } } } diff --git a/sysdeps/kvm.c b/sysdeps/kvm.c index 1665349..f7ff1a4 100644 --- a/sysdeps/kvm.c +++ b/sysdeps/kvm.c @@ -56,6 +56,32 @@ int main() { printf("pub(crate) const KVM_EXIT_IO_OUT : u64 = 0x%x;\n", KVM_EXIT_IO_OUT); printf("pub(crate) const KVM_EXIT_MMIO : u64 = 0x%x;\n", KVM_EXIT_MMIO); + /* Capabilities */ + + // Can be used on /dev/kvm fd and VM fd (if KVM_CAP_CHECK_EXTENSION_VM is available). + // + // param: capability to query KVM_CAP_* + // ret : 0 unsupported, 1 supported (some return >=1 returning number for cap) + printf("pub(crate) const KVM_CHECK_EXTENSION : u64 = 0x%x;\n", KVM_CHECK_EXTENSION); + + /* Bool Capabilities */ + + // Check if capabilities can be checked in VM fd. + // + // ret: 0 unsupported, 1 supported + printf("pub(crate) const KVM_CAP_CHECK_EXTENSION_VM : u64 = 0x%x;\n", KVM_CAP_CHECK_EXTENSION_VM); + + /* Int Capabilities */ + + // Check the recommended max amount of VCPUs. + // + // ret: 0 unsupported, >0 #vcpus + printf("pub(crate) const KVM_CAP_NR_VCPUS : u64 = 0x%x;\n", KVM_CAP_NR_VCPUS); + // Check the possible max amount of VCPUs. + // + // ret: 0 unsupported, >0 #vcpus + printf("pub(crate) const KVM_CAP_MAX_VCPUS : u64 = 0x%x;\n", KVM_CAP_MAX_VCPUS); + /* Testing constants */ printf("#[cfg(test)] const TEST_KVM_REGS_SIZE : usize = %ld;\n", sizeof(struct kvm_regs)); |