[][src]Struct kvm_ioctls::VmFd

pub struct VmFd { /* fields omitted */ }

Wrapper over KVM VM ioctls.

Implementations

impl VmFd[src]

pub unsafe fn set_user_memory_region(
    &self,
    user_memory_region: kvm_userspace_memory_region
) -> Result<(), Error>
[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.

Safety

This function is unsafe because there is no guarantee userspace_addr points to a valid memory region, nor the memory region lives as long as the kernel needs it to.

The caller of this method must make sure that:

  • the raw pointer (userspace_addr) points to valid memory
  • the regions provided to KVM are not overlapping other memory regions.

Example

extern crate kvm_bindings;

use kvm_ioctls::Kvm;
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: 0x10000 as u64,
                    memory_size: 0x10000 as u64,
                    userspace_addr: 0x0 as u64,
                    flags: 0,
                };
unsafe {
    vm.set_user_memory_region(mem_region).unwrap();
};

pub fn set_tss_address(&self, offset: usize) -> Result<(), Error>[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<(), Error>[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();
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] {
    use kvm_bindings::{kvm_create_device,
        kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2, KVM_CREATE_DEVICE_TEST};
    let mut gic_device = kvm_bindings::kvm_create_device {
        type_: kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2,
        fd: 0,
        flags: KVM_CREATE_DEVICE_TEST,
    };
    if vm.create_device(&mut gic_device).is_ok() {
        vm.create_irq_chip().unwrap();
    }
}

pub fn get_irqchip(&self, irqchip: &mut kvm_irqchip) -> Result<(), Error>[src]

X86 specific call to retrieve the state of a kernel interrupt controller.

See the documentation for KVM_GET_IRQCHIP in the KVM API doc.

Arguments

  • irqchip - kvm_irqchip (input/output) to be read.

Example

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

vm.create_irq_chip().unwrap();
let mut irqchip = kvm_irqchip::default();
irqchip.chip_id = KVM_IRQCHIP_PIC_MASTER;
vm.get_irqchip(&mut irqchip).unwrap();

pub fn set_irqchip(&self, irqchip: &kvm_irqchip) -> Result<(), Error>[src]

X86 specific call to set the state of a kernel interrupt controller.

See the documentation for KVM_SET_IRQCHIP in the KVM API doc.

Arguments

  • irqchip - kvm_irqchip (input/output) to be written.

Example

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

vm.create_irq_chip().unwrap();
let mut irqchip = kvm_irqchip::default();
irqchip.chip_id = KVM_IRQCHIP_PIC_MASTER;
// Your `irqchip` manipulation here.
vm.set_irqchip(&mut irqchip).unwrap();

pub fn create_pit2(&self, pit_config: kvm_pit_config) -> Result<(), Error>[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 get_pit2(&self) -> Result<kvm_pit_state2, Error>[src]

X86 specific call to retrieve the state of the in-kernel PIT model.

See the documentation for KVM_GET_PIT2 in the KVM API doc.

Arguments

  • pitstate - kvm_pit_state2 to be read.

Example

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

let pit_config = kvm_pit_config::default();
vm.create_pit2(pit_config).unwrap();
let pitstate = vm.get_pit2().unwrap();

pub fn set_pit2(&self, pitstate: &kvm_pit_state2) -> Result<(), Error>[src]

X86 specific call to set the state of the in-kernel PIT model.

See the documentation for KVM_SET_PIT2 in the KVM API doc.

Arguments

  • pitstate - kvm_pit_state2 to be written.

Example

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

let pit_config = kvm_pit_config::default();
vm.create_pit2(pit_config).unwrap();
let mut pitstate = kvm_pit_state2::default();
// Your `pitstate` manipulation here.
vm.set_pit2(&mut pitstate).unwrap();

pub fn get_clock(&self) -> Result<kvm_clock_data, Error>[src]

X86 specific call to retrieve the current timestamp of kvmclock.

See the documentation for KVM_GET_CLOCK in the KVM API doc.

Arguments

  • clock - kvm_clock_data to be read.

Example

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

pub fn set_clock(&self, clock: &kvm_clock_data) -> Result<(), Error>[src]

X86 specific call to set the current timestamp of kvmclock.

See the documentation for KVM_SET_CLOCK in the KVM API doc.

Arguments

  • clock - kvm_clock_data to be written.

Example

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut clock = kvm_clock_data::default();
vm.set_clock(&mut clock).unwrap();

pub fn signal_msi(&self, msi: kvm_msi) -> Result<c_int, Error>[src]

Directly injects a MSI message as per the KVM_SIGNAL_MSI ioctl.

See the documentation for KVM_SIGNAL_MSI.

This ioctl returns > 0 when the MSI is successfully delivered and 0 when the guest blocked the MSI.

Arguments

  • kvm_msi - MSI message configuration. For details check the kvm_msi structure in the KVM API doc.

Example

In this example, the important function signal_msi() calling into the actual ioctl is commented out. The reason is that MSI vectors are not chosen from the HW side (VMM). The guest OS (or anything that runs inside the VM) is supposed to allocate the MSI vectors, and usually communicate back through PCI configuration space. Sending a random MSI vector through this signal_msi() function will always result in a failure, which is why it needs to be commented out.

extern crate kvm_bindings;
use kvm_bindings::kvm_msi;

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let msi = kvm_msi::default();
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
vm.create_irq_chip().unwrap();
//vm.signal_msi(msi).unwrap();

pub fn set_gsi_routing(
    &self,
    irq_routing: &kvm_irq_routing
) -> Result<(), Error>
[src]

Sets the GSI routing table entries, overwriting any previously set entries, as per the KVM_SET_GSI_ROUTING ioctl.

See the documentation for KVM_SET_GSI_ROUTING.

Returns an io::Error when the table could not be updated.

Arguments

  • kvm_irq_routing - IRQ routing configuration. Describe all routes associated with GSI entries. For details check the kvm_irq_routing and kvm_irq_routing_entry structures in the KVM API doc.

Example

extern crate kvm_bindings;
use kvm_bindings::kvm_irq_routing;

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

let irq_routing = kvm_irq_routing::default();
vm.set_gsi_routing(&irq_routing).unwrap();

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

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

See the documentation for KVM_IOEVENTFD.

Arguments

  • fd - EventFd 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;
extern crate vmm_sys_util;
use libc::{eventfd, EFD_NONBLOCK};
use vmm_sys_util::eventfd::EventFd;
let kvm = Kvm::new().unwrap();
let vm_fd = kvm.create_vm().unwrap();
let evtfd = EventFd::new(EFD_NONBLOCK).unwrap();
vm_fd
   .register_ioevent(&evtfd, &IoEventAddress::Pio(0xf4), NoDatamatch)
   .unwrap();
vm_fd
   .register_ioevent(&evtfd, &IoEventAddress::Mmio(0x1000), NoDatamatch)
   .unwrap();

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

Unregisters an event from a certain address it has been previously registered to.

See the documentation for KVM_IOEVENTFD.

Arguments

  • fd - FD which will be unregistered.
  • addr - Address being written to.

Safety

This function is unsafe because it relies on RawFd.

Example

extern crate libc;
extern crate vmm_sys_util;
use libc::EFD_NONBLOCK;
use vmm_sys_util::eventfd::EventFd;

let kvm = Kvm::new().unwrap();
let vm_fd = kvm.create_vm().unwrap();
let evtfd = EventFd::new(EFD_NONBLOCK).unwrap();
let pio_addr = IoEventAddress::Pio(0xf4);
let mmio_addr = IoEventAddress::Mmio(0x1000);
vm_fd
   .register_ioevent(&evtfd, &pio_addr, NoDatamatch)
   .unwrap();
vm_fd
   .register_ioevent(&evtfd, &mmio_addr, 0x1234u32)
   .unwrap();
vm_fd
   .unregister_ioevent(&evtfd, &pio_addr, NoDatamatch)
   .unwrap();
vm_fd
   .unregister_ioevent(&evtfd, &mmio_addr, 0x1234u32)
   .unwrap();

pub fn get_dirty_log(
    &self,
    slot: u32,
    memory_size: usize
) -> Result<Vec<u64>, Error>
[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 example 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,
};
unsafe { vm.set_user_memory_region(mem_region).unwrap() };

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
// ASM code that just forces a MMIO Write.
let asm_code = [
        0xc6, 0x06, 0x00, 0x80, 0x00,
];
#[cfg(target_arch = "aarch64")]
let asm_code = [
    0x01, 0x00, 0x00, 0x10, /* adr x1, <this address> */
    0x22, 0x10, 0x00, 0xb9, /* str w2, [x1, #16]; write to this page */
    0x02, 0x00, 0x00, 0xb9, /* str w2, [x0]; force MMIO exit */
    0x00, 0x00, 0x00, 0x14, /* b <this address>; shouldn't get here, but if so loop forever */
];

// 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(&asm_code).unwrap();
}

let vcpu_fd = vm.create_vcpu(0).unwrap();

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
    // x86_64 specific registry setup.
    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();
}

#[cfg(target_arch = "aarch64")]
{
    // aarch64 specific registry setup.
    let mut kvi = kvm_bindings::kvm_vcpu_init::default();
    vm.get_preferred_target(&mut kvi).unwrap();
    vcpu_fd.vcpu_init(&kvi).unwrap();

    let core_reg_base: u64 = 0x6030_0000_0010_0000;
    let mmio_addr: u64 = guest_addr + mem_size as u64;
    vcpu_fd.set_one_reg(core_reg_base + 2 * 32, guest_addr); // set PC
    vcpu_fd.set_one_reg(core_reg_base + 2 * 0, mmio_addr); // set X0
}

loop {
    match vcpu_fd.run().expect("run failed") {
        VcpuExit::MmioWrite(addr, data) => {
            // On x86_64, the code snippet dirties 1 page when loading the code in memory
            // while on aarch64 the dirty bit comes from writing to guest_addr (current PC).
            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: &EventFd, gsi: u32) -> Result<(), Error>[src]

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

Arguments

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

Example

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

pub fn unregister_irqfd(&self, fd: &EventFd, gsi: u32) -> Result<(), Error>[src]

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

Arguments

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

Example

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

pub fn set_irq_line(&self, irq: u32, active: bool) -> Result<(), Error>[src]

Sets the level on the given irq to 1 if active is true, and 0 otherwise.

Arguments

  • irq - IRQ to be set.
  • active - Level of the IRQ input.

Errors

Returns an io::Error when the irq field is invalid

Examples

fn arch_setup(vm_fd: &VmFd) {
    // Arch-specific setup:
    // For x86 architectures, it simply means calling vm.create_irq_chip().unwrap().
    // For Arm architectures, the IRQ controllers need to be setup first.
    // Details please refer to the kernel documentation.
    // https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt
}

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
arch_setup(&vm);
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
    vm.set_irq_line(4, true);
    // ...
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))] {
    vm.set_irq_line(0x01_00_0020, true);
    // ....
}

pub fn create_vcpu(&self, id: u8) -> Result<VcpuFd, Error>[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 unsafe fn create_vcpu_from_rawfd(&self, fd: RawFd) -> Result<VcpuFd, Error>[src]

Creates a VcpuFd object from a vcpu RawFd.

Arguments

  • fd - the RawFd used for creating the VcpuFd 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();
// Create one vCPU with the ID=0.
let vcpu = vm.create_vcpu(0).unwrap();
let rawfd = unsafe { libc::dup(vcpu.as_raw_fd()) };
assert!(rawfd >= 0);
let vcpu = unsafe { vm.create_vcpu_from_rawfd(rawfd).unwrap() };

pub fn create_device(
    &self,
    device: &mut kvm_create_device
) -> Result<DeviceFd, Error>
[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_V2,
    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,
};
// On ARM, creating VGICv3 may fail due to hardware dependency.
// Retry to create VGICv2 in that case.
let device_fd = vm.create_device(&mut device).unwrap_or_else(|_| {
    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
    panic!("Cannot create VFIO device.");
    #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
    {
        device.type_ = kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2;
        vm.create_device(&mut device).expect("Cannot create vGIC device")
    }
});

pub fn enable_cap(&self, cap: &kvm_enable_cap) -> Result<(), Error>[src]

Enable the specified capability as per the KVM_ENABLE_CAP ioctl.

See the documentation for KVM_ENABLE_CAP.

Returns an io::Error when the capability could not be enabled.

Arguments

  • kvm_enable_cap - KVM capability structure. For details check the kvm_enable_cap structure in the KVM API doc.

Example

extern crate kvm_bindings;

use kvm_bindings::{kvm_enable_cap, KVM_CAP_SPLIT_IRQCHIP};

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let mut cap: kvm_enable_cap = Default::default();
// This example cannot enable an arm/aarch64 capability since there
// is no capability available for these architectures.
if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") {
    cap.cap = KVM_CAP_SPLIT_IRQCHIP;
    // As per the KVM documentation, KVM_CAP_SPLIT_IRQCHIP only emulates
    // the local APIC in kernel, expecting that a userspace IOAPIC will
    // be implemented by the VMM.
    // Along with this capability, the user needs to specify the number
    // of pins reserved for the userspace IOAPIC. This number needs to be
    // provided through the first argument of the capability structure, as
    // specified in KVM documentation:
    //     args[0] - number of routes reserved for userspace IOAPICs
    //
    // Because an IOAPIC supports 24 pins, that's the reason why this test
    // picked this number as reference.
    cap.args[0] = 24;
    vm.enable_cap(&cap).unwrap();
}

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

Get the kvm_run size.

pub fn check_extension(&self, c: Cap) -> bool[src]

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 - VM capability to check.

Example

use kvm_ioctls::Cap;

let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
// Check if `KVM_CAP_MP_STATE` is supported.
assert!(vm.check_extension(Cap::MpState));

Trait Implementations

impl AsRawFd for VmFd[src]

Auto Trait Implementations

impl RefUnwindSafe for VmFd

impl Send for VmFd

impl Sync for VmFd

impl Unpin for VmFd

impl UnwindSafe for VmFd

Blanket Implementations

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

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

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

impl<T> From<T> for T[src]

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

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

type Error = Infallible

The type returned in the event of a conversion error.

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

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

The type returned in the event of a conversion error.