linux_kvm/
raw.rs

1//! Raw data types for use with various KVM `ioctl` requests.
2
3/// The layout of the shared memory region used to communicate with the
4/// `KVM_RUN` ioctl request, which is `mmap`ed from the VCPU's file descriptor.
5#[allow(non_camel_case_types)]
6#[derive(Clone, Copy, Debug)]
7#[repr(C)]
8pub struct kvm_run {
9    pub request_interrupt_window: u8,
10    pub immediate_exit: u8,
11    pub padding1: [u8; 6],
12    pub exit_reason: u32,
13    pub ready_for_interrupt_injection: u8,
14    pub if_flag: u8,
15    pub flags: u16,
16    pub cr8: u64,
17    pub apic_base: u64,
18    pub exit_details: ExitDetails,
19}
20
21#[allow(non_camel_case_types)]
22#[derive(Clone, Copy, Debug)]
23#[repr(C)]
24pub struct kvm_userspace_memory_region {
25    pub slot: u32,
26    pub flags: u32,
27    pub guest_phys_addr: u64,
28    pub memory_size: u64,    // in bytes
29    pub userspace_addr: u64, // start of the userspace allocated memory
30}
31
32#[cfg(target_arch = "x86_64")]
33#[allow(non_camel_case_types)]
34#[derive(Clone, Copy, Debug)]
35#[repr(C)]
36pub struct kvm_regs {
37    pub rax: u64,
38    pub rbx: u64,
39    pub rcx: u64,
40    pub rdx: u64,
41    pub rsi: u64,
42    pub rdi: u64,
43    pub rsp: u64,
44    pub rbp: u64,
45    pub r8: u64,
46    pub r9: u64,
47    pub r10: u64,
48    pub r11: u64,
49    pub r12: u64,
50    pub r13: u64,
51    pub r14: u64,
52    pub r15: u64,
53    pub rip: u64,
54    pub rflags: u64,
55}
56
57#[cfg(target_arch = "aarch64")]
58#[allow(non_camel_case_types)]
59#[derive(Clone, Copy, Debug)]
60#[repr(C)]
61pub struct kvm_regs {
62    pub regs: aarch64_user_pt_regs,
63    pub sp_el1: u64,
64    pub elr_el1: u64,
65    pub spsr: [u64; 5],
66    pub fp_regs: aarch64_user_fpsimd_state,
67}
68
69#[cfg(target_arch = "aarch64")]
70#[allow(non_camel_case_types)]
71#[derive(Clone, Copy, Debug)]
72#[repr(C)]
73pub struct aarch64_user_pt_regs {
74    pub regs: [u64; 31],
75    pub sp: u64,
76    pub pc: u64,
77    pub pstate: u64,
78}
79
80#[cfg(target_arch = "aarch64")]
81#[allow(non_camel_case_types)]
82#[derive(Clone, Copy, Debug)]
83#[repr(C)]
84pub struct aarch64_user_fpsimd_state {
85    pub vregs: [u128; 32],
86    pub fpsr: u32,
87    pub fpcr: u32,
88    pub __reserved: [u32; 2],
89}
90
91#[cfg(target_arch = "riscv64")]
92#[allow(non_camel_case_types)]
93#[derive(Clone, Copy, Debug)]
94#[repr(C)]
95pub struct kvm_regs {
96    // The RISC-V port does not support getting/setting
97    // all registers together. It only supports individual
98    // register accesses using the GET_REG/SET_REG operations.
99}
100
101/// Used for the `exit_details` field of [`kvm_run`].
102#[derive(Clone, Copy)]
103#[repr(C)]
104pub union ExitDetails {
105    pub hw: ExitUnknown,
106    pub fail_entry: ExitFailEntry,
107    pub ex: ExitException,
108    pub io: ExitIo,
109    pub mmio: ExitMmio,
110    // TODO: The rest of these
111    pub padding: [linux_unsafe::char; 256],
112}
113
114impl core::fmt::Debug for ExitDetails {
115    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
116        f.debug_struct("ExitDetails").finish()
117    }
118}
119
120#[derive(Clone, Copy, Debug)]
121#[repr(C)]
122pub struct ExitUnknown {
123    pub hardware_exit_reason: u64,
124}
125
126#[derive(Clone, Copy, Debug)]
127#[repr(C)]
128pub struct ExitFailEntry {
129    pub hardware_entry_failure_reason: u64,
130    pub cpu: u32,
131}
132
133#[derive(Clone, Copy, Debug)]
134#[repr(C)]
135pub struct ExitException {
136    pub exception: u32,
137    pub error_code: u32,
138}
139
140#[derive(Clone, Copy, Debug)]
141#[repr(C)]
142pub struct ExitIo {
143    pub direction: u8,
144    pub size: u8,
145    pub port: u16,
146    pub count: u32,
147    pub data_offset: u64,
148}
149
150#[derive(Clone, Copy, Debug)]
151#[repr(C)]
152pub struct ExitMmio {
153    pub phys_addr: u64,
154    pub data: [u8; 8],
155    pub len: u32,
156    pub is_write: u8,
157}