Struct Kvm

Source
pub struct Kvm { /* private fields */ }
Expand description

Represents the kernel’s whole KVM subsystem.

This is the entry point for obtaining all other KVM objects, whether directly or indirectly.

Implementations§

Source§

impl Kvm

Source

pub fn open() -> Result<Self>

Opens the KVM device /dev/kvm and returns a Kvm instance wrapping it.

Fails with an error on a system where /dev/kvm doesn’t exist for some reason, such as if KVM is not enabled in the kernel.

Warning: The safety of this function relies on there being a reasonable device node at /dev/kvm. If the target system has some other unrelated device node or a non-device entry at that location then the returned object will allow issuing ioctl requests to that file that may cause memory corruption depending on how the opened device reacts to the KVM ioctl numbers.

This function is not marked as unsafe because a system configured in that way is considered unreasonable, and this crate is optimized for reasonable Linux configurations that follow the filesystem layout given in the kernel documentation.

Examples found in repository?
examples/kvm-vm-setup.rs (line 8)
7fn run() -> linux_io::result::Result<()> {
8    let kvm = Kvm::open()?;
9    println!("opened KVM subsystem: {:?}", &kvm);
10    let version = kvm.get_api_version()?;
11    if version != 12 {
12        eprintln!("unsupported KVM API version {}", version);
13        return Err(linux_io::result::Error::new(25));
14    }
15    let mut vm = kvm.create_vm()?;
16    println!("created a VM: {:?}", &vm);
17
18    let mut mem = MemoryRegion::new(0x1000)?;
19    println!("created a memory region: {:?}", &mem);
20
21    {
22        let mem_data = mem.as_mut_slice();
23
24        #[cfg(target_arch = "x86_64")]
25        {
26            // "UD2" explicitly-undefined instruction
27            mem_data[0] = 0x0f;
28            mem_data[1] = 0x0b;
29        }
30
31        #[cfg(target_arch = "aarch64")]
32        {
33            // "udf" explicitly-undefined instruction
34            mem_data[0] = 0x01;
35            mem_data[1] = 0x00;
36            mem_data[2] = 0x00;
37            mem_data[3] = 0x00;
38        }
39    }
40
41    vm.set_guest_memory_region(0, KVM_MEM_READONLY, 0x1000, &mut mem)?;
42    println!("registered the memory region with the VM");
43
44    let cpu = vm.create_vcpu(0)?;
45    println!("created a VCPU: {:?}", &cpu);
46    let mut runner = cpu.to_runner()?;
47    println!("created a VCPU runner: {:?}", &runner);
48    runner.with_raw_run_state(|state| println!("run state: {:?}", &state));
49
50    runner.modify_regs(|regs| {
51        #[cfg(target_arch = "x86_64")]
52        {
53            regs.rip = 0x1000;
54        }
55        #[cfg(target_arch = "aarch64")]
56        {
57            regs.regs.pc = 0x1000;
58        }
59    })?;
60    println!("set initial register values");
61
62    #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
63    {
64        runner.run_raw()?;
65        runner.with_raw_run_state(|state| println!("run state after running: {:?}", &state));
66        let regs = runner.get_regs()?;
67        println!("registers after running: {:?}", &regs)
68    }
69
70    Ok(())
71}
Source

pub const fn from_file(f: File<KvmSystem>) -> Self

Wraps the given already-opened file in a Kvm object.

Source

pub fn get_api_version(&self) -> Result<int>

Identifies the version of the KVM API used by the current kernel.

The stable API always returns version 12. The kernel documentation suggests that applications should always call this and refuse to run if it returns any value other than that; the version number is not expected to change in the future because future API additions will use Self::check_extension instead.

Examples found in repository?
examples/kvm-vm-setup.rs (line 10)
7fn run() -> linux_io::result::Result<()> {
8    let kvm = Kvm::open()?;
9    println!("opened KVM subsystem: {:?}", &kvm);
10    let version = kvm.get_api_version()?;
11    if version != 12 {
12        eprintln!("unsupported KVM API version {}", version);
13        return Err(linux_io::result::Error::new(25));
14    }
15    let mut vm = kvm.create_vm()?;
16    println!("created a VM: {:?}", &vm);
17
18    let mut mem = MemoryRegion::new(0x1000)?;
19    println!("created a memory region: {:?}", &mem);
20
21    {
22        let mem_data = mem.as_mut_slice();
23
24        #[cfg(target_arch = "x86_64")]
25        {
26            // "UD2" explicitly-undefined instruction
27            mem_data[0] = 0x0f;
28            mem_data[1] = 0x0b;
29        }
30
31        #[cfg(target_arch = "aarch64")]
32        {
33            // "udf" explicitly-undefined instruction
34            mem_data[0] = 0x01;
35            mem_data[1] = 0x00;
36            mem_data[2] = 0x00;
37            mem_data[3] = 0x00;
38        }
39    }
40
41    vm.set_guest_memory_region(0, KVM_MEM_READONLY, 0x1000, &mut mem)?;
42    println!("registered the memory region with the VM");
43
44    let cpu = vm.create_vcpu(0)?;
45    println!("created a VCPU: {:?}", &cpu);
46    let mut runner = cpu.to_runner()?;
47    println!("created a VCPU runner: {:?}", &runner);
48    runner.with_raw_run_state(|state| println!("run state: {:?}", &state));
49
50    runner.modify_regs(|regs| {
51        #[cfg(target_arch = "x86_64")]
52        {
53            regs.rip = 0x1000;
54        }
55        #[cfg(target_arch = "aarch64")]
56        {
57            regs.regs.pc = 0x1000;
58        }
59    })?;
60    println!("set initial register values");
61
62    #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
63    {
64        runner.run_raw()?;
65        runner.with_raw_run_state(|state| println!("run state after running: {:?}", &state));
66        let regs = runner.get_regs()?;
67        println!("registers after running: {:?}", &regs)
68    }
69
70    Ok(())
71}
Source

pub fn check_extension(&self, ext: int) -> Result<int>

Query whether the KVM subsystem in the current kernel supports a particular extension.

A result of zero indicates a lack of support while nonzero indicates support. The nonzero value may carry additional meanings for some extensions.

Source

pub fn create_vm(&self) -> Result<VirtualMachine<'_>>

Create a new virtual machine.

Examples found in repository?
examples/kvm-vm-setup.rs (line 15)
7fn run() -> linux_io::result::Result<()> {
8    let kvm = Kvm::open()?;
9    println!("opened KVM subsystem: {:?}", &kvm);
10    let version = kvm.get_api_version()?;
11    if version != 12 {
12        eprintln!("unsupported KVM API version {}", version);
13        return Err(linux_io::result::Error::new(25));
14    }
15    let mut vm = kvm.create_vm()?;
16    println!("created a VM: {:?}", &vm);
17
18    let mut mem = MemoryRegion::new(0x1000)?;
19    println!("created a memory region: {:?}", &mem);
20
21    {
22        let mem_data = mem.as_mut_slice();
23
24        #[cfg(target_arch = "x86_64")]
25        {
26            // "UD2" explicitly-undefined instruction
27            mem_data[0] = 0x0f;
28            mem_data[1] = 0x0b;
29        }
30
31        #[cfg(target_arch = "aarch64")]
32        {
33            // "udf" explicitly-undefined instruction
34            mem_data[0] = 0x01;
35            mem_data[1] = 0x00;
36            mem_data[2] = 0x00;
37            mem_data[3] = 0x00;
38        }
39    }
40
41    vm.set_guest_memory_region(0, KVM_MEM_READONLY, 0x1000, &mut mem)?;
42    println!("registered the memory region with the VM");
43
44    let cpu = vm.create_vcpu(0)?;
45    println!("created a VCPU: {:?}", &cpu);
46    let mut runner = cpu.to_runner()?;
47    println!("created a VCPU runner: {:?}", &runner);
48    runner.with_raw_run_state(|state| println!("run state: {:?}", &state));
49
50    runner.modify_regs(|regs| {
51        #[cfg(target_arch = "x86_64")]
52        {
53            regs.rip = 0x1000;
54        }
55        #[cfg(target_arch = "aarch64")]
56        {
57            regs.regs.pc = 0x1000;
58        }
59    })?;
60    println!("set initial register values");
61
62    #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
63    {
64        runner.run_raw()?;
65        runner.with_raw_run_state(|state| println!("run state after running: {:?}", &state));
66        let regs = runner.get_regs()?;
67        println!("registers after running: {:?}", &regs)
68    }
69
70    Ok(())
71}
Source

pub fn get_vcpu_mmap_size(&self) -> Result<int>

Determine the size of the shared memory regions that will be used between kernel and userspace for each VCPU.

Trait Implementations§

Source§

impl Debug for Kvm

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Kvm

§

impl RefUnwindSafe for Kvm

§

impl Send for Kvm

§

impl Sync for Kvm

§

impl Unpin for Kvm

§

impl UnwindSafe for Kvm

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.