Struct linux_kvm::VirtualCpu

source ·
pub struct VirtualCpu<'a> { /* private fields */ }
Expand description

A virtual CPU belonging to a VirtualMachine.

Implementations§

source§

impl<'a> VirtualCpu<'a>

source

pub fn get_regs(&self) -> Result<kvm_regs>

Get the architecture-specific representation of the current register values of this vCPU.

source

pub fn set_regs(&self, new: &kvm_regs) -> Result<()>

Set the architecture-specific representation of the current register values of this vCPU.

source

pub fn to_runner(self) -> Result<VirtualCpuRunner<'a>>

Wrap this CPU into an object that has the necessary extra state to run it.

This encapsulates the step of using mmap on the VCPU file descriptor to establish a shared memory space with the KVM subsystem, so failure here represents failure of either that mmap operation or the ioctl call to discover its parameters.

Examples found in repository?
examples/kvm-vm-setup.rs (line 46)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn run() -> linux_io::result::Result<()> {
    let kvm = Kvm::open()?;
    println!("opened KVM subsystem: {:?}", &kvm);
    let version = kvm.get_api_version()?;
    if version != 12 {
        eprintln!("unsupported KVM API version {}", version);
        return Err(linux_io::result::Error::new(25));
    }
    let mut vm = kvm.create_vm()?;
    println!("created a VM: {:?}", &vm);

    let mut mem = MemoryRegion::new(0x1000)?;
    println!("created a memory region: {:?}", &mem);

    {
        let mem_data = mem.as_mut_slice();

        #[cfg(target_arch = "x86_64")]
        {
            // "UD2" explicitly-undefined instruction
            mem_data[0] = 0x0f;
            mem_data[1] = 0x0b;
        }

        #[cfg(target_arch = "aarch64")]
        {
            // "udf" explicitly-undefined instruction
            mem_data[0] = 0x01;
            mem_data[1] = 0x00;
            mem_data[2] = 0x00;
            mem_data[3] = 0x00;
        }
    }

    vm.set_guest_memory_region(0, KVM_MEM_READONLY, 0x1000, &mut mem)?;
    println!("registered the memory region with the VM");

    let cpu = vm.create_vcpu(0)?;
    println!("created a VCPU: {:?}", &cpu);
    let mut runner = cpu.to_runner()?;
    println!("created a VCPU runner: {:?}", &runner);
    runner.with_raw_run_state(|state| println!("run state: {:?}", &state));

    runner.modify_regs(|regs| {
        #[cfg(target_arch = "x86_64")]
        {
            regs.rip = 0x1000;
        }
        #[cfg(target_arch = "aarch64")]
        {
            regs.regs.pc = 0x1000;
        }
    })?;
    println!("set initial register values");

    #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
    {
        runner.run_raw()?;
        runner.with_raw_run_state(|state| println!("run state after running: {:?}", &state));
        let regs = runner.get_regs()?;
        println!("registers after running: {:?}", &regs)
    }

    Ok(())
}

Trait Implementations§

source§

impl<'a> Debug for VirtualCpu<'a>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for VirtualCpu<'a>

§

impl<'a> RefUnwindSafe for VirtualCpu<'a>

§

impl<'a> Send for VirtualCpu<'a>

§

impl<'a> Sync for VirtualCpu<'a>

§

impl<'a> Unpin for VirtualCpu<'a>

§

impl<'a> UnwindSafe for VirtualCpu<'a>

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>,

§

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>,

§

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.