pub trait VcpuX86_64: Vcpu {
Show 30 methods // Required methods fn set_interrupt_window_requested(&self, requested: bool); fn ready_for_interrupt(&self) -> bool; fn interrupt(&self, irq: u8) -> Result<()>; fn inject_nmi(&self) -> Result<()>; fn get_regs(&self) -> Result<Regs>; fn set_regs(&self, regs: &Regs) -> Result<()>; fn get_sregs(&self) -> Result<Sregs>; fn set_sregs(&self, sregs: &Sregs) -> Result<()>; fn get_fpu(&self) -> Result<Fpu>; fn set_fpu(&self, fpu: &Fpu) -> Result<()>; fn get_debugregs(&self) -> Result<DebugRegs>; fn set_debugregs(&self, debugregs: &DebugRegs) -> Result<()>; fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>>; fn set_xcr(&self, xcr: u32, value: u64) -> Result<()>; fn get_xsave(&self) -> Result<Xsave>; fn set_xsave(&self, xsave: &Xsave) -> Result<()>; fn get_interrupt_state(&self) -> Result<Value>; fn set_interrupt_state(&self, data: Value) -> Result<()>; fn get_msr(&self, msr_index: u32) -> Result<u64>; fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>; fn set_msr(&self, msr_index: u32, value: u64) -> Result<()>; fn set_cpuid(&self, cpuid: &CpuId) -> Result<()>; fn set_guest_debug( &self, addrs: &[GuestAddress], enable_singlestep: bool ) -> Result<()>; fn handle_cpuid(&mut self, entry: &CpuIdEntry) -> Result<()>; fn restore_timekeeping( &self, host_tsc_reference_moment: u64, tsc_offset: u64 ) -> Result<()>; // Provided methods fn get_tsc_offset(&self) -> Result<u64> { ... } fn set_tsc_offset(&self, offset: u64) -> Result<()> { ... } fn set_tsc_value(&self, value: u64) -> Result<()> { ... } fn snapshot(&self) -> Result<VcpuSnapshot> { ... } fn restore( &mut self, snapshot: &VcpuSnapshot, host_tsc_reference_moment: u64 ) -> Result<()> { ... }
}
Expand description

A wrapper around creating and using a VCPU on x86_64.

Required Methods§

source

fn set_interrupt_window_requested(&self, requested: bool)

Sets or clears the flag that requests the VCPU to exit when it becomes possible to inject interrupts into the guest.

source

fn ready_for_interrupt(&self) -> bool

Checks if we can inject an interrupt into the VCPU.

source

fn interrupt(&self, irq: u8) -> Result<()>

Injects interrupt vector irq into the VCPU.

This function should only be called when Self::ready_for_interrupt returns true. Otherwise the interrupt injetion may fail or the next VCPU run may fail.

The caller should avoid calling this function more than 1 time for one VMEXIT, because the hypervisor may behave differently: some hypervisors(e.g. WHPX, KVM) will only try to inject the last irq requested, while some other hypervisors(e.g. HAXM) may try to inject all irqs requested.

source

fn inject_nmi(&self) -> Result<()>

Injects a non-maskable interrupt into the VCPU.

source

fn get_regs(&self) -> Result<Regs>

Gets the VCPU general purpose registers.

source

fn set_regs(&self, regs: &Regs) -> Result<()>

Sets the VCPU general purpose registers.

source

fn get_sregs(&self) -> Result<Sregs>

Gets the VCPU special registers.

source

fn set_sregs(&self, sregs: &Sregs) -> Result<()>

Sets the VCPU special registers.

source

fn get_fpu(&self) -> Result<Fpu>

Gets the VCPU FPU registers.

source

fn set_fpu(&self, fpu: &Fpu) -> Result<()>

Sets the VCPU FPU registers.

source

fn get_debugregs(&self) -> Result<DebugRegs>

Gets the VCPU debug registers.

source

fn set_debugregs(&self, debugregs: &DebugRegs) -> Result<()>

Sets the VCPU debug registers.

source

fn get_xcrs(&self) -> Result<BTreeMap<u32, u64>>

Gets the VCPU extended control registers.

source

fn set_xcr(&self, xcr: u32, value: u64) -> Result<()>

Sets a VCPU extended control register.

source

fn get_xsave(&self) -> Result<Xsave>

Gets the VCPU x87 FPU, MMX, XMM, YMM and MXCSR registers.

source

fn set_xsave(&self, xsave: &Xsave) -> Result<()>

Sets the VCPU x87 FPU, MMX, XMM, YMM and MXCSR registers.

source

fn get_interrupt_state(&self) -> Result<Value>

Gets interrupt state (hypervisor specific) for this VCPU that must be saved/restored for snapshotting.

source

fn set_interrupt_state(&self, data: Value) -> Result<()>

Sets interrupt state (hypervisor specific) for this VCPU. Only used for snapshotting.

source

fn get_msr(&self, msr_index: u32) -> Result<u64>

Gets a single model-specific register’s value.

source

fn get_all_msrs(&self) -> Result<BTreeMap<u32, u64>>

Gets the model-specific registers. Returns all the MSRs for the VCPU.

source

fn set_msr(&self, msr_index: u32, value: u64) -> Result<()>

Sets a single model-specific register’s value.

source

fn set_cpuid(&self, cpuid: &CpuId) -> Result<()>

Sets up the data returned by the CPUID instruction.

source

fn set_guest_debug( &self, addrs: &[GuestAddress], enable_singlestep: bool ) -> Result<()>

Sets up debug registers and configure vcpu for handling guest debug events.

source

fn handle_cpuid(&mut self, entry: &CpuIdEntry) -> Result<()>

This function should be called after Vcpu::run returns VcpuExit::Cpuid, and entry should represent the result of emulating the CPUID instruction. The handle_cpuid function will then set the appropriate registers on the vcpu.

source

fn restore_timekeeping( &self, host_tsc_reference_moment: u64, tsc_offset: u64 ) -> Result<()>

Some hypervisors require special handling to restore timekeeping when a snapshot is restored. They are provided with a host TSC reference moment, guaranteed to be the same across all Vcpus, and the Vcpu’s TSC offset at the moment it was snapshotted.

Provided Methods§

source

fn get_tsc_offset(&self) -> Result<u64>

Gets the guest->host TSC offset.

The default implementation uses VcpuX86_64::get_msr() to read the guest TSC.

source

fn set_tsc_offset(&self, offset: u64) -> Result<()>

Sets the guest->host TSC offset.

The default implementation uses VcpuX86_64::set_tsc_value() to set the TSC value.

It sets TSC_OFFSET (VMCS / CB field) by setting the TSC MSR to the current host TSC value plus the desired offset. We rely on the fact that hypervisors determine the value of TSC_OFFSET by computing TSC_OFFSET = new_tsc_value

  • _rdtsc() = _rdtsc() + offset - _rdtsc() ~= offset. Note that the ~= is important: this is an approximate operation, because the two _rdtsc() calls are separated by at least a few ticks.

Note: TSC_OFFSET, host TSC, guest TSC, and TSC MSR are all different concepts.

  • When a guest executes rdtsc, the value (guest TSC) returned is host_tsc * TSC_MULTIPLIER + TSC_OFFSET + TSC_ADJUST.
  • The TSC MSR is a special MSR that when written to by the host, will cause TSC_OFFSET to be set accordingly by the hypervisor.
  • When the guest writes to TSC MSR, it actually changes the TSC_ADJUST MSR for the guest. Generally this is only happens if the guest is trying to re-zero or synchronize TSCs.
source

fn set_tsc_value(&self, value: u64) -> Result<()>

Sets the guest TSC exactly to the provided value.

The default implementation sets the guest’s TSC by writing the value to the MSR directly.

See VcpuX86_64::set_tsc_offset() for an explanation of how this value is actually read by the guest after being set.

source

fn snapshot(&self) -> Result<VcpuSnapshot>

Snapshot vCPU state

source

fn restore( &mut self, snapshot: &VcpuSnapshot, host_tsc_reference_moment: u64 ) -> Result<()>

Implementations§

source§

impl dyn VcpuX86_64

source

pub fn is<__T: VcpuX86_64>(&self) -> bool

Returns true if the trait object wraps an object of type __T.

source

pub fn downcast<__T: VcpuX86_64>(self: Box<Self>) -> Result<Box<__T>, Box<Self>>

Returns a boxed object from a boxed trait object if the underlying object is of type __T. Returns the original boxed trait if it isn’t.

source

pub fn downcast_rc<__T: VcpuX86_64>(self: Rc<Self>) -> Result<Rc<__T>, Rc<Self>>

Returns an Rc-ed object from an Rc-ed trait object if the underlying object is of type __T. Returns the original Rc-ed trait if it isn’t.

source

pub fn downcast_ref<__T: VcpuX86_64>(&self) -> Option<&__T>

Returns a reference to the object within the trait object if it is of type __T, or None if it isn’t.

source

pub fn downcast_mut<__T: VcpuX86_64>(&mut self) -> Option<&mut __T>

Returns a mutable reference to the object within the trait object if it is of type __T, or None if it isn’t.

Implementors§