Struct kvm_ioctls::Kvm
source · pub struct Kvm { /* private fields */ }
Expand description
Wrapper over KVM system ioctls.
Implementations§
source§impl Kvm
impl Kvm
sourcepub fn new() -> Result<Self, Error>
pub fn new() -> Result<Self, Error>
Opens /dev/kvm
and returns a Kvm
object on success.
Example
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
sourcepub fn new_with_path<P>(kvm_path: P) -> Result<Self, Error>
pub fn new_with_path<P>(kvm_path: P) -> Result<Self, Error>
sourcepub fn open_with_cloexec(close_on_exec: bool) -> Result<RawFd, Error>
pub fn open_with_cloexec(close_on_exec: bool) -> Result<RawFd, Error>
Opens /dev/kvm
and returns the fd number on success.
One usecase for this method is opening /dev/kvm
before exec-ing into a
process with seccomp filters enabled that blacklist the sys_open
syscall.
For this usecase open_with_cloexec
must be called with the close_on_exec
parameter set to false.
Arguments
close_on_exec
: If true opens/dev/kvm
using theO_CLOEXEC
flag.
Example
let kvm_fd = Kvm::open_with_cloexec(false).unwrap();
// The `kvm_fd` can now be passed to another process where we can use
// `from_raw_fd` for creating a `Kvm` object:
let kvm = unsafe { Kvm::from_raw_fd(kvm_fd) };
sourcepub fn open_with_cloexec_at<P>(
path: P,
close_on_exec: bool
) -> Result<RawFd, Error>
pub fn open_with_cloexec_at<P>( path: P, close_on_exec: bool ) -> Result<RawFd, Error>
Opens the KVM device at kvm_path
and returns the fd number on success.
Same as open_with_cloexec()
except this method opens kvm_path
instead of /dev/kvm
.
Arguments
kvm_path
: path to the KVM device. Usually it is/dev/kvm
.close_on_exec
: If true openskvm_path
using theO_CLOEXEC
flag.
Example
let kvm_path = CString::new("/dev/kvm").unwrap();
let kvm_fd = Kvm::open_with_cloexec_at(kvm_path, false).unwrap();
// The `kvm_fd` can now be passed to another process where we can use
// `from_raw_fd` for creating a `Kvm` object:
let kvm = unsafe { Kvm::from_raw_fd(kvm_fd) };
sourcepub fn get_api_version(&self) -> i32
pub fn get_api_version(&self) -> i32
Returns the KVM API version.
See the documentation for KVM_GET_API_VERSION
.
Example
let kvm = Kvm::new().unwrap();
assert_eq!(kvm.get_api_version(), 12);
sourcepub fn check_extension_raw(&self, c: c_ulong) -> i32
pub fn check_extension_raw(&self, c: c_ulong) -> i32
Wrapper over KVM_CHECK_EXTENSION
.
Returns 0 if the capability is not available and a positive integer otherwise.
See the documentation for KVM_CHECK_EXTENSION
.
Arguments
c
- KVM capability to check in a form of a raw integer.
Example
use kvm_ioctls::Cap;
let kvm = Kvm::new().unwrap();
assert!(kvm.check_extension_raw(Cap::MaxVcpuId as c_ulong) > 0);
sourcepub fn check_extension_int(&self, c: Cap) -> i32
pub fn check_extension_int(&self, c: Cap) -> i32
Wrapper over KVM_CHECK_EXTENSION
.
Returns 0 if the capability is not available and a positive integer otherwise.
See the documentation for KVM_CHECK_EXTENSION
.
Arguments
c
- KVM capability to check.
Example
use kvm_ioctls::Cap;
let kvm = Kvm::new().unwrap();
assert!(kvm.check_extension_int(Cap::MaxVcpuId) > 0);
sourcepub fn check_extension(&self, c: Cap) -> bool
pub fn check_extension(&self, c: Cap) -> bool
Checks if a particular Cap
is available.
Returns true if the capability is supported and false otherwise.
See the documentation for KVM_CHECK_EXTENSION
.
Arguments
c
- KVM capability to check.
Example
use kvm_ioctls::Cap;
let kvm = Kvm::new().unwrap();
// Check if `KVM_CAP_USER_MEMORY` is supported.
assert!(kvm.check_extension(Cap::UserMemory));
sourcepub fn get_vcpu_mmap_size(&self) -> Result<usize, Error>
pub fn get_vcpu_mmap_size(&self) -> Result<usize, Error>
Returns the size of the memory mapping required to use the vcpu’s kvm_run
structure.
See the documentation for KVM_GET_VCPU_MMAP_SIZE
.
Example
let kvm = Kvm::new().unwrap();
assert!(kvm.get_vcpu_mmap_size().unwrap() > 0);
sourcepub fn get_nr_vcpus(&self) -> usize
pub fn get_nr_vcpus(&self) -> usize
Gets the recommended number of VCPUs per VM.
See the documentation for KVM_CAP_NR_VCPUS
.
Default to 4 when KVM_CAP_NR_VCPUS
is not implemented.
Example
let kvm = Kvm::new().unwrap();
// We expect the number of vCPUs to be > 0 as per KVM API documentation.
assert!(kvm.get_nr_vcpus() > 0);
sourcepub fn get_nr_memslots(&self) -> usize
pub fn get_nr_memslots(&self) -> usize
Returns the maximum allowed memory slots per VM.
KVM reports the number of available memory slots (KVM_CAP_NR_MEMSLOTS
)
using the extension interface. Both x86 and s390 implement this, ARM
and powerpc do not yet enable it.
Default to 32 when KVM_CAP_NR_MEMSLOTS
is not implemented.
Example
let kvm = Kvm::new().unwrap();
assert!(kvm.get_nr_memslots() > 0);
sourcepub fn get_max_vcpus(&self) -> usize
pub fn get_max_vcpus(&self) -> usize
Gets the recommended maximum number of VCPUs per VM.
See the documentation for KVM_CAP_MAX_VCPUS
.
Returns get_nr_vcpus() when
KVM_CAP_MAX_VCPUS
is not implemented.
Example
let kvm = Kvm::new().unwrap();
assert!(kvm.get_max_vcpus() > 0);
sourcepub fn get_max_vcpu_id(&self) -> usize
pub fn get_max_vcpu_id(&self) -> usize
Gets the Maximum VCPU ID per VM.
See the documentation for KVM_CAP_MAX_VCPU_ID
Returns get_max_vcpus() when
KVM_CAP_MAX_VCPU_ID
is not implemented
Example
let kvm = Kvm::new().unwrap();
assert!(kvm.get_max_vcpu_id() > 0);
sourcepub fn get_emulated_cpuid(&self, num_entries: usize) -> Result<CpuId, Error>
pub fn get_emulated_cpuid(&self, num_entries: usize) -> Result<CpuId, Error>
X86 specific call to get the system emulated CPUID values.
See the documentation for KVM_GET_EMULATED_CPUID
.
Arguments
num_entries
- Maximum number of CPUID entries. This function can return less than this when the hardware does not support so many CPUID entries.
Returns Error errno::Error(libc::ENOMEM)
when the input num_entries
is greater than
KVM_MAX_CPUID_ENTRIES
.
Example
extern crate kvm_bindings;
use kvm_bindings::KVM_MAX_CPUID_ENTRIES;
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
let mut cpuid = kvm.get_emulated_cpuid(KVM_MAX_CPUID_ENTRIES).unwrap();
let cpuid_entries = cpuid.as_mut_slice();
assert!(cpuid_entries.len() <= KVM_MAX_CPUID_ENTRIES);
sourcepub fn get_supported_cpuid(&self, num_entries: usize) -> Result<CpuId, Error>
pub fn get_supported_cpuid(&self, num_entries: usize) -> Result<CpuId, Error>
X86 specific call to get the system supported CPUID values.
See the documentation for KVM_GET_SUPPORTED_CPUID
.
Arguments
num_entries
- Maximum number of CPUID entries. This function can return less than this when the hardware does not support so many CPUID entries.
Returns Error errno::Error(libc::ENOMEM)
when the input num_entries
is greater than
KVM_MAX_CPUID_ENTRIES
.
Example
extern crate kvm_bindings;
use kvm_bindings::KVM_MAX_CPUID_ENTRIES;
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
let mut cpuid = kvm.get_supported_cpuid(KVM_MAX_CPUID_ENTRIES).unwrap();
let cpuid_entries = cpuid.as_mut_slice();
assert!(cpuid_entries.len() <= KVM_MAX_CPUID_ENTRIES);
sourcepub fn get_msr_index_list(&self) -> Result<MsrList, Error>
pub fn get_msr_index_list(&self) -> Result<MsrList, Error>
X86 specific call to get list of supported MSRS
See the documentation for KVM_GET_MSR_INDEX_LIST
.
Example
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
let msr_index_list = kvm.get_msr_index_list().unwrap();
sourcepub fn get_msr_feature_index_list(&self) -> Result<MsrList, Error>
pub fn get_msr_feature_index_list(&self) -> Result<MsrList, Error>
X86 specific call to get a list of MSRs that can be passed to the KVM_GET_MSRS system ioctl.
See the documentation for KVM_GET_MSR_FEATURE_INDEX_LIST
.
Example
use kvm_bindings::{kvm_msr_entry, Msrs};
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
let msr_feature_index_list = kvm.get_msr_feature_index_list().unwrap();
sourcepub fn get_msrs(&self, msrs: &mut Msrs) -> Result<usize, Error>
pub fn get_msrs(&self, msrs: &mut Msrs) -> Result<usize, Error>
X86 specific call to read the values of MSR-based features that are available for the VM.
As opposed to VcpuFd::get_msrs()
, this call returns all the MSRs supported by the
system, similar to get_supported_cpuid()
for CPUID.
See the documentation for KVM_GET_MSRS
.
Arguments
msrs
- MSRs (input/output). For details check thekvm_msrs
structure in the KVM API doc.
Example
use kvm_bindings::{kvm_msr_entry, Msrs};
use kvm_ioctls::Kvm;
let kvm = Kvm::new().unwrap();
let msr_feature_index_list = kvm.get_msr_feature_index_list().unwrap();
let mut msrs = Msrs::from_entries(
&msr_feature_index_list
.as_slice()
.iter()
.map(|&idx| kvm_msr_entry {
index: idx,
..Default::default()
})
.collect::<Vec<_>>(),
)
.unwrap();
let ret = kvm.get_msrs(&mut msrs).unwrap();
sourcepub fn create_vm(&self) -> Result<VmFd, Error>
pub fn create_vm(&self) -> Result<VmFd, Error>
Creates a VM fd using the KVM fd.
See the documentation for KVM_CREATE_VM
.
A call to this function will also initialize the size of the vcpu mmap area using the
KVM_GET_VCPU_MMAP_SIZE
ioctl.
Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
// Check that the VM mmap size is the same reported by `KVM_GET_VCPU_MMAP_SIZE`.
assert!(vm.run_size() == kvm.get_vcpu_mmap_size().unwrap());
sourcepub fn create_vm_with_type(&self, vm_type: u64) -> Result<VmFd, Error>
pub fn create_vm_with_type(&self, vm_type: u64) -> Result<VmFd, Error>
Creates a VM fd using the KVM fd of a specific type.
See the documentation for KVM_CREATE_VM
.
A call to this function will also initialize the size of the vcpu mmap area using the
KVM_GET_VCPU_MMAP_SIZE
ioctl.
vm_type
- Platform and architecture specific platform VM type. A value of 0 is the equivalent to using the default VM type.
Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm_with_type(0).unwrap();
// Check that the VM mmap size is the same reported by `KVM_GET_VCPU_MMAP_SIZE`.
assert!(vm.run_size() == kvm.get_vcpu_mmap_size().unwrap());
sourcepub unsafe fn create_vmfd_from_rawfd(&self, fd: RawFd) -> Result<VmFd, Error>
pub unsafe fn create_vmfd_from_rawfd(&self, fd: RawFd) -> Result<VmFd, Error>
Creates a VmFd object from a VM RawFd.
Arguments
fd
- the RawFd used for creating the VmFd object.
Safety
This function is unsafe as the primitives currently returned have the contract that they are the sole owner of the file descriptor they are wrapping. Usage of this function could accidentally allow violating this contract which can cause memory unsafety in code that relies on it being true.
The caller of this method must make sure the fd is valid and nothing else uses it.
Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let rawfd = unsafe { libc::dup(vm.as_raw_fd()) };
assert!(rawfd >= 0);
let vm = unsafe { kvm.create_vmfd_from_rawfd(rawfd).unwrap() };
Trait Implementations§
source§impl FromRawFd for Kvm
impl FromRawFd for Kvm
source§unsafe fn from_raw_fd(fd: RawFd) -> Self
unsafe fn from_raw_fd(fd: RawFd) -> Self
Creates a new Kvm object assuming fd
represents an existing open file descriptor
associated with /dev/kvm
.
For usage examples check open_with_cloexec().
Arguments
fd
- File descriptor for/dev/kvm
.
Safety
This function is unsafe as the primitives currently returned have the contract that they are the sole owner of the file descriptor they are wrapping. Usage of this function could accidentally allow violating this contract which can cause memory unsafety in code that relies on it being true.
The caller of this method must make sure the fd is valid and nothing else uses it.
Example
let kvm_fd = Kvm::open_with_cloexec(true).unwrap();
// Safe because we verify that the fd is valid in `open_with_cloexec` and we own the fd.
let kvm = unsafe { Kvm::from_raw_fd(kvm_fd) };