[][src]Struct kvm_ioctls::VcpuFd

pub struct VcpuFd { /* fields omitted */ }

Wrapper over KVM vCPU ioctls.

Methods

impl VcpuFd[src]

pub fn get_regs(&self) -> Result<kvm_regs>[src]

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();
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
let regs = vcpu.get_regs().unwrap();

pub fn set_regs(&self, regs: &kvm_regs) -> Result<()>[src]

Sets the vCPU general purpose registers using the KVM_SET_REGS ioctl.

Arguments

  • regs - general purpose registers. For details check the kvm_regs structure in the KVM API doc.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();

#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] {
    // 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(&regs).unwrap();
}

pub fn get_sregs(&self) -> Result<kvm_sregs>[src]

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();
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
let sregs = vcpu.get_sregs().unwrap();

pub fn set_sregs(&self, sregs: &kvm_sregs) -> Result<()>[src]

Sets the vCPU special registers using the KVM_SET_SREGS ioctl.

Arguments

  • sregs - Special registers. For details check the kvm_sregs structure in the KVM API doc.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] {
    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();
}

pub fn get_fpu(&self) -> Result<kvm_fpu>[src]

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();
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
let fpu = vcpu.get_fpu().unwrap();

pub fn set_fpu(&self, fpu: &kvm_fpu) -> Result<()>[src]

Set the floating point state (FPU) of a vCPU using the KVM_SET_FPU ioct.

Arguments

  • fpu - FPU configuration. For details check the kvm_fpu structure in the KVM API doc.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
    let KVM_FPU_CWD: u16 = 0x37f;
    let fpu = kvm_fpu {
        fcw: KVM_FPU_CWD,
        ..Default::default()
    };
    vcpu.set_fpu(&fpu).unwrap();
}

pub fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()>[src]

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(MAX_KVM_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.mut_entries_slice();
   for entry in entries.iter_mut() {
       match entry.function {
           6 => entry.ecx &= !(1 << ECX_EPB_SHIFT),
           _ => (),
       }
   }
}

vcpu.set_cpuid2(&kvm_cpuid);

pub fn get_lapic(&self) -> Result<kvm_lapic_state>[src]

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();

pub fn set_lapic(&self, klapic: &kvm_lapic_state) -> Result<()>[src]

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 the kvm_lapic_state structure 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();

pub fn get_msrs(&self, msrs: &mut kvm_msrs) -> Result<i32>[src]

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 the kvm_msrs structure 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 msrs = kvm_msrs::default();
vcpu.get_msrs(&mut msrs).unwrap();

pub fn set_msrs(&self, msrs: &kvm_msrs) -> Result<()>[src]

Setup the model-specific registers (MSR) for this vCPU.

See the documentation for KVM_SET_MSRS.

Arguments

  • msrs - MSRs. For details check the kvm_msrs structure 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 msrs = kvm_msrs::default();
vcpu.get_msrs(&mut msrs).unwrap();

let msrs_entries = {
    kvm_msr_entry {
        index: 0x0000_0174,
        ..Default::default()
    }
};

// Create a vector large enough to hold the MSR entry defined above in
// a `kvm_msrs`structure.
let msrs_vec: Vec<u8> =
    Vec::with_capacity(mem::size_of::<kvm_msrs>() + mem::size_of::<kvm_msr_entry>());
let mut msrs: &mut kvm_msrs = unsafe {
    &mut *(msrs_vec.as_ptr() as *mut kvm_msrs)
};
msrs.nmsrs = 1;
vcpu.set_msrs(msrs).unwrap();

pub fn run(&self) -> Result<VcpuExit>[src]

Triggers the running of the current virtual CPU returning an exit reason.

See documentation for KVM_RUN.

Example

// This is a dummy example for running on x86 based on https://lwn.net/Articles/658511/.
#[cfg(target_arch = "x86_64")] {
    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,
    };
    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 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),
        }
    }
}

Trait Implementations

impl AsRawFd for VcpuFd[src]

Auto Trait Implementations

impl Send for VcpuFd

impl Sync for VcpuFd

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.