[][src]Struct kvm_ioctls::VmFd

pub struct VmFd { /* fields omitted */ }

Wrapper over KVM VM ioctls.

Methods

impl VmFd[src]

pub fn set_user_memory_region(
    &self,
    user_memory_region: kvm_userspace_memory_region
) -> Result<()>
[src]

Creates/modifies a guest physical memory slot.

See the documentation for KVM_SET_USER_MEMORY_REGION.

Arguments

  • user_memory_region - Guest physical memory slot. For details check the kvm_userspace_memory_region structure in the KVM API doc.

Example

extern crate kvm_bindings;

use kvm_ioctls::{Kvm, VmFd};
use kvm_bindings::kvm_userspace_memory_region;

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mem_region = kvm_userspace_memory_region {
                    slot: 0,
                    guest_phys_addr: 0x1000 as u64,
                    memory_size: 0x4000 as u64,
                    userspace_addr: 0x0 as u64,
                    flags: 0,
                };
vm.set_user_memory_region(mem_region).unwrap();

pub fn set_tss_address(&self, offset: usize) -> Result<()>[src]

Sets the address of the three-page region in the VM's address space.

See the documentation for KVM_SET_TSS_ADDR.

Arguments

  • offset - Physical address of a three-page region in the guest's physical address space.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
vm.set_tss_address(0xfffb_d000).unwrap();

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

Creates an in-kernel interrupt controller.

See the documentation for KVM_CREATE_IRQCHIP.

Example

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

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
vm.create_irq_chip().unwrap();

pub fn create_pit2(&self, pit_config: kvm_pit_config) -> Result<()>[src]

Creates a PIT as per the KVM_CREATE_PIT2 ioctl.

Arguments

  • pit_config - PIT configuration. For details check the kvm_pit_config structure in the KVM API doc.

Example

extern crate kvm_bindings;
use kvm_bindings::kvm_pit_config;

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let pit_config = kvm_pit_config::default();
vm.create_pit2(pit_config).unwrap();

pub fn register_ioevent<T: Into<u64>>(
    &self,
    fd: RawFd,
    addr: &IoEventAddress,
    datamatch: T
) -> Result<()>
[src]

Registers an event to be signaled whenever a certain address is written to.

See the documentation for KVM_IOEVENTFD.

Arguments

  • fd - FD which will be signaled. When signaling, the usual vmexit to userspace is prevented.
  • addr - Address being written to.
  • datamatch - Limits signaling fd to only the cases where the value being written is equal to this parameter. The size of datamatch is important and it must match the expected size of the guest's write.

Example

extern crate libc;
use libc::{eventfd, EFD_NONBLOCK};

let kvm = Kvm::new().unwrap();
let vm_fd = kvm.create_vm().unwrap();
let evtfd = unsafe { eventfd(0, EFD_NONBLOCK) };
vm_fd
   .register_ioevent(evtfd, &IoEventAddress::Pio(0xf4), NoDatamatch)
   .unwrap();
vm_fd
   .register_ioevent(evtfd, &IoEventAddress::Mmio(0x1000), NoDatamatch)
   .unwrap();

pub fn get_dirty_log(&self, slot: u32, memory_size: usize) -> Result<Vec<u64>>[src]

Gets the bitmap of pages dirtied since the last call of this function.

Leverages the dirty page logging feature in KVM. As a side-effect, this also resets the bitmap inside the kernel. For the dirty log to be available, you have to set the flag KVM_MEM_LOG_DIRTY_PAGES when creating guest memory regions.

Check the documentation for KVM_GET_DIRTY_LOG.

Arguments

  • slot - Guest memory slot identifier.
  • memory_size - Size of the memory region.

Example

// This examples is 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
};

// Initialize a guest memory region using the flag `KVM_MEM_LOG_DIRTY_PAGES`.
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: KVM_MEM_LOG_DIRTY_PAGES,
};
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 => {
            // The code snippet dirties 1 page when loading the code in memory.
            let dirty_pages_bitmap = vm.get_dirty_log(0, mem_size).unwrap();
            let dirty_pages = dirty_pages_bitmap
                    .into_iter()
                    .map(|page| page.count_ones())
                    .fold(0, |dirty_page_count, i| dirty_page_count + i);
            assert_eq!(dirty_pages, 1);
            break;
        }
        exit_reason => panic!("unexpected exit reason: {:?}", exit_reason),
    }
}

pub fn register_irqfd(&self, fd: RawFd, gsi: u32) -> Result<()>[src]

Registers an event that will, when signaled, trigger the gsi IRQ.

Arguments

  • fd - Event to be signaled.
  • gsi - IRQ to be triggered.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let evtfd = unsafe { eventfd(0, EFD_NONBLOCK) };
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
vm.register_irqfd(evtfd, 0).unwrap();

pub fn create_vcpu(&self, id: u8) -> Result<VcpuFd>[src]

Creates a new KVM vCPU file descriptor and maps the memory corresponding its kvm_run structure.

See the documentation for KVM_CREATE_VCPU.

Arguments

  • id - The vCPU ID.

Errors

Returns an io::Error when the VM fd is invalid or the vCPU memory cannot be mapped correctly.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
// Create one vCPU with the ID=0.
let vcpu = vm.create_vcpu(0);

pub fn create_device(&self, device: &mut kvm_create_device) -> Result<DeviceFd>[src]

Creates an emulated device in the kernel.

See the documentation for KVM_CREATE_DEVICE.

Arguments

  • device: device configuration. For details check the kvm_create_device structure in the KVM API doc.

Example

use kvm_bindings::{
    kvm_device_type_KVM_DEV_TYPE_VFIO,
    kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3,
    KVM_CREATE_DEVICE_TEST,
};
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();

// Creating a device with the KVM_CREATE_DEVICE_TEST flag to check
// whether the device type is supported. This will not create the device.
// To create the device the flag needs to be removed.
let mut device = kvm_bindings::kvm_create_device {
    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    type_: kvm_device_type_KVM_DEV_TYPE_VFIO,
    #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
    type_: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3,
    fd: 0,
    flags: KVM_CREATE_DEVICE_TEST,
};
let device_fd = vm
    .create_device(&mut device).unwrap();

pub fn run_size(&self) -> usize[src]

Get the kvm_run size.

Trait Implementations

impl AsRawFd for VmFd[src]

Auto Trait Implementations

impl Send for VmFd

impl Sync for VmFd

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<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.