aboutsummaryrefslogblamecommitdiffhomepage
path: root/src/kvm_sys.rs
blob: 8d5c85b8e845d603d0d69bf2aeea73c093f1dcbc (plain) (tree)























































































































































































































































                                                                                 
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(dead_code)]

// Generated by `build.rs`.
include!(concat!(env!("OUT_DIR"), "/kvm_constants.rs"));

use std::fmt;

#[repr(C)]
#[derive(Default, Debug)]
pub struct Rflags(pub u64);

#[repr(C)]
#[derive(Default, Debug)]
pub struct kvm_regs {
    pub rax: u64,
    pub rbx: u64,
    pub rcx: u64,
    pub rdx: u64,
    pub rsi: u64,
    pub rdi: u64,
    pub rsp: u64,
    pub rbp: u64,
    pub r8: u64,
    pub r9: u64,
    pub r10: u64,
    pub r11: u64,
    pub r12: u64,
    pub r13: u64,
    pub r14: u64,
    pub r15: u64,
    pub rip: u64,
    pub rflags: Rflags,
}

#[repr(C)]
#[derive(Default, Debug)]
pub struct kvm_segment {
    pub base: u64,
    pub limit: u32,
    pub selector: u16,
    pub type_: u8,
    pub present: u8,
    pub dpl: u8,
    pub db: u8,
    pub s: u8,
    pub l: u8,
    pub g: u8,
    pub avl: u8,
    unusable: u8,
    _padding: u8,
}

#[repr(C)]
#[derive(Default, Debug)]
pub struct kvm_dtable {
    pub base: u64,
    pub limit: u16,
    _padding: [u16; 3],
}

#[repr(C)]
#[derive(Default, Debug)]
pub struct kvm_sregs {
    pub cs: kvm_segment,
    pub ds: kvm_segment,
    pub es: kvm_segment,
    pub fs: kvm_segment,
    pub gs: kvm_segment,
    pub ss: kvm_segment,
    pub tr: kvm_segment,
    pub ldt: kvm_segment,
    pub gdt: kvm_dtable,
    pub idt: kvm_dtable,
    pub cr0: u64,
    cr2: u64,
    pub cr3: u64,
    pub cr4: u64,
    pub cr8: u64,
    pub effer: u64,
    pub apic_base: u64,
    pub interrupt_bitmap: [u64; 4],
}

#[repr(C)]
#[derive(Default, Debug)]
pub(crate) struct kvm_userspace_memory_region {
    pub slot: u32,
    pub flags: u32,
    pub guest_phys_addr: u64,
    pub memory_size: u64,
    pub userspace_addr: u64,
}

#[repr(C)]
pub(crate) struct kvm_run {
    request_interrupt_window: u8,
    immediate_exit: u8,
    padding1: [u8; 6],
    pub exit_reason: u32,
    ready_for_interrupt_injection: u8,
    if_flag: u8,
    flags: u16,
    cr8: u64,
    apic_base: u64,
    pub inner: kvm_run_union,
    kvm_valid_regs: u64,
    kvm_dirty_regs: u64,
    s: kvm_run_union_s,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub(crate) struct kvm_run_io {
    pub direction: u8,
    pub size: u8,
    pub port: u16,
    pub count: u32,
    pub data_offset: u64,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub(crate) struct kvm_run_mmio {
    pub phys_addr: u64,
    pub data: [u8; 8],
    pub len: u32,
    pub is_write: u8,
}

// Only add the union fields used here.
#[repr(C)]
pub(crate) union kvm_run_union {
    pub io: kvm_run_io,
    pub mmio: kvm_run_mmio,
    padding: [u8; 256],
}

// Only add the union fields used here.
#[repr(C)]
union kvm_run_union_s {
    padding: [u8; 2048],
}

// {{{ Display : Rflags

impl fmt::Display for Rflags {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let IF = || (self.0 >> 9) & 0b1;
        let IOPL = || (self.0 >> 12) & 0b11;
        let AC = || (self.0 >> 19) & 0b1;
        write!(f, "AC({}) IOPL({}) IF({})", AC(), IOPL(), IF())
    }
}

// }}}
// {{{ Display : kvm_regs

impl fmt::Display for kvm_regs {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "rax: {:#018x} rbx: {:#018x} rcx: {:#018x} rdx: {:#018x}\n\
             rsi: {:#018x} rdi: {:#018x}\n\
             r8 : {:#018x} r9 : {:#018x} r10: {:#018x} r11: {:#018x}\n\
             r12: {:#018x} r13: {:#018x} r14: {:#018x} r15: {:#018x}\n\
             rsp: {:#018x} rbp: {:#018x}\n\
             rip: {:#018x} rflags: {:#018x} [{}]",
            self.rax,
            self.rbx,
            self.rcx,
            self.rdx,
            self.rsi,
            self.rdi,
            self.r8,
            self.r9,
            self.r10,
            self.r11,
            self.r12,
            self.r13,
            self.r14,
            self.r15,
            self.rsp,
            self.rbp,
            self.rip,
            self.rflags.0,
            self.rflags
        )
    }
}

// }}}

#[cfg(test)]
mod tests {
    use super::*;
    use std::mem;

    #[test]
    fn check_kvm_regs() {
        assert_eq!(mem::size_of::<kvm_regs>(), TEST_KVM_REGS_SIZE);
        assert_eq!(mem::align_of::<kvm_regs>(), TEST_KVM_REGS_ALIGN);
    }

    #[test]
    fn check_kvm_segment() {
        assert_eq!(mem::size_of::<kvm_segment>(), TEST_KVM_SEGMENT_SIZE);
        assert_eq!(mem::align_of::<kvm_segment>(), TEST_KVM_SEGMENT_ALIGN);
    }

    #[test]
    fn check_kvm_dtable() {
        assert_eq!(mem::size_of::<kvm_dtable>(), TEST_KVM_DTABLE_SIZE);
        assert_eq!(mem::align_of::<kvm_dtable>(), TEST_KVM_DTABLE_ALIGN);
    }

    #[test]
    fn check_kvm_sregs() {
        assert_eq!(mem::size_of::<kvm_sregs>(), TEST_KVM_SREGS_SIZE);
        assert_eq!(mem::align_of::<kvm_sregs>(), TEST_KVM_SREGS_ALIGN);
        assert_eq!(
            mem::size_of_val(&kvm_sregs::default().interrupt_bitmap),
            TEST_KVM_SREGS_INTERRTUP_BITMAP_SIZE
        );
    }

    #[test]
    fn check_kvm_userspace_memory_region() {
        assert_eq!(
            mem::size_of::<kvm_userspace_memory_region>(),
            TEST_KVM_USERSPACE_MEMORY_REGION_SIZE
        );
        assert_eq!(
            mem::align_of::<kvm_userspace_memory_region>(),
            TEST_KVM_USERSPACE_MEMORY_REGION_ALIGN
        );
    }

    #[test]
    fn check_kvm_run() {
        assert_eq!(mem::size_of::<kvm_run>(), TEST_KVM_RUN_SIZE);
        assert_eq!(mem::align_of::<kvm_run>(), TEST_KVM_RUN_ALIGN);
        assert_eq!(mem::size_of::<kvm_run_io>(), TEST_KVM_RUN_IO_SIZE);
        assert_eq!(mem::size_of::<kvm_run_mmio>(), TEST_KVM_RUN_MMIO_SIZE);
        assert_eq!(mem::size_of::<kvm_run_union_s>(), TEST_KVM_RUN_UNION_S_SIZE);
    }
}