pub struct VcpuFd { /* private fields */ }Expand description
Wrapper over KVM vCPU ioctls.
Implementations§
Source§impl VcpuFd
impl VcpuFd
Sourcepub fn get_regs(&self) -> Result<kvm_regs, Error>
pub fn get_regs(&self) -> Result<kvm_regs, Error>
Returns the vCPU general purpose registers.
The registers are returned in a kvm_regs structure as defined in the
KVM API documentation.
See documentation for KVM_GET_REGS.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let regs = vcpu.get_regs().unwrap();Sourcepub fn set_regs(&self, regs: &kvm_regs) -> Result<(), Error>
pub fn set_regs(&self, regs: &kvm_regs) -> Result<(), Error>
Sets the vCPU general purpose registers using the KVM_SET_REGS ioctl.
§Arguments
regs- general purpose registers. For details check thekvm_regsstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// Get the current vCPU registers.
let mut regs = vcpu.get_regs().unwrap();
// Set a new value for the Instruction Pointer.
regs.rip = 0x100;
vcpu.set_regs(®s).unwrap();Sourcepub fn get_sregs(&self) -> Result<kvm_sregs, Error>
pub fn get_sregs(&self) -> Result<kvm_sregs, Error>
Returns the vCPU special registers.
The registers are returned in a kvm_sregs structure as defined in the
KVM API documentation.
See documentation for KVM_GET_SREGS.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let sregs = vcpu.get_sregs().unwrap();Sourcepub fn set_sregs(&self, sregs: &kvm_sregs) -> Result<(), Error>
pub fn set_sregs(&self, sregs: &kvm_sregs) -> Result<(), Error>
Sets the vCPU special registers using the KVM_SET_SREGS ioctl.
§Arguments
sregs- Special registers. For details check thekvm_sregsstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mut sregs = vcpu.get_sregs().unwrap();
// Update the code segment (cs).
sregs.cs.base = 0;
sregs.cs.selector = 0;
vcpu.set_sregs(&sregs).unwrap();Sourcepub fn get_fpu(&self) -> Result<kvm_fpu, Error>
pub fn get_fpu(&self) -> Result<kvm_fpu, Error>
Returns the floating point state (FPU) from the vCPU.
The state is returned in a kvm_fpu structure as defined in the
KVM API doc.
See the documentation for KVM_GET_FPU.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let fpu = vcpu.get_fpu().unwrap();Sourcepub fn set_fpu(&self, fpu: &kvm_fpu) -> Result<(), Error>
pub fn set_fpu(&self, fpu: &kvm_fpu) -> Result<(), Error>
Set the floating point state (FPU) of a vCPU using the KVM_SET_FPU ioct.
§Arguments
fpu- FPU configuration. For details check thekvm_fpustructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let KVM_FPU_CWD: u16 = 0x37f;
let fpu = kvm_fpu {
fcw: KVM_FPU_CWD,
..Default::default()
};
vcpu.set_fpu(&fpu).unwrap();Sourcepub fn set_cpuid2(&self, cpuid: &CpuId) -> Result<(), Error>
pub fn set_cpuid2(&self, cpuid: &CpuId) -> Result<(), Error>
X86 specific call to setup the CPUID registers.
See the documentation for KVM_SET_CPUID2.
§Arguments
cpuid- CPUID registers.
§Example
let kvm = Kvm::new().unwrap();
let mut kvm_cpuid = kvm.get_supported_cpuid(KVM_MAX_CPUID_ENTRIES).unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// Update the CPUID entries to disable the EPB feature.
const ECX_EPB_SHIFT: u32 = 3;
let entries = kvm_cpuid.as_mut_slice();
for entry in entries.iter_mut() {
match entry.function {
6 => entry.ecx &= !(1 << ECX_EPB_SHIFT),
_ => (),
}
}
vcpu.set_cpuid2(&kvm_cpuid).unwrap();Sourcepub fn get_cpuid2(&self, num_entries: usize) -> Result<CpuId, Error>
pub fn get_cpuid2(&self, num_entries: usize) -> Result<CpuId, Error>
X86 specific call to retrieve the CPUID registers.
It requires knowledge of how many kvm_cpuid_entry2 entries there are to get.
See the documentation for KVM_GET_CPUID2 in the
KVM API doc.
§Arguments
num_entries- Number of CPUID entries to be read.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let cpuid = vcpu.get_cpuid2(KVM_MAX_CPUID_ENTRIES).unwrap();Sourcepub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<(), Error>
pub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<(), Error>
See the documentation for KVM_ENABLE_CAP.
§Arguments
- kvm_enable_cap - KVM capability structure. For details check the
kvm_enable_capstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut cap: kvm_enable_cap = Default::default();
// KVM_CAP_HYPERV_SYNIC needs KVM_CAP_SPLIT_IRQCHIP enabled
cap.cap = KVM_CAP_SPLIT_IRQCHIP;
cap.args[0] = 24;
vm.enable_cap(&cap).unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::HypervSynic) {
let mut cap: kvm_enable_cap = Default::default();
cap.cap = KVM_CAP_HYPERV_SYNIC;
vcpu.enable_cap(&cap).unwrap();
}Sourcepub fn get_lapic(&self) -> Result<kvm_lapic_state, Error>
pub fn get_lapic(&self) -> Result<kvm_lapic_state, Error>
Returns the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
The state is returned in a kvm_lapic_state structure as defined in the
KVM API doc.
See the documentation for KVM_GET_LAPIC.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
// For `get_lapic` to work, you first need to create a IRQ chip before creating the vCPU.
vm.create_irq_chip().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let lapic = vcpu.get_lapic().unwrap();Sourcepub fn set_lapic(&self, klapic: &kvm_lapic_state) -> Result<(), Error>
pub fn set_lapic(&self, klapic: &kvm_lapic_state) -> Result<(), Error>
Sets the state of the LAPIC (Local Advanced Programmable Interrupt Controller).
See the documentation for KVM_SET_LAPIC.
§Arguments
klapic- LAPIC state. For details check thekvm_lapic_statestructure in the KVM API doc.
§Example
use std::io::Write;
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
// For `get_lapic` to work, you first need to create a IRQ chip before creating the vCPU.
vm.create_irq_chip().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mut lapic = vcpu.get_lapic().unwrap();
// Write to APIC_ICR offset the value 2.
let apic_icr_offset = 0x300;
let write_value: &[u8] = &[2, 0, 0, 0];
let mut apic_icr_slice =
unsafe { &mut *(&mut lapic.regs[apic_icr_offset..] as *mut [i8] as *mut [u8]) };
apic_icr_slice.write(write_value).unwrap();
// Update the value of LAPIC.
vcpu.set_lapic(&lapic).unwrap();Sourcepub fn get_msrs(&self, msrs: &mut Msrs) -> Result<usize, Error>
pub fn get_msrs(&self, msrs: &mut Msrs) -> Result<usize, Error>
Returns the model-specific registers (MSR) for this vCPU.
It emulates KVM_GET_MSRS ioctl’s behavior by returning the number of MSRs
successfully read upon success or the last error number in case of failure.
The MSRs are returned in the msr method argument.
§Arguments
msrs- MSRs (input/output). For details check thekvm_msrsstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// Configure the struct to say which entries we want to get.
let mut msrs = Msrs::from_entries(&[
kvm_msr_entry {
index: 0x0000_0174,
..Default::default()
},
kvm_msr_entry {
index: 0x0000_0175,
..Default::default()
},
])
.unwrap();
let read = vcpu.get_msrs(&mut msrs).unwrap();
assert_eq!(read, 2);Sourcepub fn set_msrs(&self, msrs: &Msrs) -> Result<usize, Error>
pub fn set_msrs(&self, msrs: &Msrs) -> Result<usize, Error>
Setup the model-specific registers (MSR) for this vCPU. Returns the number of MSR entries actually written.
See the documentation for KVM_SET_MSRS.
§Arguments
msrs- MSRs. For details check thekvm_msrsstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// Configure the entries we want to set.
let mut msrs = Msrs::from_entries(&[kvm_msr_entry {
index: 0x0000_0174,
..Default::default()
}])
.unwrap();
let written = vcpu.set_msrs(&msrs).unwrap();
assert_eq!(written, 1);Sourcepub fn get_mp_state(&self) -> Result<kvm_mp_state, Error>
pub fn get_mp_state(&self) -> Result<kvm_mp_state, Error>
Returns the vcpu’s current “multiprocessing state”.
See the documentation for KVM_GET_MP_STATE in the
KVM API doc.
§Arguments
kvm_mp_state- multiprocessing state to be read.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mp_state = vcpu.get_mp_state().unwrap();Sourcepub fn set_mp_state(&self, mp_state: kvm_mp_state) -> Result<(), Error>
pub fn set_mp_state(&self, mp_state: kvm_mp_state) -> Result<(), Error>
Sets the vcpu’s current “multiprocessing state”.
See the documentation for KVM_SET_MP_STATE in the
KVM API doc.
§Arguments
kvm_mp_state- multiprocessing state to be written.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mp_state = Default::default();
// Your `mp_state` manipulation here.
vcpu.set_mp_state(mp_state).unwrap();Sourcepub fn get_xsave(&self) -> Result<kvm_xsave, Error>
pub fn get_xsave(&self) -> Result<kvm_xsave, Error>
X86 specific call that returns the vcpu’s current “xsave struct”.
See the documentation for KVM_GET_XSAVE in the
KVM API doc.
§Arguments
kvm_xsave- xsave struct to be read.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xsave = vcpu.get_xsave().unwrap();Sourcepub unsafe fn get_xsave2(&self, xsave: &mut Xsave) -> Result<(), Error>
pub unsafe fn get_xsave2(&self, xsave: &mut Xsave) -> Result<(), Error>
X86 specific call that gets the current vcpu’s “xsave struct” via KVM_GET_XSAVE2.
See the documentation for KVM_GET_XSAVE2 in the
KVM API doc.
§Arguments
xsave- A mutable reference to anXsaveinstance that will be populated with the current vcpu’s “xsave struct”.
§Safety
This function is unsafe because there is no guarantee xsave is allocated with enough space
to hold the entire xsave state.
The required size in bytes can be retrieved via KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2) and
can vary depending on features that have been dynamically enabled by arch_prctl(). Thus,
any features must not be enabled dynamically after the required size has been confirmed.
If xsave is not large enough, KVM_GET_XSAVE2 copies data beyond the allocated area,
possibly causing undefined behavior.
See the documentation for dynamically enabled XSTATE features in the kernel doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xsave_size = vm.check_extension_int(Cap::Xsave2);
if xsave_size > 0 {
let fam_size = (xsave_size as usize - std::mem::size_of::<kvm_xsave>())
.div_ceil(std::mem::size_of::<<kvm_xsave2 as FamStruct>::Entry>());
let mut xsave = Xsave::new(fam_size).unwrap();
unsafe { vcpu.get_xsave2(&mut xsave).unwrap() };
}Sourcepub unsafe fn set_xsave(&self, xsave: &kvm_xsave) -> Result<(), Error>
pub unsafe fn set_xsave(&self, xsave: &kvm_xsave) -> Result<(), Error>
X86 specific call that sets the vcpu’s current “xsave struct”.
See the documentation for KVM_SET_XSAVE in the
KVM API doc.
§Arguments
xsave- xsave struct to be written.
§Safety
The C kvm_xsave struct was extended to have a flexible array member (FAM) at the end in
Linux 5.17. The size can vary depending on features that have been dynamically enabled via
arch_prctl() and the required size can be retrieved via
KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2). That means KVM_SET_XSAVE may copy data beyond the
size of the traditional C kvm_xsave struct (i.e. 4096 bytes) now.
It is safe if used on Linux prior to 5.17, if no XSTATE features are enabled dynamically or
if the required size is still within the traditional 4096 bytes even with dynamically
enabled features. However, if any features are enabled dynamically, it is recommended to use
set_xsave2() instead.
See the documentation for dynamically enabled XSTATE features in the kernel doc.
Theoretically, it can be made safe by checking which features are enabled in the bit vector
of the XSTATE header and validating the required size is less than or equal to 4096 bytes.
However, to do it properly, we would need to extract the XSTATE header from the kvm_xsave
struct, check enabled features, retrieve the required size for each enabled feature (like
setup_xstate_cache() do in Linux) and calculate the total size.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xsave = Default::default();
// Your `xsave` manipulation here.
unsafe { vcpu.set_xsave(&xsave).unwrap() };Sourcepub unsafe fn set_xsave2(&self, xsave: &Xsave) -> Result<(), Error>
pub unsafe fn set_xsave2(&self, xsave: &Xsave) -> Result<(), Error>
Convenience function for doing KVM_SET_XSAVE with the FAM-enabled Xsave
instead of the pre-5.17 plain kvm_xsave.
§Arguments
xsave- A reference to anXsaveinstance to be set.
§Safety
This function is unsafe because there is no guarantee xsave is properly allocated with
the size that KVM assumes.
The required size in bytes can be retrieved via KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2) and
can vary depending on features that have been dynamically enabled by arch_prctl(). Thus,
any features must not be enabled after the required size has been confirmed.
If xsave is not large enough, KVM_SET_XSAVE copies data beyond the allocated area to
the kernel, possibly causing undefined behavior.
See the documentation for dynamically enabled XSTATE features in the kernel doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xsave_size = vm.check_extension_int(Cap::Xsave2);
if xsave_size > 0 {
let fam_size = (xsave_size as usize - std::mem::size_of::<kvm_xsave>())
.div_ceil(std::mem::size_of::<<kvm_xsave2 as FamStruct>::Entry>());
let xsave = Xsave::new(fam_size).unwrap();
// Your `xsave` manipulation here.
unsafe { vcpu.set_xsave2(&xsave).unwrap() };
}Sourcepub fn get_xcrs(&self) -> Result<kvm_xcrs, Error>
pub fn get_xcrs(&self) -> Result<kvm_xcrs, Error>
X86 specific call that returns the vcpu’s current “xcrs”.
See the documentation for KVM_GET_XCRS in the
KVM API doc.
§Arguments
kvm_xcrs- xcrs to be read.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xcrs = vcpu.get_xcrs().unwrap();Sourcepub fn set_xcrs(&self, xcrs: &kvm_xcrs) -> Result<(), Error>
pub fn set_xcrs(&self, xcrs: &kvm_xcrs) -> Result<(), Error>
X86 specific call that sets the vcpu’s current “xcrs”.
See the documentation for KVM_SET_XCRS in the
KVM API doc.
§Arguments
kvm_xcrs- xcrs to be written.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let xcrs = Default::default();
// Your `xcrs` manipulation here.
vcpu.set_xcrs(&xcrs).unwrap();Sourcepub fn get_debug_regs(&self) -> Result<kvm_debugregs, Error>
pub fn get_debug_regs(&self) -> Result<kvm_debugregs, Error>
X86 specific call that returns the vcpu’s current “debug registers”.
See the documentation for KVM_GET_DEBUGREGS in the
KVM API doc.
§Arguments
kvm_debugregs- debug registers to be read.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let debug_regs = vcpu.get_debug_regs().unwrap();Sourcepub fn set_debug_regs(&self, debug_regs: &kvm_debugregs) -> Result<(), Error>
pub fn set_debug_regs(&self, debug_regs: &kvm_debugregs) -> Result<(), Error>
X86 specific call that sets the vcpu’s current “debug registers”.
See the documentation for KVM_SET_DEBUGREGS in the
KVM API doc.
§Arguments
kvm_debugregs- debug registers to be written.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let debug_regs = Default::default();
// Your `debug_regs` manipulation here.
vcpu.set_debug_regs(&debug_regs).unwrap();Sourcepub fn get_vcpu_events(&self) -> Result<kvm_vcpu_events, Error>
pub fn get_vcpu_events(&self) -> Result<kvm_vcpu_events, Error>
Returns currently pending exceptions, interrupts, and NMIs as well as related states of the vcpu.
See the documentation for KVM_GET_VCPU_EVENTS in the
KVM API doc.
§Arguments
kvm_vcpu_events- vcpu events to be read.
§Example
let kvm = Kvm::new().unwrap();
if kvm.check_extension(Cap::VcpuEvents) {
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let vcpu_events = vcpu.get_vcpu_events().unwrap();
}Sourcepub fn set_vcpu_events(
&self,
vcpu_events: &kvm_vcpu_events,
) -> Result<(), Error>
pub fn set_vcpu_events( &self, vcpu_events: &kvm_vcpu_events, ) -> Result<(), Error>
Sets pending exceptions, interrupts, and NMIs as well as related states of the vcpu.
See the documentation for KVM_SET_VCPU_EVENTS in the
KVM API doc.
§Arguments
kvm_vcpu_events- vcpu events to be written.
§Example
let kvm = Kvm::new().unwrap();
if kvm.check_extension(Cap::VcpuEvents) {
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let vcpu_events = Default::default();
// Your `vcpu_events` manipulation here.
vcpu.set_vcpu_events(&vcpu_events).unwrap();
}Sourcepub fn set_guest_debug(
&self,
debug_struct: &kvm_guest_debug,
) -> Result<(), Error>
pub fn set_guest_debug( &self, debug_struct: &kvm_guest_debug, ) -> Result<(), Error>
Sets processor-specific debug registers and configures the vcpu for handling
certain guest debug events using the KVM_SET_GUEST_DEBUG ioctl.
§Arguments
debug_struct- control bitfields and debug registers, depending on the specific architecture. For details check thekvm_guest_debugstructure in the KVM API doc.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let debug_struct = kvm_guest_debug {
// Configure the vcpu so that a KVM_DEBUG_EXIT would be generated
// when encountering a software breakpoint during execution
control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP,
pad: 0,
// Reset all arch-specific debug registers
arch: Default::default(),
};
vcpu.set_guest_debug(&debug_struct).unwrap();Sourcepub fn kvmclock_ctrl(&self) -> Result<(), Error>
pub fn kvmclock_ctrl(&self) -> Result<(), Error>
Notify the guest about the vCPU being paused.
See the documentation for KVM_KVMCLOCK_CTRL in the
KVM API documentation.
Sourcepub fn run(&mut self) -> Result<VcpuExit<'_>, Error>
pub fn run(&mut self) -> Result<VcpuExit<'_>, Error>
Triggers the running of the current virtual CPU returning an exit reason.
See documentation for KVM_RUN.
§Example
Running some dummy code on x86_64 that immediately halts the vCPU. Based on https://lwn.net/Articles/658511/.
let mem_size = 0x4000;
let guest_addr: u64 = 0x1000;
let load_addr: *mut u8 = unsafe {
libc::mmap(
null_mut(),
mem_size,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_ANONYMOUS | libc::MAP_SHARED | libc::MAP_NORESERVE,
-1,
0,
) as *mut u8
};
let mem_region = kvm_userspace_memory_region {
slot: 0,
guest_phys_addr: guest_addr,
memory_size: mem_size as u64,
userspace_addr: load_addr as u64,
flags: 0,
};
unsafe { vm.set_user_memory_region(mem_region).unwrap() };
// Dummy x86 code that just calls halt.
let x86_code = [0xf4 /* hlt */];
// Write the code in the guest memory. This will generate a dirty page.
unsafe {
let mut slice = slice::from_raw_parts_mut(load_addr, mem_size);
slice.write(&x86_code).unwrap();
}
let mut vcpu_fd = vm.create_vcpu(0).unwrap();
let mut vcpu_sregs = vcpu_fd.get_sregs().unwrap();
vcpu_sregs.cs.base = 0;
vcpu_sregs.cs.selector = 0;
vcpu_fd.set_sregs(&vcpu_sregs).unwrap();
let mut vcpu_regs = vcpu_fd.get_regs().unwrap();
// Set the Instruction Pointer to the guest address where we loaded the code.
vcpu_regs.rip = guest_addr;
vcpu_regs.rax = 2;
vcpu_regs.rbx = 3;
vcpu_regs.rflags = 2;
vcpu_fd.set_regs(&vcpu_regs).unwrap();
loop {
match vcpu_fd.run().expect("run failed") {
VcpuExit::Hlt => {
break;
}
exit_reason => panic!("unexpected exit reason: {:?}", exit_reason),
}
}Sourcepub fn get_kvm_run(&mut self) -> &mut kvm_run
pub fn get_kvm_run(&mut self) -> &mut kvm_run
Returns a mutable reference to the kvm_run structure
Sourcepub fn set_kvm_immediate_exit(&mut self, val: u8)
pub fn set_kvm_immediate_exit(&mut self, val: u8)
Sets the immediate_exit flag on the kvm_run struct associated with this vCPU to val.
Sourcepub fn get_tsc_khz(&self) -> Result<u32, Error>
pub fn get_tsc_khz(&self) -> Result<u32, Error>
Returns the vCPU TSC frequency in KHz or an error if the host has unstable TSC.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let tsc_khz = vcpu.get_tsc_khz().unwrap();Sourcepub fn set_tsc_khz(&self, freq: u32) -> Result<(), Error>
pub fn set_tsc_khz(&self, freq: u32) -> Result<(), Error>
Sets the specified vCPU TSC frequency.
§Arguments
freq- The frequency unit is KHz as per the KVM API documentation forKVM_SET_TSC_KHZ.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::GetTscKhz) && kvm.check_extension(Cap::TscControl) {
vcpu.set_tsc_khz(1000).unwrap();
}Sourcepub fn translate_gva(&self, gva: u64) -> Result<kvm_translation, Error>
pub fn translate_gva(&self, gva: u64) -> Result<kvm_translation, Error>
Translates a virtual address according to the vCPU’s current address translation mode.
The physical address is returned in a kvm_translation structure as defined in the
KVM API documentation.
See documentation for KVM_TRANSLATE.
§Arguments
gva- The virtual address to translate.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
#[cfg(target_arch = "x86_64")]
let tr = vcpu.translate_gva(0x10000).unwrap();Sourcepub fn set_sync_valid_reg(&mut self, reg: SyncReg)
pub fn set_sync_valid_reg(&mut self, reg: SyncReg)
Enable the given SyncReg to be copied to userspace on the next exit
§Arguments
reg- TheSyncRegto copy out of the guest
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut vcpu = vm.create_vcpu(0).unwrap();
vcpu.set_sync_valid_reg(SyncReg::Register);
vcpu.set_sync_valid_reg(SyncReg::SystemRegister);
vcpu.set_sync_valid_reg(SyncReg::VcpuEvents);Sourcepub fn set_sync_dirty_reg(&mut self, reg: SyncReg)
pub fn set_sync_dirty_reg(&mut self, reg: SyncReg)
Sourcepub fn clear_sync_valid_reg(&mut self, reg: SyncReg)
pub fn clear_sync_valid_reg(&mut self, reg: SyncReg)
Sourcepub fn clear_sync_dirty_reg(&mut self, reg: SyncReg)
pub fn clear_sync_dirty_reg(&mut self, reg: SyncReg)
Sourcepub fn sync_regs(&self) -> kvm_sync_regs
pub fn sync_regs(&self) -> kvm_sync_regs
Get the kvm_sync_regs from the VM
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::SyncRegs) {
vcpu.set_sync_valid_reg(SyncReg::Register);
vcpu.run();
let guest_rax = vcpu.sync_regs().regs.rax;
}Sourcepub fn sync_regs_mut(&mut self) -> &mut kvm_sync_regs
pub fn sync_regs_mut(&mut self) -> &mut kvm_sync_regs
Get a mutable reference to the kvm_sync_regs from the VM
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::SyncRegs) {
vcpu.set_sync_valid_reg(SyncReg::Register);
vcpu.run();
// Set the guest RAX to 0xdeadbeef
vcpu.sync_regs_mut().regs.rax = 0xdeadbeef;
vcpu.set_sync_dirty_reg(SyncReg::Register);
vcpu.run();
}Sourcepub fn smi(&self) -> Result<(), Error>
pub fn smi(&self) -> Result<(), Error>
Triggers an SMI on the virtual CPU.
See documentation for KVM_SMI.
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::X86Smm) {
vcpu.smi().unwrap();
}Sourcepub fn nested_state(
&self,
buffer: &mut KvmNestedStateBuffer,
) -> Result<Option<NonZeroUsize>, Error>
pub fn nested_state( &self, buffer: &mut KvmNestedStateBuffer, ) -> Result<Option<NonZeroUsize>, Error>
Returns the nested guest state using the KVM_GET_NESTED_STATE ioctl.
This only works when KVM_CAP_NESTED_STATE is available.
§Arguments
buffer: The buffer to be filled with the new nested state.
§Return Value
If this returns None, KVM doesn’t have nested state. Otherwise, the
actual length of the state is returned.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mut state_buffer = KvmNestedStateBuffer::empty();
if kvm.check_extension(Cap::NestedState) {
vcpu.nested_state(&mut state_buffer).unwrap();
// Next, serialize the actual state into a file or so.
}Sourcepub fn set_nested_state(
&self,
state: &KvmNestedStateBuffer,
) -> Result<(), Error>
pub fn set_nested_state( &self, state: &KvmNestedStateBuffer, ) -> Result<(), Error>
Sets the nested guest state using the KVM_SET_NESTED_STATE ioctl.
This only works when KVM_CAP_NESTED_STATE is available.
§Arguments
state: The new state to be put into KVM. The header must report thesizeof the state properly. The state must be retrieved first usingSelf::nested_state.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::NestedState) {
let mut state_buffer = KvmNestedStateBuffer::empty();
vcpu.nested_state(&mut state_buffer).unwrap();
// Rename the variable to better reflect the role.
let old_state = state_buffer;
// now assume we transfer the state to a new location
// and load it back into kvm:
vcpu.set_nested_state(&old_state).unwrap();
}Sourcepub fn nmi(&self) -> Result<(), Error>
pub fn nmi(&self) -> Result<(), Error>
Queues an NMI on the thread’s vcpu. Only usable if KVM_CAP_USER_NMI
is available.
See the documentation for KVM_NMI.
§Example
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::UserNmi) {
vcpu.nmi().unwrap();
}Sourcepub fn map_coalesced_mmio_ring(&mut self) -> Result<(), Error>
pub fn map_coalesced_mmio_ring(&mut self) -> Result<(), Error>
Maps the coalesced MMIO ring page. This allows reading entries from
the ring via coalesced_mmio_read().
§Returns
Returns an error if the buffer could not be mapped, usually because
KVM_CAP_COALESCED_MMIO (Cap::CoalescedMmio)
is not available.
§Examples
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut vcpu = vm.create_vcpu(0).unwrap();
if kvm.check_extension(Cap::CoalescedMmio) {
vcpu.map_coalesced_mmio_ring().unwrap();
}Sourcepub fn coalesced_mmio_read(
&mut self,
) -> Result<Option<kvm_coalesced_mmio>, Error>
pub fn coalesced_mmio_read( &mut self, ) -> Result<Option<kvm_coalesced_mmio>, Error>
Read a single entry from the coalesced MMIO ring.
For entries to be appended to the ring by the kernel, addresses must be registered
via VmFd::register_coalesced_mmio().
map_coalesced_mmio_ring() must have been called beforehand.
See the documentation for KVM_(UN)REGISTER_COALESCED_MMIO.
§Returns
- An error if
map_coalesced_mmio_ring()was not called beforehand. Ok<None>if the ring is empty.Ok<Some<kvm_coalesced_mmio>>if an entry was successfully read.