[−][src]Struct kvm_ioctls::VmFd
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]
&self,
user_memory_region: kvm_userspace_memory_region
) -> Result<(), Error>
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 thekvm_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]
&self,
irq_routing: &kvm_irq_routing
) -> Result<(), Error>
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
andkvm_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]
&self,
fd: &EventFd,
addr: &IoEventAddress,
datamatch: T
) -> Result<(), Error>
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 usualvmexit
to userspace is prevented.addr
- Address being written to.datamatch
- Limits signalingfd
to only the cases where the value being written is equal to this parameter. The size ofdatamatch
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]
&self,
fd: &EventFd,
addr: &IoEventAddress,
datamatch: T
) -> Result<(), Error>
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]
&self,
slot: u32,
memory_size: usize
) -> Result<Vec<u64>, Error>
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]
&self,
device: &mut kvm_create_device
) -> Result<DeviceFd, Error>
Creates an emulated device in the kernel.
See the documentation for KVM_CREATE_DEVICE
.
Arguments
device
: device configuration. For details check thekvm_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
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]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,