kvm_rs/
kvm_sys.rs

1// SPDX-License-Identifier: MIT
2//
3// Copyright (c) 2021, Johannes Stoelp <dev@memzero.de>
4
5//! Definitions of the system header [`<linux/kvm.h>`][kvm-h].
6//!
7//! [kvm-h]: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/kvm.h
8
9#![allow(non_snake_case)]
10#![allow(non_camel_case_types)]
11#![allow(dead_code)]
12
13// Generated by `build.rs`.
14include!(concat!(env!("OUT_DIR"), "/kvm_constants.rs"));
15
16#[repr(C)]
17#[derive(Default, Debug)]
18pub struct kvm_regs {
19    pub rax: u64,
20    pub rbx: u64,
21    pub rcx: u64,
22    pub rdx: u64,
23    pub rsi: u64,
24    pub rdi: u64,
25    pub rsp: u64,
26    pub rbp: u64,
27    pub r8: u64,
28    pub r9: u64,
29    pub r10: u64,
30    pub r11: u64,
31    pub r12: u64,
32    pub r13: u64,
33    pub r14: u64,
34    pub r15: u64,
35    pub rip: u64,
36    pub rflags: u64,
37}
38
39#[repr(C)]
40#[derive(Default, Debug)]
41pub struct kvm_segment {
42    pub base: u64,
43    pub limit: u32,
44    pub selector: u16,
45    pub type_: u8,
46    pub present: u8,
47    pub dpl: u8,
48    pub db: u8,
49    pub s: u8,
50    pub l: u8,
51    pub g: u8,
52    pub avl: u8,
53    unusable: u8,
54    _padding: u8,
55}
56
57#[repr(C)]
58#[derive(Default, Debug)]
59pub struct kvm_dtable {
60    pub base: u64,
61    pub limit: u16,
62    _padding: [u16; 3],
63}
64
65#[repr(C)]
66#[derive(Default, Debug)]
67pub struct kvm_sregs {
68    pub cs: kvm_segment,
69    pub ds: kvm_segment,
70    pub es: kvm_segment,
71    pub fs: kvm_segment,
72    pub gs: kvm_segment,
73    pub ss: kvm_segment,
74    pub tr: kvm_segment,
75    pub ldt: kvm_segment,
76    pub gdt: kvm_dtable,
77    pub idt: kvm_dtable,
78    pub cr0: u64,
79    pub cr2: u64,
80    pub cr3: u64,
81    pub cr4: u64,
82    pub cr8: u64,
83    pub efer: u64,
84    pub apic_base: u64,
85    pub interrupt_bitmap: [u64; 4],
86}
87
88#[repr(C)]
89#[derive(Default, Debug)]
90pub(crate) struct kvm_userspace_memory_region {
91    pub slot: u32,
92    pub flags: u32,
93    pub guest_phys_addr: u64,
94    pub memory_size: u64,
95    pub userspace_addr: u64,
96}
97
98#[cfg(target_arch = "x86_64")]
99#[repr(C)]
100#[derive(Default, Debug)]
101pub struct kvm_debugregs {
102    pub db: [u64; 4],
103    pub dr6: u64,
104    pub dr7: u64,
105    pub flags: u64,
106    pub reserved: [u64; 9],
107}
108
109#[repr(C)]
110#[derive(Default, Debug)]
111pub(crate) struct kvm_guest_debug {
112    pub control: u32,
113    pad: u32,
114    pub arch: kvm_guest_debug_arch,
115}
116
117#[cfg(target_arch = "x86_64")]
118#[repr(C)]
119#[derive(Default, Debug)]
120pub(crate) struct kvm_guest_debug_arch {
121    pub debugreg: [u64; 8],
122}
123
124#[repr(C)]
125pub(crate) struct kvm_run {
126    request_interrupt_window: u8,
127    immediate_exit: u8,
128    padding1: [u8; 6],
129    pub exit_reason: u32,
130    ready_for_interrupt_injection: u8,
131    if_flag: u8,
132    flags: u16,
133    cr8: u64,
134    apic_base: u64,
135    pub inner: kvm_run_union,
136    kvm_valid_regs: u64,
137    kvm_dirty_regs: u64,
138    s: kvm_run_union_s,
139}
140
141#[repr(C)]
142#[derive(Copy, Clone, Debug)]
143pub(crate) struct kvm_run_io {
144    pub direction: u8,
145    pub size: u8,
146    pub port: u16,
147    pub count: u32,
148    pub data_offset: u64,
149}
150
151#[repr(C)]
152#[derive(Copy, Clone, Debug)]
153pub(crate) struct kvm_run_mmio {
154    pub phys_addr: u64,
155    pub data: [u8; 8],
156    pub len: u32,
157    pub is_write: u8,
158}
159
160#[cfg(target_arch = "x86_64")]
161#[repr(C)]
162#[derive(Copy, Clone, Debug)]
163pub(crate) struct kvm_run_debug {
164    pub exception: u32,
165    pad: u32,
166    pub pc: u64,
167    pub dr6: u64,
168    pub dr7: u64,
169}
170
171// Only add the union fields used here.
172#[repr(C)]
173pub(crate) union kvm_run_union {
174    pub io: kvm_run_io,
175    pub mmio: kvm_run_mmio,
176    pub debug: kvm_run_debug,
177    padding: [u8; 256],
178}
179
180// Only add the union fields used here.
181#[repr(C)]
182union kvm_run_union_s {
183    padding: [u8; 2048],
184}
185
186#[cfg(test)]
187mod tests {
188    use super::*;
189    use std::mem;
190
191    #[test]
192    fn check_kvm_regs() {
193        assert_eq!(mem::size_of::<kvm_regs>(), TEST_KVM_REGS_SIZE);
194        assert_eq!(mem::align_of::<kvm_regs>(), TEST_KVM_REGS_ALIGN);
195    }
196
197    #[test]
198    fn check_kvm_segment() {
199        assert_eq!(mem::size_of::<kvm_segment>(), TEST_KVM_SEGMENT_SIZE);
200        assert_eq!(mem::align_of::<kvm_segment>(), TEST_KVM_SEGMENT_ALIGN);
201    }
202
203    #[test]
204    fn check_kvm_dtable() {
205        assert_eq!(mem::size_of::<kvm_dtable>(), TEST_KVM_DTABLE_SIZE);
206        assert_eq!(mem::align_of::<kvm_dtable>(), TEST_KVM_DTABLE_ALIGN);
207    }
208
209    #[test]
210    fn check_kvm_sregs() {
211        assert_eq!(mem::size_of::<kvm_sregs>(), TEST_KVM_SREGS_SIZE);
212        assert_eq!(mem::align_of::<kvm_sregs>(), TEST_KVM_SREGS_ALIGN);
213        assert_eq!(
214            mem::size_of_val(&kvm_sregs::default().interrupt_bitmap),
215            TEST_KVM_SREGS_INTERRTUP_BITMAP_SIZE
216        );
217    }
218
219    #[test]
220    fn check_kvm_userspace_memory_region() {
221        assert_eq!(
222            mem::size_of::<kvm_userspace_memory_region>(),
223            TEST_KVM_USERSPACE_MEMORY_REGION_SIZE
224        );
225        assert_eq!(
226            mem::align_of::<kvm_userspace_memory_region>(),
227            TEST_KVM_USERSPACE_MEMORY_REGION_ALIGN
228        );
229    }
230
231    #[test]
232    fn check_kvm_run() {
233        assert_eq!(mem::size_of::<kvm_run>(), TEST_KVM_RUN_SIZE);
234        assert_eq!(mem::align_of::<kvm_run>(), TEST_KVM_RUN_ALIGN);
235        assert_eq!(mem::size_of::<kvm_run_io>(), TEST_KVM_RUN_IO_SIZE);
236        assert_eq!(mem::size_of::<kvm_run_mmio>(), TEST_KVM_RUN_MMIO_SIZE);
237        assert_eq!(mem::size_of::<kvm_run_union_s>(), TEST_KVM_RUN_UNION_S_SIZE);
238    }
239
240    #[cfg(target_arch = "x86_64")]
241    #[test]
242    fn check_kvm_run_x86() {
243        assert_eq!(mem::size_of::<kvm_run_debug>(), TEST_KVM_RUN_DEBUG_SIZE);
244    }
245
246    #[cfg(target_arch = "x86_64")]
247    #[test]
248    fn check_kvm_debugregs() {
249        assert_eq!(mem::size_of::<kvm_debugregs>(), TEST_KVM_DEBUGREGS_SIZE);
250        assert_eq!(mem::align_of::<kvm_debugregs>(), TEST_KVM_DEBUGREGS_ALIGN);
251    }
252
253    #[test]
254    fn check_kvm_guest_dbg() {
255        assert_eq!(mem::size_of::<kvm_guest_debug>(), TEST_KVM_GUEST_DEBUG_SIZE);
256        assert_eq!(
257            mem::align_of::<kvm_guest_debug>(),
258            TEST_KVM_GUEST_DEBUG_ALIGN
259        );
260    }
261
262    #[cfg(target_arch = "x86_64")]
263    #[test]
264    fn check_kvm_guest_dbg_arch() {
265        assert_eq!(
266            mem::size_of::<kvm_guest_debug_arch>(),
267            TEST_KVM_GUEST_DEBUG_ARCH_SIZE
268        );
269        assert_eq!(
270            mem::align_of::<kvm_guest_debug_arch>(),
271            TEST_KVM_GUEST_DEBUG_ARCH_ALIGN
272        );
273    }
274}