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
impl Kvm
Sourcepub fn open() -> Result<Self>
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?
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: {:?}", ®s)
68 }
69
70 Ok(())
71}
Sourcepub const fn from_file(f: File<KvmSystem>) -> Self
pub const fn from_file(f: File<KvmSystem>) -> Self
Wraps the given already-opened file in a Kvm
object.
Sourcepub fn get_api_version(&self) -> Result<int>
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?
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: {:?}", ®s)
68 }
69
70 Ok(())
71}
Sourcepub fn check_extension(&self, ext: int) -> Result<int>
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.
Sourcepub fn create_vm(&self) -> Result<VirtualMachine<'_>>
pub fn create_vm(&self) -> Result<VirtualMachine<'_>>
Create a new virtual machine.
Examples found in repository?
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: {:?}", ®s)
68 }
69
70 Ok(())
71}
Sourcepub fn get_vcpu_mmap_size(&self) -> Result<int>
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.