libvmm 0.1.0

Virtual Machine Monitor
.equ RDI, 0x00
.equ RAX, 0x08
.equ RBX, 0x10
.equ RCX, 0x18
.equ RDX, 0x20
.equ RSI, 0x28
.equ RBP, 0x30
.equ R8,  0x38
.equ R9,  0x40
.equ R10, 0x48
.equ R11, 0x50
.equ R12, 0x58
.equ R13, 0x60
.equ R14, 0x68
.equ R15, 0x70

.macro restore_host_regs
    pop %rdi
    pop %r15
    pop %r14
    pop %r13
    pop %r12
    pop %rbp
    pop %rbx
.endmacro

.macro vmx instruction
.global vmx_\instruction
vmx_\instruction:
    /// save host state
    push %rbx
    push %rbp
    push %r12
    push %r13
    push %r14
    push %r15

    /// &guest_regs, push last. It is used in guest save later.
    push %rdi;

    /// set return stack
    mov $0x00006c14, %rax
    vmwrite %rsp, %rax

    /// restore guest state without affecting the result of cmp
    mov RAX(%rdi), %rax
    mov RBX(%rdi), %rbx
    mov RCX(%rdi), %rcx
    mov RDX(%rdi), %rdx
    mov RSI(%rdi), %rsi
    mov RBP(%rdi), %rbp
    mov R8(%rdi),  %r8
    mov R9(%rdi),  %r9
    mov R10(%rdi), %r10
    mov R11(%rdi), %r11
    mov R12(%rdi), %r12
    mov R13(%rdi), %r13
    mov R14(%rdi), %r14
    mov R15(%rdi), %r15

    /// Now kill %rsi which contains the guest_regs.
    mov RDI(%rdi), %rdi

    \instruction

    /// If we are here, vmlaunch/vmresume failed
    restore_host_regs
    xor %rax, %rax
    retq
.endmacro

.code64

.global vmx_return

vmx vmlaunch
vmx vmresume

vmx_return:
    /// save it for now
    push %rdi

    /// get the guest_regs register
    mov 0x8(%rsp), %rdi

    /// save guest state
    mov %rax, RAX(%rdi)
    mov %rbx, RBX(%rdi)
    mov %rcx, RCX(%rdi)
    mov %rdx, RDX(%rdi)
    mov %rsi, RSI(%rdi)
    mov %rbp, RBP(%rdi)
    mov %r8,  R8(%rdi)
    mov %r9,  R9(%rdi)
    mov %r10, R10(%rdi)
    mov %r11, R11(%rdi)
    mov %r12, R12(%rdi)
    mov %r13, R13(%rdi)
    mov %r14, R14(%rdi)
    mov %r15, R15(%rdi)
    mov 0x0(%rsp), %rax /// get guest %rdi from stack
    mov %rax, RDI(%rdi)

    add $0x8, %rsp
    restore_host_regs

    /// VMLAUNCH/VMRESUME was successful
    mov $1, %rax
    retq;