# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.21 $
+# $Revision: 1.22 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
bget.c malloc.c \
synch.c kthread.c \
serial.c reboot.c \
- paging.c vm_guest.c \
- svm.c svm_handler.c vmm.c vmm_util.c vmm_stubs.c svm_ctrl_regs.c \
- vmcb.c vmm_mem.c vmm_paging.c vmm_io.c vmm_debug.c svm_io.c \
- vmm_shadow_paging.c vm_guest_mem.c \
- debug.c vmx.c vmcs_gen.c vmcs.c\
+ paging.c \
+ debug.c vmm_stubs.c vm.c\
main.c
# Kernel object files built from C source files
KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
# Kernel assembly files
-KERNEL_ASM_SRCS := lowlevel.asm vmx_lowlevel.asm svm_lowlevel.asm
+KERNEL_ASM_SRCS := lowlevel.asm
KERNEL_GAS_SRCS := testvm.s
# Common library object files.
COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
+VMM_ASM_SRCS := svm_lowlevel.asm \
+# vmx_lowlevel.asm
+
+VMM_ASM_OBJS := $(VMM_ASM_SRCS:%.asm=palacios/%.o)
+
+
+VMM_C_SRCS := vm_guest.c \
+ svm.c svm_handler.c vmm.c vmm_util.c svm_ctrl_regs.c \
+ vmcb.c vmm_mem.c vmm_paging.c vmm_io.c vmm_debug.c svm_io.c \
+ vmm_shadow_paging.c vm_guest_mem.c #\
+# vmx.c vmcs_gen.c vmcs.c
+
+VMM_C_OBJS := $(VMM_C_SRCS:%.c=palacios/%.o)
+
+VMM_OBJS := $(VMM_C_OBJS) $(VMM_ASM_OBJS)
# Flags used for kernel C source files
CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include
+# Flags used for VMM C source files
+CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include
+
+# Flags used for VMM C ASM files
+NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
+
# Flags user for kernel assembly files
NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
common/%.o : common/%.c
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
+palacios/%.o : palacios/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o palacios/$*.o
+
+palacios/%.o : palacios/%.asm
+ $(NASM) $(NASM_VMM_OPTS) $< -o palacios/$*.o
+
# ----------------------------------------------------------------------
# Targets -
# Specifies files to be built
all : $(ALL_TARGETS)
-geekos/vmx_lowlevel.o: $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm
- $(NASM) -O99 \
- -f elf \
- -I$(PROJECT_ROOT)/src/geekos/ \
- $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm \
- -o $@
+#geekos/vmx_lowlevel.o: $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm
+# $(NASM) -O99 \
+# -f elf \
+# -I$(PROJECT_ROOT)/src/geekos/ \
+# $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm \
+# -o $@
-geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
- $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
+#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
+# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
# Standard floppy image - just boots the kernel
fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin vm_kernel
$(PAD) $@ 512
# The kernel executable and symbol map.
-geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS)
+geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS)
$(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
- $(KERNEL_OBJS) $(COMMON_C_OBJS)
+ $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS)
$(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
-vmm_mem_test: geekos/vmm_mem.c
- $(HOST_CC) -m32 -o mem_test -DVMM_MEM_TEST -I../include ../src/geekos/vmm_mem.c
-
# Clean build directories of generated files
clean :
- for d in geekos common libc user tools; do \
+ for d in geekos common libc user tools palacios; do \
(cd $$d && rm -f *); \
done
$(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
| $(PERL) -n -e 's,^(\S),common/$$1,;print' \
>> depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(VMM_C_SRCS:%.c=$(PROJECT_ROOT)/src/palacios/%.c) \
+ | $(PERL) -n -e 's,^(\S),palacios/$$1,;print' \
+ >> depend.mak
# By default, there are no header file dependencies.
depend.mak :
+geekos/idt.o: ../src/geekos/idt.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/idt.h \
+ ../include/geekos/int.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h ../include/geekos/debug.h
+geekos/int.o: ../src/geekos/int.c ../include/geekos/idt.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h ../include/geekos/debug.h \
+ ../include/geekos/cpu.h
+geekos/trap.o: ../src/geekos/trap.c ../include/geekos/idt.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/kthread.h \
+ ../include/geekos/list.h ../include/geekos/trap.h \
+ ../include/geekos/serial.h ../include/geekos/irq.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h ../include/geekos/debug.h
+geekos/irq.o: ../src/geekos/irq.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/idt.h ../include/geekos/int.h \
+ ../include/geekos/defs.h ../include/geekos/io.h ../include/geekos/irq.h
+geekos/io.o: ../src/geekos/io.c ../include/geekos/io.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h
+geekos/blockdev.o: ../src/geekos/blockdev.c ../include/geekos/errno.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/malloc.h ../include/geekos/int.h \
+ ../include/geekos/kassert.h ../include/geekos/defs.h \
+ ../include/geekos/kthread.h ../include/geekos/list.h \
+ ../include/geekos/synch.h ../include/geekos/blockdev.h \
+ ../include/geekos/fileio.h
+geekos/ide.o: ../src/geekos/ide.c ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/int.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h ../include/geekos/errno.h \
+ ../include/geekos/malloc.h ../include/geekos/timer.h \
+ ../include/geekos/kthread.h ../include/geekos/list.h \
+ ../include/geekos/blockdev.h ../include/geekos/fileio.h \
+ ../include/geekos/ide.h
+geekos/keyboard.o: ../src/geekos/keyboard.c ../include/geekos/kthread.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/list.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/fmtout.h \
+ ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/irq.h ../include/geekos/int.h \
+ ../include/geekos/defs.h ../include/geekos/io.h \
+ ../include/geekos/keyboard.h
+geekos/screen.o: ../src/geekos/screen.c \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ ../include/geekos/io.h ../include/geekos/int.h ../include/geekos/defs.h \
+ ../include/geekos/debug.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+geekos/timer.o: ../src/geekos/timer.c \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
+ ../include/geekos/io.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/fmtout.h \
+ ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/irq.h \
+ ../include/geekos/kthread.h ../include/geekos/list.h \
+ ../include/geekos/timer.h ../include/geekos/serial.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/debug.h
+geekos/mem.o: ../src/geekos/mem.c ../include/geekos/defs.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/bootinfo.h ../include/geekos/gdt.h \
+ ../include/geekos/int.h ../include/geekos/malloc.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/mem.h ../include/geekos/list.h \
+ ../include/geekos/paging.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/io.h \
+ ../include/geekos/debug.h
+geekos/crc32.o: ../src/geekos/crc32.c ../include/geekos/crc32.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/serial.h ../include/geekos/irq.h \
+ ../include/geekos/int.h ../include/geekos/defs.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ ../include/geekos/io.h ../include/geekos/debug.h
+geekos/gdt.o: ../src/geekos/gdt.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/segment.h ../include/geekos/int.h \
+ ../include/geekos/defs.h ../include/geekos/tss.h \
+ ../include/geekos/gdt.h ../include/libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/debug.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h ../include/geekos/io.h
+geekos/tss.o: ../src/geekos/tss.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/gdt.h \
+ ../include/geekos/segment.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/tss.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/int.h ../include/geekos/io.h \
+ ../include/geekos/debug.h
+geekos/segment.o: ../src/geekos/segment.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/tss.h ../include/geekos/segment.h
+geekos/bget.o: ../src/geekos/bget.c ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/bget.h
+geekos/malloc.o: ../src/geekos/malloc.c ../include/geekos/screen.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/defs.h ../include/geekos/bget.h \
+ ../include/geekos/malloc.h
+geekos/synch.o: ../src/geekos/synch.c ../include/geekos/kthread.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/list.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/fmtout.h \
+ ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/int.h ../include/geekos/defs.h \
+ ../include/geekos/synch.h
+geekos/kthread.o: ../src/geekos/kthread.c ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/int.h \
+ ../include/geekos/mem.h ../include/geekos/list.h \
+ ../include/geekos/paging.h ../include/geekos/bootinfo.h \
+ ../include/geekos/symbol.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/kthread.h ../include/geekos/malloc.h \
+ ../include/geekos/serial.h ../include/geekos/irq.h \
+ ../include/geekos/io.h ../include/geekos/debug.h
+geekos/serial.o: ../src/geekos/serial.c ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/int.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h ../include/geekos/reboot.h \
+ ../include/geekos/gdt.h ../include/geekos/idt.h
+geekos/reboot.o: ../src/geekos/reboot.c ../include/geekos/reboot.h \
+ ../include/libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+geekos/paging.o: ../src/geekos/paging.c ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/idt.h \
+ ../include/geekos/kthread.h ../include/geekos/list.h \
+ ../include/geekos/mem.h ../include/geekos/paging.h \
+ ../include/geekos/bootinfo.h ../include/geekos/malloc.h \
+ ../include/geekos/gdt.h ../include/geekos/segment.h \
+ ../include/geekos/crc32.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/io.h \
+ ../include/geekos/debug.h
+geekos/debug.o: ../src/geekos/debug.c ../include/geekos/debug.h \
+ ../include/geekos/serial.h ../include/geekos/irq.h \
+ ../include/geekos/int.h ../include/geekos/kassert.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/defs.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h
+geekos/vmm_stubs.o: ../src/geekos/vmm_stubs.c ../include/geekos/vmm_stubs.h \
+ ../include/geekos/mem.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/defs.h ../include/geekos/list.h \
+ ../include/geekos/kassert.h ../include/geekos/screen.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/paging.h ../include/geekos/bootinfo.h \
+ ../include/geekos/malloc.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/int.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/io.h
+geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/screen.h ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/geekos/mem.h ../include/geekos/defs.h \
+ ../include/geekos/list.h ../include/geekos/kassert.h \
+ ../include/geekos/paging.h ../include/geekos/crc32.h \
+ ../include/geekos/tss.h ../include/geekos/int.h \
+ ../include/geekos/kthread.h ../include/geekos/trap.h \
+ ../include/geekos/timer.h ../include/geekos/keyboard.h \
+ ../include/geekos/io.h ../include/geekos/serial.h \
+ ../include/geekos/irq.h ../include/geekos/reboot.h \
+ ../include/geekos/ide.h ../include/geekos/malloc.h \
+ ../include/geekos/debug.h ../include/palacios/vmm.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm_mem.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/geekos/gdt.h \
+ ../include/geekos/vmm_stubs.h
+common/fmtout.o: ../src/common/fmtout.c \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \
+ ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h
+common/string.o: ../src/common/string.c ../include/libc/fmtout.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \
+ ../include/libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+common/memmove.o: ../src/common/memmove.c ../include/libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+palacios/vm_guest.o: ../src/palacios/vm_guest.c ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/svm.o: ../src/palacios/svm.c ../include/palacios/svm.h \
+ ../include/palacios/vmm_util.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmcb.h \
+ ../include/palacios/svm_handler.h ../include/palacios/vmm_debug.h \
+ ../include/palacios/vm_guest_mem.h
+palacios/svm_handler.o: ../src/palacios/svm_handler.c \
+ ../include/palacios/svm_handler.h ../include/palacios/svm.h \
+ ../include/palacios/vmm_util.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmcb.h \
+ ../include/palacios/svm_ctrl_regs.h ../include/palacios/svm_io.h
+palacios/vmm.o: ../src/palacios/vmm.c ../include/palacios/vmm.h \
+ ../include/palacios/vmm_types.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/svm.h \
+ ../include/palacios/vmcb.h ../include/palacios/vmx.h \
+ ../include/palacios/vmcs.h ../include/palacios/vmcs_gen.h
+palacios/vmm_util.o: ../src/palacios/vmm_util.c ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/svm_ctrl_regs.o: ../src/palacios/svm_ctrl_regs.c \
+ ../include/palacios/svm_ctrl_regs.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmcb.h ../include/palacios/vmm_emulate.h \
+ ../include/palacios/vm_guest_mem.h ../include/palacios/vmm_ctrl_regs.h
+palacios/vmcb.o: ../src/palacios/vmcb.c ../include/palacios/vmcb.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/vmm_mem.o: ../src/palacios/vmm_mem.c ../include/palacios/vmm_mem.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/vmm_paging.o: ../src/palacios/vmm_paging.c \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vm_guest_mem.h
+palacios/vmm_io.o: ../src/palacios/vmm_io.c ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h ../include/palacios/vmm_mem.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/vmm_debug.o: ../src/palacios/vmm_debug.c ../include/palacios/vmm_debug.h \
+ ../include/palacios/vmm.h ../include/palacios/vmm_types.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/svm_io.o: ../src/palacios/svm_io.c ../include/palacios/svm_io.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_util.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmcb.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_ctrl_regs.h ../include/palacios/vmm_emulate.h \
+ ../include/palacios/vm_guest_mem.h
+palacios/vmm_shadow_paging.o: ../src/palacios/vmm_shadow_paging.c \
+ ../include/palacios/vmm_shadow_paging.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmm_paging.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vm_guest_mem.h
+palacios/vm_guest_mem.o: ../src/palacios/vm_guest_mem.c \
+ ../include/palacios/vm_guest_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm.h \
+ ../include/geekos/string.h ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h
+palacios/vmx.o: ../src/palacios/vmx.c ../include/geekos/cpu.h \
+ ../include/geekos/io_devs.h ../include/geekos/io.h \
+ ../include/geekos/ktypes.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/palacios/vmx.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmcs.h ../include/palacios/vmcs_gen.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h ../include/palacios/vmm_string.h
+palacios/vmcs_gen.o: ../src/palacios/vmcs_gen.c ../include/palacios/vmcs_gen.h \
+ ../include/palacios/vmcs.h ../include/palacios/vmm_types.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
+palacios/vmcs.o: ../src/palacios/vmcs.c ../include/palacios/vmcs.h \
+ ../include/palacios/vmm_types.h ../include/palacios/vmcs_gen.h \
+ ../include/palacios/vmm.h ../include/geekos/string.h \
+ ../include/geekos/../libc/string.h \
+ /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_paging.h
--- /dev/null
+#ifndef __VM_H
+#define __VM_H
+
+int RunVMM();
+
+
+#endif
+
void * Allocate_VMM_Pages(int num_pages);
void Free_VMM_Page(void * page);
-void * VMM_Malloc(uint_t size);
+void * VMM_Malloc(unsigned int size);
void VMM_Free(void * addr);
void * Identity(void *addr);
#ifndef __SVM_H
#define __SVM_H
-#include <geekos/vmm_util.h>
-#include <geekos/vmm.h>
-#include <geekos/vmcb.h>
+#include <palacios/vmm_util.h>
+#include <palacios/vmm.h>
+#include <palacios/vmcb.h>
#define CPUID_FEATURE_IDS 0x80000001
#define CPUID_FEATURE_IDS_ecx_svm_avail 0x00000004
#ifndef __SVM_CTRL_REGS_H
#define __SVM_CTRL_REGS_H
-#include <geekos/vm_guest.h>
-#include <geekos/vmm_util.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_util.h>
// First opcode byte
#ifndef __SVM_HANDLER_H
#define __SVM_HANDLER_H
-#include <geekos/svm.h>
-#include <geekos/vmcb.h>
-#include <geekos/vmm.h>
+#include <palacios/svm.h>
+#include <palacios/vmcb.h>
+#include <palacios/vmm.h>
#ifndef __SVM_IO_H
#define __SVM_IO_H
-#include <geekos/vm_guest.h>
-#include <geekos/vmcb.h>
-#include <geekos/vmm.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmcb.h>
+#include <palacios/vmm.h>
struct svm_io_info {
uint_t type : 1 PACKED; // (0=out, 1=in)
#ifndef __VM_GUEST_H
#define __VM_GUEST_H
-#include <geekos/vmm_mem.h>
-#include <geekos/ktypes.h>
-#include <geekos/vmm_io.h>
-#include <geekos/vmm_shadow_paging.h>
+#include <palacios/vmm_mem.h>
+#include <palacios/vmm_types.h>
+#include <palacios/vmm_io.h>
+#include <palacios/vmm_shadow_paging.h>
typedef ullong_t gpr_t;
#ifndef __VM_GUEST_MEM_H
#define __VM_GUEST_MEM_H
-#include <geekos/vm_guest.h>
-#include <geekos/vmm_mem.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_mem.h>
/* These functions are ordered such that they can only call the functions defined in a lower order group */
#ifndef __VMCB_H
#define __VMCB_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
#define VMCB_CTRL_AREA_OFFSET 0x0
#ifndef __VMCS_H
#define __VMCS_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
/* 16 bit guest state */
//uint_t VMCSRead(uint_t tag, void * val);
-#include <geekos/vmcs_gen.h>
+#include <palacios/vmcs_gen.h>
#endif
#ifndef vmcs_gen
#define vmcs_gen
-#include <geekos/vmcs.h>
-#include <geekos/vmm.h>
+#include <palacios/vmcs.h>
+#include <palacios/vmm.h>
void Set_VMCS_GUEST_ES_SELECTOR(uint_t val);
uint_t Get_VMCS_GUEST_ES_SELECTOR();
#define __VMM_H
-#include <geekos/ktypes.h>
-#include <geekos/string.h>
+//#include <palacios/vmm_types.h>
+#include <palacios/vmm_string.h>
-#include <geekos/vmm_mem.h>
-//#include <geekos/vmm_paging.h>
+#include <palacios/vmm_mem.h>
+//#include <palacios/vmm_paging.h>
-#include <geekos/vm_guest.h>
+#include <palacios/vm_guest.h>
/* utility definitions */
#define PrintDebug(fmt, args...) \
void *(*allocate_pages)(int numPages);
void (*free_page)(void * page);
- void *(*malloc)(uint_t size);
+ void *(*malloc)(unsigned int size);
void (*free)(void * addr);
void *(*paddr_to_vaddr)(void *addr);
#ifndef __VMM_EMULATE_H
#define __VMM_EMULATE_H
-#include <geekos/vm_guest.h>
+#include <palacios/vm_guest.h>
/*
#ifndef __VMM_IO_H
#define __VMM_IO_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
-#include <geekos/vmm_util.h>
+#include <palacios/vmm_util.h>
// FOREACH_IO_HOOK(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook)
#define FOREACH_IO_HOOK(io_map, io_hook) for (io_hook = (io_map).head; io_hook != NULL; io_hook = (io_hook)->next)
#define __VMM_MEM_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
typedef ulong_t addr_t;
#define __VMM_PAGING_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
-#include <geekos/vmm_mem.h>
-#include <geekos/vmm_util.h>
+#include <palacios/vmm_mem.h>
+#include <palacios/vmm_util.h>
/*
-#include <geekos/vmm_util.h>
+#include <palacios/vmm_util.h>
-#include <geekos/vmm_paging.h>
+#include <palacios/vmm_paging.h>
struct shadow_page_state {
--- /dev/null
+/*
+ * String library
+ * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+ * $Revision: 1.1 $
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "COPYING".
+ */
+
+#ifndef STRING_H
+#define STRING_H
+
+#include <stddef.h>
+
+void* memset(void* s, int c, size_t n);
+void* memcpy(void *dst, const void* src, size_t n);
+//void *memmove(void *dst, const void *src, size_t n);
+int memcmp(const void *s1, const void *s2, size_t n);
+size_t strlen(const char* s);
+size_t strnlen(const char *s, size_t maxlen);
+int strcmp(const char* s1, const char* s2);
+int strncmp(const char* s1, const char* s2, size_t limit);
+char *strcat(char *s1, const char *s2);
+char *strcpy(char *dest, const char *src);
+char *strncpy(char *dest, const char *src, size_t limit);
+char *strdup(const char *s1);
+int atoi(const char *buf);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strpbrk(const char *s, const char *accept);
+
+
+
+#endif /* STRING_H */
#ifndef __VMM_TYPES_H
#define __VMM_TYPES_H
+#include <geekos/ktypes.h>
+/*
typedef signed char s8;
-typedef unsigned char u8;
+typedef unsigned char uchar_t;
typedef signed short s16;
-typedef unsigned short u16;
+typedef unsigned short ushort_t;
typedef signed int s32;
-typedef unsigned int u32;
+typedef unsigned int uint_t;
typedef signed long long s64;
-typedef unsigned long long u64;
+typedef unsigned long long ullong_t;
-typedef unsigned long size_t;
+typedef unsigned long ulong_t;
+typedef unsigned long size_t;
+*/
#endif
#ifndef __VMM_UTIL_H
#define __VMM_UTIL_H
-#include <geekos/ktypes.h>
+#include <palacios/vmm_types.h>
#ifndef PAGE_SIZE
#ifndef __VMX_H
#define __VMX_H
-#include <geekos/ktypes.h>
-#include <geekos/vmcs.h>
+#include <palacios/vmm_types.h>
+#include <palacios/vmcs.h>
#define IA32_FEATURE_CONTROL_MSR ((unsigned int)0x3a)
#define IA32_VMX_BASIC_MSR ((unsigned int)0x480)
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
* Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.30 $
+ * $Revision: 1.31 $
*
* This is free software. You are permitted to use,
* redistribute, and modify it as specified in the file "COPYING".
#include <geekos/malloc.h>
#include <geekos/debug.h>
-#include <geekos/vmm.h>
+#include <geekos/vm.h>
#include <geekos/gdt.h>
-#include <geekos/vmm_stubs.h>
#define SPEAKER_PORT 0x61
+
void Buzz(unsigned delay, unsigned num)
{
volatile int x;
-int IO_Read(ushort_t port, void * dst, uint_t length) {
- uchar_t * iter = dst;
- uint_t i;
-
- for (i = 0; i < length; i++) {
- *iter = MyIn_Byte(port);
- iter++;
- }
-
- return 0;
-}
-
-
-
-int IO_Write(ushort_t port, void * src, uint_t length) {
- uchar_t * iter = src;
- uint_t i;
-
-
- for (i = 0; i < length; i++) {
- MyOut_Byte(port, *iter);
- iter++;
- }
-
- return 0;
-}
-
-
-
-int IO_Write_to_Serial(ushort_t port, void * src, uint_t length) {
- PrintBoth("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
- switch (length) {
-
- case 1:
- PrintBoth(">0x%.2x\n", *(char*)src);
- break;
- case 2:
- PrintBoth(">0x%.4x\n", *(ushort_t*)src);
- break;
- case 4:
- PrintBoth(">0x%.8x\n", *(uint_t*)src);
- break;
- default:
- break;
- }
-
- // SerialMemDump(src, length);
- return length;
-}
-
-
-void BuzzVM()
-{
- int x;
- int j;
- unsigned char init;
-
-#if 0
- __asm__ __volatile__ (
- "popf"
- );
-
-#endif
-
- PrintBoth("Starting To Buzz\n");
-
- init=MyIn_Byte(SPEAKER_PORT);
-
- while (1) {
- MyOut_Byte(SPEAKER_PORT, init|0x2);
- for (j=0;j<1000000;j++) {
- x+=j;
- }
- MyOut_Byte(SPEAKER_PORT, init);
- for (j=0;j<1000000;j++) {
- x+=j;
- }
- }
-}
-
-
-
-
#endif
{
- struct vmm_os_hooks os_hooks;
- struct vmm_ctrl_ops vmm_ops;
- struct guest_info vm_info;
- addr_t rsp;
- addr_t rip;
-
- memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
- memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
- memset(&vm_info, 0, sizeof(struct guest_info));
-
- os_hooks.print_debug = &PrintBoth;
- os_hooks.print_info = &Print;
- os_hooks.print_trace = &SerialPrint;
- os_hooks.allocate_pages = &Allocate_VMM_Pages;
- os_hooks.free_page = &Free_VMM_Page;
- os_hooks.malloc = &VMM_Malloc;
- os_hooks.free = &VMM_Free;
- os_hooks.vaddr_to_paddr = &Identity;
- os_hooks.paddr_to_vaddr = &Identity;
-
-
- // DumpGDT();
- Init_VMM(&os_hooks, &vmm_ops);
-
- init_shadow_map(&(vm_info.mem_map));
- init_shadow_page_state(&(vm_info.shdw_pg_state));
- vm_info.page_mode = SHADOW_PAGING;
-
- vm_info.cpu_mode = REAL;
-
- init_vmm_io_map(&(vm_info.io_map));
-
-
- if (0) {
-
- // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);
- // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
-
- rip = (ulong_t)(void*)&BuzzVM;
- // rip -= 0x10000;
- // rip = (addr_t)(void*)&exit_test;
- // rip -= 0x2000;
- vm_info.rip = rip;
- rsp = (addr_t)Alloc_Page();
-
- vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
-
-
- } else {
- //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
- // add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
-
- shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
- init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
- 0x100000, HOST_REGION_PHYSICAL_MEMORY);
- add_shadow_region(&(vm_info.mem_map),ent);
-
- hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
- hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
-
- /*
- vm_info.cr0 = 0;
- vm_info.cs.base=0xf000;
- vm_info.cs.limit=0xffff;
- */
- //vm_info.rip = 0xfff0;
-
- vm_info.rip = 0;
- vm_info.vm_regs.rsp = 0x0;
- }
-
- PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp);
- (vmm_ops).init_guest(&vm_info);
- PrintBoth("Starting Guest\n");
- (vmm_ops).start_guest(&vm_info);
+ RunVMM();
}
; Symbol mangling macros
; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
-; $Revision: 1.1 $
+; $Revision: 1.2 $
; This file defines macros for dealing with externally-visible
; symbols that must be mangled for some object file formats.
; Thanks to Christopher Giese for providing the NASM macros
; (thus saving me hours of frustration).
-%ifndef SYMBOL_ASM
-%define SYMBOL_ASM
+%ifndef __VMM_SYMBOL_ASM
+%define __VMM_SYMBOL_ASM
%ifdef NEED_UNDERSCORE
--- /dev/null
+#include <geekos/vmm_stubs.h>
+#include <palacios/vmm.h>
+#include <geekos/debug.h>
+#include <geekos/serial.h>
+
+
+#define SPEAKER_PORT 0x61
+
+
+
+
+inline void VM_Out_Byte(ushort_t port, uchar_t value)
+{
+ __asm__ __volatile__ (
+ "outb %b0, %w1"
+ :
+ : "a" (value), "Nd" (port)
+ );
+}
+
+/*
+ * Read a byte from an I/O port.
+ */
+inline uchar_t VM_In_Byte(ushort_t port)
+{
+ uchar_t value;
+
+ __asm__ __volatile__ (
+ "inb %w1, %b0"
+ : "=a" (value)
+ : "Nd" (port)
+ );
+
+ return value;
+}
+
+
+
+int IO_Read(ushort_t port, void * dst, uint_t length) {
+ uchar_t * iter = dst;
+ uint_t i;
+
+ for (i = 0; i < length; i++) {
+ *iter = VM_In_Byte(port);
+ iter++;
+ }
+
+ return 0;
+}
+
+
+
+int IO_Write(ushort_t port, void * src, uint_t length) {
+ uchar_t * iter = src;
+ uint_t i;
+
+
+ for (i = 0; i < length; i++) {
+ VM_Out_Byte(port, *iter);
+ iter++;
+ }
+
+ return 0;
+}
+
+
+
+int IO_Write_to_Serial(ushort_t port, void * src, uint_t length) {
+ PrintBoth("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
+ switch (length) {
+
+ case 1:
+ PrintBoth(">0x%.2x\n", *(char*)src);
+ break;
+ case 2:
+ PrintBoth(">0x%.4x\n", *(ushort_t*)src);
+ break;
+ case 4:
+ PrintBoth(">0x%.8x\n", *(uint_t*)src);
+ break;
+ default:
+ break;
+ }
+
+ // SerialMemDump(src, length);
+ return length;
+}
+
+
+
+void BuzzVM()
+{
+ int x;
+ int j;
+ unsigned char init;
+
+#if 0
+ __asm__ __volatile__ (
+ "popf"
+ );
+
+#endif
+
+ PrintBoth("Starting To Buzz\n");
+
+ init=VM_In_Byte(SPEAKER_PORT);
+
+ while (1) {
+ VM_Out_Byte(SPEAKER_PORT, init|0x2);
+ for (j=0;j<1000000;j++) {
+ x+=j;
+ }
+ VM_Out_Byte(SPEAKER_PORT, init);
+ for (j=0;j<1000000;j++) {
+ x+=j;
+ }
+ }
+}
+
+
+
+
+
+
+int RunVMM() {
+
+ struct vmm_os_hooks os_hooks;
+ struct vmm_ctrl_ops vmm_ops;
+ struct guest_info vm_info;
+ addr_t rsp;
+ addr_t rip;
+
+ memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
+ memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
+ memset(&vm_info, 0, sizeof(struct guest_info));
+
+ os_hooks.print_debug = &PrintBoth;
+ os_hooks.print_info = &Print;
+ os_hooks.print_trace = &SerialPrint;
+ os_hooks.allocate_pages = &Allocate_VMM_Pages;
+ os_hooks.free_page = &Free_VMM_Page;
+ os_hooks.malloc = &VMM_Malloc;
+ os_hooks.free = &VMM_Free;
+ os_hooks.vaddr_to_paddr = &Identity;
+ os_hooks.paddr_to_vaddr = &Identity;
+
+
+ // DumpGDT();
+ Init_VMM(&os_hooks, &vmm_ops);
+
+ init_shadow_map(&(vm_info.mem_map));
+ init_shadow_page_state(&(vm_info.shdw_pg_state));
+ vm_info.page_mode = SHADOW_PAGING;
+
+ vm_info.cpu_mode = REAL;
+
+ init_vmm_io_map(&(vm_info.io_map));
+
+
+ if (0) {
+
+ // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);
+ // add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
+
+ rip = (ulong_t)(void*)&BuzzVM;
+ // rip -= 0x10000;
+ // rip = (addr_t)(void*)&exit_test;
+ // rip -= 0x2000;
+ vm_info.rip = rip;
+ rsp = (addr_t)Alloc_Page();
+
+ vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
+
+
+ } else {
+ //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
+ // add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
+
+ shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
+ init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
+ 0x100000, HOST_REGION_PHYSICAL_MEMORY);
+ add_shadow_region(&(vm_info.mem_map),ent);
+
+ hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
+ hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
+
+ /*
+ vm_info.cr0 = 0;
+ vm_info.cs.base=0xf000;
+ vm_info.cs.limit=0xffff;
+ */
+ //vm_info.rip = 0xfff0;
+
+ vm_info.rip = 0;
+ vm_info.vm_regs.rsp = 0x0;
+ }
+
+ PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp);
+ (vmm_ops).init_guest(&vm_info);
+ PrintBoth("Starting Guest\n");
+ (vmm_ops).start_guest(&vm_info);
+
+ return 0;
+
+}
}
-void * VMM_Malloc(uint_t size) {
- return Malloc((ulong_t) size);
+void * VMM_Malloc(unsigned int size) {
+ return Malloc((unsigned long) size);
}
--- /dev/null
+#include <palacios/svm.h>
+#include <palacios/vmm.h>
+
+#include <palacios/vmcb.h>
+#include <palacios/vmm_mem.h>
+#include <palacios/vmm_paging.h>
+#include <palacios/svm_handler.h>
+
+#include <palacios/vmm_debug.h>
+#include <palacios/vm_guest_mem.h>
+
+
+/* TEMPORARY BECAUSE SVM IS WEIRD */
+//#include <palacios/tss.h>
+/* ** */
+
+extern struct vmm_os_hooks * os_hooks;
+
+extern uint_t cpuid_ecx(uint_t op);
+extern uint_t cpuid_edx(uint_t op);
+extern void Get_MSR(uint_t MSR, uint_t * high_byte, uint_t * low_byte);
+extern void Set_MSR(uint_t MSR, uint_t high_byte, uint_t low_byte);
+extern uint_t launch_svm(vmcb_t * vmcb_addr);
+extern void safe_svm_launch(vmcb_t * vmcb_addr, struct guest_gprs * gprs);
+
+extern uint_t Get_CR3();
+
+extern void GetGDTR(void * gdt);
+extern void GetIDTR(void * idt);
+
+extern void DisableInts();
+
+/* Checks machine SVM capability */
+/* Implemented from: AMD Arch Manual 3, sect 15.4 */
+int is_svm_capable() {
+ uint_t ret = cpuid_ecx(CPUID_FEATURE_IDS);
+ uint_t vm_cr_low = 0, vm_cr_high = 0;
+
+
+ if ((ret & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
+ PrintDebug("SVM Not Available\n");
+ return 0;
+ }
+
+ Get_MSR(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
+
+ if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 1) {
+ PrintDebug("Nested Paging not supported\n");
+ }
+
+ if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 0) {
+ return 1;
+ }
+
+ ret = cpuid_edx(CPUID_SVM_REV_AND_FEATURE_IDS);
+
+ if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
+ PrintDebug("SVM BIOS Disabled, not unlockable\n");
+ } else {
+ PrintDebug("SVM is locked with a key\n");
+ }
+
+ return 0;
+}
+
+
+
+void Init_SVM(struct vmm_ctrl_ops * vmm_ops) {
+ reg_ex_t msr;
+ void * host_state;
+
+
+ // Enable SVM on the CPU
+ Get_MSR(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
+ msr.e_reg.low |= EFER_MSR_svm_enable;
+ Set_MSR(EFER_MSR, 0, msr.e_reg.low);
+
+ PrintDebug("SVM Enabled\n");
+
+
+ // Setup the host state save area
+ host_state = os_hooks->allocate_pages(4);
+
+ msr.e_reg.high = 0;
+ msr.e_reg.low = (uint_t)host_state;
+
+
+ PrintDebug("Host State being saved at %x\n", (uint_t)host_state);
+ Set_MSR(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
+
+
+
+ // Setup the SVM specific vmm operations
+ vmm_ops->init_guest = &init_svm_guest;
+ vmm_ops->start_guest = &start_svm_guest;
+
+
+ return;
+}
+
+
+int init_svm_guest(struct guest_info *info) {
+
+ PrintDebug("Allocating VMCB\n");
+ info->vmm_data = (void*)Allocate_VMCB();
+
+
+ //PrintDebug("Generating Guest nested page tables\n");
+ // info->page_tables = NULL;
+ //info->page_tables = generate_guest_page_tables_64(&(info->mem_layout), &(info->mem_list));
+ //info->page_tables = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list));
+ //PrintDebugPageTables(info->page_tables);
+
+
+ PrintDebug("Initializing VMCB (addr=%x)\n", info->vmm_data);
+ Init_VMCB((vmcb_t*)(info->vmm_data), *info);
+
+ // info->rip = 0;
+
+ info->vm_regs.rdi = 0;
+ info->vm_regs.rsi = 0;
+ info->vm_regs.rbp = 0;
+ info->vm_regs.rsp = 0;
+ info->vm_regs.rbx = 0;
+ info->vm_regs.rdx = 0;
+ info->vm_regs.rcx = 0;
+ info->vm_regs.rax = 0;
+
+ return 0;
+}
+
+
+// can we start a kernel thread here...
+int start_svm_guest(struct guest_info *info) {
+
+
+
+ PrintDebug("Launching SVM VM (vmcb=%x)\n", info->vmm_data);
+ //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
+
+ while (1) {
+
+ PrintDebug("SVM Launch Args (vmcb=%x), (info=%x), (vm_regs=%x)\n", info->vmm_data, &(info->vm_regs));
+ PrintDebug("Launching to RIP: %x\n", info->rip);
+ safe_svm_launch((vmcb_t*)(info->vmm_data), &(info->vm_regs));
+ //launch_svm((vmcb_t*)(info->vmm_data));
+ PrintDebug("SVM Returned\n");
+
+ if (handle_svm_exit(info) != 0) {
+ // handle exit code....
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+vmcb_t * Allocate_VMCB() {
+ vmcb_t * vmcb_page = (vmcb_t*)os_hooks->allocate_pages(1);
+
+
+ memset(vmcb_page, 0, 4096);
+
+ return vmcb_page;
+}
+
+
+void Init_VMCB_Real(vmcb_t * vmcb, struct guest_info vm_info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
+ uint_t i;
+
+
+ guest_state->rsp = vm_info.vm_regs.rsp;
+ guest_state->rip = vm_info.rip;
+
+
+ guest_state->efer |= EFER_MSR_svm_enable;
+ guest_state->rflags = 0x00000002; // The reserved bit is always 1
+ ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ ctrl_area->guest_ASID = 1;
+ guest_state->cr0 = 0x60000010;
+
+
+ ctrl_area->exceptions.ex_names.de = 1;
+ ctrl_area->exceptions.ex_names.df = 1;
+ ctrl_area->exceptions.ex_names.pf = 1;
+ ctrl_area->exceptions.ex_names.ts = 1;
+ ctrl_area->exceptions.ex_names.ss = 1;
+ ctrl_area->exceptions.ex_names.ac = 1;
+ ctrl_area->exceptions.ex_names.mc = 1;
+ ctrl_area->exceptions.ex_names.gp = 1;
+ ctrl_area->exceptions.ex_names.ud = 1;
+ ctrl_area->exceptions.ex_names.np = 1;
+ ctrl_area->exceptions.ex_names.of = 1;
+ ctrl_area->exceptions.ex_names.nmi = 1;
+
+ guest_state->cs.selector = 0xf000;
+ guest_state->cs.limit=0xffff;
+ guest_state->cs.base = 0xffff0000;
+ guest_state->cs.attrib.raw = 0x9a;
+
+
+ struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
+ for ( i = 0; segregs[i] != NULL; i++) {
+ struct vmcb_selector * seg = segregs[i];
+
+ seg->selector = 0x0000;
+ seg->base = 0xffff0000;
+ seg->attrib.raw = 0x9b;
+ seg->limit = 0xffff;
+ }
+
+ /* Set GPRs */
+ /*
+ EDX == 0xfxx
+ EAX, EBX, ECX, ESI, EDI, EBP, ESP == 0x0
+ */
+
+ guest_state->gdtr.base = 0;
+ guest_state->gdtr.limit = 0xffff;
+ guest_state->gdtr.attrib.raw = 0x0;
+
+ guest_state->idtr.base = 0;
+ guest_state->idtr.limit = 0xffff;
+ guest_state->idtr.attrib.raw = 0x0;
+
+ guest_state->ldtr.base = 0;
+ guest_state->ldtr.limit = 0xffff;
+ guest_state->ldtr.attrib.raw = 0x82;
+
+ guest_state->tr.base = 0;
+ guest_state->tr.limit = 0xffff;
+ guest_state->tr.attrib.raw = 0x83;
+
+
+
+
+ if (vm_info.io_map.num_ports > 0) {
+ vmm_io_hook_t * iter;
+ addr_t io_port_bitmap;
+
+ io_port_bitmap = (addr_t)os_hooks->allocate_pages(3);
+ memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
+
+ ctrl_area->IOPM_BASE_PA = io_port_bitmap;
+
+ //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
+
+ FOREACH_IO_HOOK(vm_info.io_map, iter) {
+ ushort_t port = iter->port;
+ uchar_t * bitmap = (uchar_t *)io_port_bitmap;
+
+ bitmap += (port / 8);
+ PrintDebug("Setting Bit in block %x\n", bitmap);
+ *bitmap |= 1 << (port % 8);
+ }
+
+ ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ }
+
+ ctrl_area->instrs.instrs.INTR = 1;
+
+ // also determine if CPU supports nested paging
+
+ if (vm_info.page_mode == SHADOW_PAGING) {
+ PrintDebug("Creating initial shadow page table\n");
+ vm_info.shdw_pg_state.shadow_cr3.e_reg.low |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
+ PrintDebug("Created\n");
+
+ guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
+
+ ctrl_area->cr_reads.crs.cr3 = 1;
+ ctrl_area->cr_writes.crs.cr3 = 1;
+ ctrl_area->cr_reads.crs.cr0 = 1;
+ ctrl_area->cr_writes.crs.cr0 = 1;
+
+ ctrl_area->instrs.instrs.INVLPG = 1;
+ ctrl_area->instrs.instrs.INVLPGA = 1;
+
+
+ guest_state->g_pat = 0x7040600070406ULL;
+
+ vm_info.shdw_pg_state.guest_cr0.e_reg.low = guest_state->cr0;
+ guest_state->cr0 |= 0x80000000;
+ } else if (vm_info.page_mode == NESTED_PAGING) {
+ // Flush the TLB on entries/exits
+ //ctrl_area->TLB_CONTROL = 1;
+
+ // Enable Nested Paging
+ //ctrl_area->NP_ENABLE = 1;
+
+ //PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
+
+ // Set the Nested Page Table pointer
+ // ctrl_area->N_CR3 = ((addr_t)vm_info.page_tables);
+ // ctrl_area->N_CR3 = (addr_t)(vm_info.page_tables);
+
+ // ctrl_area->N_CR3 = Get_CR3();
+ // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
+
+ // guest_state->g_pat = 0x7040600070406ULL;
+ }
+
+}
+
+
+void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
+ uint_t i;
+
+
+ guest_state->rsp = vm_info.vm_regs.rsp;
+ guest_state->rip = vm_info.rip;
+
+
+ //ctrl_area->instrs.instrs.CR0 = 1;
+ ctrl_area->cr_reads.crs.cr0 = 1;
+ ctrl_area->cr_writes.crs.cr0 = 1;
+
+ guest_state->efer |= EFER_MSR_svm_enable;
+ guest_state->rflags = 0x00000002; // The reserved bit is always 1
+ ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ // guest_state->cr0 = 0x00000001; // PE
+ ctrl_area->guest_ASID = 1;
+
+
+ ctrl_area->exceptions.ex_names.de = 1;
+ ctrl_area->exceptions.ex_names.df = 1;
+ ctrl_area->exceptions.ex_names.pf = 1;
+ ctrl_area->exceptions.ex_names.ts = 1;
+ ctrl_area->exceptions.ex_names.ss = 1;
+ ctrl_area->exceptions.ex_names.ac = 1;
+ ctrl_area->exceptions.ex_names.mc = 1;
+ ctrl_area->exceptions.ex_names.gp = 1;
+ ctrl_area->exceptions.ex_names.ud = 1;
+ ctrl_area->exceptions.ex_names.np = 1;
+ ctrl_area->exceptions.ex_names.of = 1;
+ ctrl_area->exceptions.ex_names.nmi = 1;
+
+ guest_state->cs.selector = 0x0000;
+ guest_state->cs.limit=~0u;
+ guest_state->cs.base = guest_state->cs.selector<<4;
+ guest_state->cs.attrib.raw = 0xf3;
+
+
+ struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
+ for ( i = 0; segregs[i] != NULL; i++) {
+ struct vmcb_selector * seg = segregs[i];
+
+ seg->selector = 0x0000;
+ seg->base = seg->selector << 4;
+ seg->attrib.raw = 0xf3;
+ seg->limit = ~0u;
+ }
+
+ if (vm_info.io_map.num_ports > 0) {
+ vmm_io_hook_t * iter;
+ addr_t io_port_bitmap;
+
+ io_port_bitmap = (addr_t)os_hooks->allocate_pages(3);
+ memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
+
+ ctrl_area->IOPM_BASE_PA = io_port_bitmap;
+
+ //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
+
+ FOREACH_IO_HOOK(vm_info.io_map, iter) {
+ ushort_t port = iter->port;
+ uchar_t * bitmap = (uchar_t *)io_port_bitmap;
+
+ bitmap += (port / 8);
+ PrintDebug("Setting Bit in block %x\n", bitmap);
+ *bitmap |= 1 << (port % 8);
+ }
+
+
+ //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
+
+ ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ }
+
+ ctrl_area->instrs.instrs.INTR = 1;
+
+
+
+ if (vm_info.page_mode == SHADOW_PAGING) {
+ PrintDebug("Creating initial shadow page table\n");
+ vm_info.shdw_pg_state.shadow_cr3.e_reg.low |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
+ PrintDebug("Created\n");
+
+ guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
+
+ ctrl_area->cr_reads.crs.cr3 = 1;
+ ctrl_area->cr_writes.crs.cr3 = 1;
+
+
+ ctrl_area->instrs.instrs.INVLPG = 1;
+ ctrl_area->instrs.instrs.INVLPGA = 1;
+
+ guest_state->g_pat = 0x7040600070406ULL;
+
+ guest_state->cr0 |= 0x80000000;
+ } else if (vm_info.page_mode == NESTED_PAGING) {
+ // Flush the TLB on entries/exits
+ //ctrl_area->TLB_CONTROL = 1;
+
+ // Enable Nested Paging
+ //ctrl_area->NP_ENABLE = 1;
+
+ //PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
+
+ // Set the Nested Page Table pointer
+ // ctrl_area->N_CR3 = ((addr_t)vm_info.page_tables);
+ // ctrl_area->N_CR3 = (addr_t)(vm_info.page_tables);
+
+ // ctrl_area->N_CR3 = Get_CR3();
+ // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
+
+ // guest_state->g_pat = 0x7040600070406ULL;
+ }
+
+
+
+}
+
+void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
+ uint_t i = 0;
+
+
+ guest_state->rsp = vm_info.vm_regs.rsp;
+ guest_state->rip = vm_info.rip;
+
+
+ /* I pretty much just gutted this from TVMM */
+ /* Note: That means its probably wrong */
+
+ // set the segment registers to mirror ours
+ guest_state->cs.selector = 1<<3;
+ guest_state->cs.attrib.fields.type = 0xa; // Code segment+read
+ guest_state->cs.attrib.fields.S = 1;
+ guest_state->cs.attrib.fields.P = 1;
+ guest_state->cs.attrib.fields.db = 1;
+ guest_state->cs.attrib.fields.G = 1;
+ guest_state->cs.limit = 0xfffff;
+ guest_state->cs.base = 0;
+
+ struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
+ for ( i = 0; segregs[i] != NULL; i++) {
+ struct vmcb_selector * seg = segregs[i];
+
+ seg->selector = 2<<3;
+ seg->attrib.fields.type = 0x2; // Data Segment+read/write
+ seg->attrib.fields.S = 1;
+ seg->attrib.fields.P = 1;
+ seg->attrib.fields.db = 1;
+ seg->attrib.fields.G = 1;
+ seg->limit = 0xfffff;
+ seg->base = 0;
+ }
+
+
+ {
+ /* JRL THIS HAS TO GO */
+
+ // guest_state->tr.selector = GetTR_Selector();
+ guest_state->tr.attrib.fields.type = 0x9;
+ guest_state->tr.attrib.fields.P = 1;
+ // guest_state->tr.limit = GetTR_Limit();
+ //guest_state->tr.base = GetTR_Base();// - 0x2000;
+ /* ** */
+ }
+
+
+ /* ** */
+
+
+ guest_state->efer |= EFER_MSR_svm_enable;
+ guest_state->rflags = 0x00000002; // The reserved bit is always 1
+ ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ guest_state->cr0 = 0x00000001; // PE
+ ctrl_area->guest_ASID = 1;
+
+
+ // guest_state->cpl = 0;
+
+
+
+ // Setup exits
+
+ ctrl_area->cr_writes.crs.cr4 = 1;
+
+ ctrl_area->exceptions.ex_names.de = 1;
+ ctrl_area->exceptions.ex_names.df = 1;
+ ctrl_area->exceptions.ex_names.pf = 1;
+ ctrl_area->exceptions.ex_names.ts = 1;
+ ctrl_area->exceptions.ex_names.ss = 1;
+ ctrl_area->exceptions.ex_names.ac = 1;
+ ctrl_area->exceptions.ex_names.mc = 1;
+ ctrl_area->exceptions.ex_names.gp = 1;
+ ctrl_area->exceptions.ex_names.ud = 1;
+ ctrl_area->exceptions.ex_names.np = 1;
+ ctrl_area->exceptions.ex_names.of = 1;
+ ctrl_area->exceptions.ex_names.nmi = 1;
+
+
+
+ ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ ctrl_area->IOPM_BASE_PA = (uint_t)os_hooks->allocate_pages(3);
+
+ {
+ reg_ex_t tmp_reg;
+ tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA;
+ memset((void*)(tmp_reg.e_reg.low), 0xffffffff, PAGE_SIZE * 2);
+ }
+
+ ctrl_area->instrs.instrs.INTR = 1;
+
+
+ {
+ char gdt_buf[6];
+ char idt_buf[6];
+
+ memset(gdt_buf, 0, 6);
+ memset(idt_buf, 0, 6);
+
+
+ uint_t gdt_base, idt_base;
+ ushort_t gdt_limit, idt_limit;
+
+ GetGDTR(gdt_buf);
+ gdt_base = *(ulong_t*)((uchar_t*)gdt_buf + 2) & 0xffffffff;
+ gdt_limit = *(ushort_t*)(gdt_buf) & 0xffff;
+ PrintDebug("GDT: base: %x, limit: %x\n", gdt_base, gdt_limit);
+
+ GetIDTR(idt_buf);
+ idt_base = *(ulong_t*)(idt_buf + 2) & 0xffffffff;
+ idt_limit = *(ushort_t*)(idt_buf) & 0xffff;
+ PrintDebug("IDT: base: %x, limit: %x\n",idt_base, idt_limit);
+
+
+ // gdt_base -= 0x2000;
+ //idt_base -= 0x2000;
+
+ guest_state->gdtr.base = gdt_base;
+ guest_state->gdtr.limit = gdt_limit;
+ guest_state->idtr.base = idt_base;
+ guest_state->idtr.limit = idt_limit;
+
+
+ }
+
+
+ // also determine if CPU supports nested paging
+ /*
+ if (vm_info.page_tables) {
+ // if (0) {
+ // Flush the TLB on entries/exits
+ ctrl_area->TLB_CONTROL = 1;
+
+ // Enable Nested Paging
+ ctrl_area->NP_ENABLE = 1;
+
+ PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
+
+ // Set the Nested Page Table pointer
+ ctrl_area->N_CR3 |= ((addr_t)vm_info.page_tables & 0xfffff000);
+
+
+ // ctrl_area->N_CR3 = Get_CR3();
+ // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
+
+ guest_state->g_pat = 0x7040600070406ULL;
+
+ PrintDebug("Set Nested CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(ctrl_area->N_CR3)), (uint_t)*((unsigned char *)&(ctrl_area->N_CR3) + 4));
+ PrintDebug("Set Guest CR3: lo: 0x%x hi: 0x%x\n", (uint_t)*(&(guest_state->cr3)), (uint_t)*((unsigned char *)&(guest_state->cr3) + 4));
+ // Enable Paging
+ // guest_state->cr0 |= 0x80000000;
+ }
+ */
+
+}
+
+
--- /dev/null
+#include <palacios/svm_ctrl_regs.h>
+#include <palacios/vmm_mem.h>
+#include <palacios/vmm.h>
+#include <palacios/vmcb.h>
+#include <palacios/vmm_emulate.h>
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vmm_ctrl_regs.h>
+
+
+/* Segmentation is a problem here...
+ *
+ * When we get a memory operand, presumably we use the default segment (which is?)
+ * unless an alternate segment was specfied in the prefix...
+ */
+
+
+int handle_cr0_write(struct guest_info * info) {
+ //vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ char instr[15];
+
+
+ if (info->cpu_mode == REAL) {
+ int index = 0;
+ int ret;
+
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
+ if (ret != 15) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read instruction (ret=%d)\n", ret);
+ return -1;
+ }
+
+ while (is_prefix_byte(instr[index])) {
+ index++;
+ }
+
+ if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] == lmsw_byte) &&
+ (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
+
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr0_real *old_cr0;
+ struct cr0_real *new_cr0;
+ operand_type_t addr_type;
+ char new_cr0_val = 0;
+ // LMSW
+ // decode mod/RM
+ index += 2;
+
+ old_cr0 = (struct cr0_real*)&(guest_state->cr0);
+
+
+ addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
+
+
+ if (addr_type == REG_OPERAND) {
+ new_cr0 = (struct cr0_real *)first_operand;
+ } else if (addr_type == MEM_OPERAND) {
+ addr_t host_addr;
+
+ if (guest_pa_to_host_va(info, first_operand + (guest_state->ds.base << 4), &host_addr) == -1) {
+ // gpf the guest
+ return -1;
+ }
+
+ new_cr0 = (struct cr0_real *)host_addr;
+ } else {
+ // error... don't know what to do
+ return -1;
+ }
+
+ if ((new_cr0->pe == 1) && (old_cr0->pe == 0)) {
+ info->cpu_mode = PROTECTED;
+ } else if ((new_cr0->pe == 0) && (old_cr0->pe == 1)) {
+ info->cpu_mode = REAL;
+ }
+
+ new_cr0_val = *(char*)(new_cr0) & 0x0f;
+
+
+ if (info->page_mode == SHADOW_PAGING) {
+ struct cr0_real * virt_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
+
+ /* struct cr0_real is only 4 bits wide,
+ * so we can overwrite the old_cr0 without worrying about the shadow fields
+ */
+ *(char*)old_cr0 &= 0xf0;
+ *(char*)old_cr0 |= new_cr0_val;
+
+ *(char*)virt_cr0 &= 0xf0;
+ *(char*)virt_cr0 |= new_cr0_val;
+ } else {
+ // for now we just pass through....
+ *(char*)old_cr0 &= 0xf0;
+ *(char*)old_cr0 |= new_cr0_val;
+ }
+
+ PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
+ info->rip += index;
+ PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
+ } else if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] == clts_byte)) {
+ // CLTS
+ } else {
+ // unsupported instruction, UD the guest
+ return -1;
+ }
+
+
+ } else if (info->cpu_mode == PROTECTED) {
+ int index = 0;
+ int ret;
+
+ PrintDebug("Protected Mode write to CR0\n");
+
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
+ if (ret != 0) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read instruction (ret=%d)\n", ret);
+ return -1;
+ }
+
+ while (is_prefix_byte(instr[index])) {
+ index++;
+ }
+
+
+ /* CHECK IF MOV_TO_CR CAN TAKE MEMORY OPERANDS... */
+ if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] == mov_to_cr_byte)) {
+
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr0_32 *old_cr0;
+ struct cr0_32 *new_cr0;
+ operand_type_t addr_type;
+
+ index += 2;
+
+ old_cr0 = (struct cr0_32*)&(guest_state->cr0);
+
+ addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+
+ if (addr_type == REG_OPERAND) {
+ new_cr0 = (struct cr0_32 *)first_operand;
+ } else if (addr_type == MEM_OPERAND) {
+ addr_t host_addr;
+
+ if (guest_pa_to_host_va(info, first_operand + guest_state->ds.base, &host_addr) == -1) {
+ // gpf the guest
+ return -1;
+ }
+
+ new_cr0 = (struct cr0_32 *)host_addr;
+ } else {
+ // error... don't know what to do
+ return -1;
+ }
+
+
+ if (info->page_mode == SHADOW_PAGING) {
+ struct cr0_32 * virt_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+
+ if ((new_cr0->pg == 1) && (virt_cr0->pg == 0)){
+ info->cpu_mode = PROTECTED_PG;
+
+ // Activate Shadow Paging
+ }
+
+ *virt_cr0 = *new_cr0;
+ *old_cr0 = *new_cr0;
+ } else {
+ // fill in
+ }
+
+ info->rip += index;
+
+ }
+
+ } else {
+ PrintDebug("Unknown Mode write to CR0\n");
+ while(1);
+ }
+ return 0;
+}
+
+
+int handle_cr0_read(struct guest_info * info) {
+ //vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ char instr[15];
+
+ if (info->cpu_mode == REAL) {
+ int index = 0;
+ int ret;
+
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
+ if (ret != 15) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read instruction (ret=%d)\n", ret);
+ return -1;
+ }
+
+ while (is_prefix_byte(instr[index])) {
+ index++;
+ }
+
+ if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] == smsw_byte) &&
+ (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
+
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr0_real *cr0;
+ operand_type_t addr_type;
+ char cr0_val = 0;
+
+ index += 2;
+
+ cr0 = (struct cr0_real*)&(guest_state->cr0);
+
+
+ addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
+
+ if (addr_type == MEM_OPERAND) {
+ addr_t host_addr;
+
+ if (guest_pa_to_host_va(info, first_operand + (guest_state->ds.base << 4), &host_addr) == -1) {
+ // gpf the guest
+ return -1;
+ }
+
+ first_operand = host_addr;
+ } else {
+ // error... don't know what to do
+ return -1;
+ }
+
+ cr0_val = *(char*)cr0 & 0x0f;
+
+
+ *(char *)first_operand &= 0xf0;
+ *(char *)first_operand |= cr0_val;
+
+ info->rip += index;
+
+ }
+
+ } else if (info->cpu_mode == PROTECTED) {
+ int index = 0;
+ int ret;
+
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, guest_state->rip, guest_state->cs.base), 15, instr);
+ if (ret != 15) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read instruction (ret=%d)\n", ret);
+ return -1;
+ }
+
+ while (is_prefix_byte(instr[index])) {
+ index++;
+ }
+
+
+ }
+
+
+ return 0;
+}
--- /dev/null
+#include <palacios/svm_handler.h>
+#include <palacios/vmm.h>
+#include <palacios/svm_ctrl_regs.h>
+#include <palacios/svm_io.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+int handle_svm_exit(struct guest_info * info) {
+ vmcb_ctrl_t * guest_ctrl = 0;
+ vmcb_saved_state_t * guest_state = 0;
+ ulong_t exit_code = 0;
+
+ guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+ guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+
+ // Update the high level state
+ info->rip = guest_state->rip;
+ info->vm_regs.rsp = guest_state->rsp;
+ info->vm_regs.rax = guest_state->rax;
+ info->vm_regs.rsp = guest_state->rsp;
+
+
+ PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data);
+ PrintDebug("RIP: %x\n", guest_state->rip);
+
+
+
+ exit_code = guest_ctrl->exit_code;
+
+ // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
+ PrintDebug("SVM Returned: Exit Code: %x\n",exit_code);
+
+ PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
+ PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
+
+ PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
+ PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
+
+
+ if (exit_code == VMEXIT_IOIO) {
+ struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
+
+ if (io_info->type == 0) {
+ if (io_info->str) {
+ handle_svm_io_outs(info);
+ } else {
+ handle_svm_io_out(info);
+ }
+ } else {
+ if (io_info->str) {
+ handle_svm_io_ins(info);
+ } else {
+ handle_svm_io_in(info);
+ }
+ }
+ } else if (exit_code == VMEXIT_CR0_WRITE) {
+ PrintDebug("CR0 Write\n");
+
+ if (handle_cr0_write(info) == -1) {
+ return -1;
+ }
+
+ } else if (( (exit_code == VMEXIT_CR3_READ) ||
+ (exit_code == VMEXIT_CR3_WRITE) ||
+ (exit_code == VMEXIT_INVLPG) ||
+ (exit_code == VMEXIT_INVLPGA) ||
+ (exit_code == VMEXIT_EXCP14)) &&
+ (info->page_mode == SHADOW_PAGING)) {
+ handle_shadow_paging(info);
+ }
+
+
+ // Update the low level state
+ guest_state->rax = info->vm_regs.rax;
+ guest_state->rip = info->rip;
+ guest_state->rsp = info->vm_regs.rsp;
+
+ return 0;
+}
+
+
+
+
+int handle_shadow_paging(struct guest_info * info) {
+ vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
+ // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+ if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
+
+ }
+
+ return 0;
+}
+
+
+
--- /dev/null
+#include <palacios/svm_io.h>
+#include <palacios/vmm_io.h>
+#include <palacios/vmm_ctrl_regs.h>
+#include <palacios/vmm_emulate.h>
+#include <palacios/vm_guest_mem.h>
+
+
+// This should package up an IO request and call vmm_handle_io
+int handle_svm_io_in(struct guest_info * info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+
+ vmm_io_hook_t * hook = get_io_hook(&(info->io_map), io_info->port);
+ uint_t read_size = 0;
+
+ if (hook == NULL) {
+ // error, we should not have exited on this port
+ return -1;
+ }
+
+ PrintDebug("IN on port %d (0x%x)\n", io_info->port, io_info->port);
+
+ if (io_info->sz8) {
+ read_size = 1;
+ } else if (io_info->sz16) {
+ read_size = 2;
+ } else if (io_info->sz32) {
+ read_size = 4;
+ }
+
+
+ if (hook->read(io_info->port, &(info->vm_regs.rax), read_size) != read_size) {
+ // not sure how we handle errors.....
+ return -1;
+ }
+
+ info->rip = ctrl_area->exit_info2;
+
+ return 0;
+}
+
+
+
+
+
+/* We might not handle wrap around of the RDI register correctly...
+ * In that if we do wrap around the effect will manifest in the higher bits of the register
+ */
+int handle_svm_io_ins(struct guest_info * info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+
+ vmm_io_hook_t * hook = get_io_hook(&(info->io_map), io_info->port);
+ uint_t read_size = 0;
+ addr_t base_addr = guest_state->es.base ;
+ addr_t dst_addr = 0;
+ uint_t rep_num = 1;
+ ullong_t mask = 0;
+
+
+
+ // This is kind of hacky...
+ // direction can equal either 1 or -1
+ // We will multiply the final added offset by this value to go the correct direction
+ int direction = 1;
+ struct rflags * flags = (struct rflags *)&(guest_state->rflags);
+ if (flags->df) {
+ direction = -1;
+ }
+
+
+ if (hook == NULL) {
+ // error, we should not have exited on this port
+ return -1;
+ }
+
+ PrintDebug("INS on port %d (0x%x)\n", io_info->port, io_info->port);
+
+ if (io_info->sz8) {
+ read_size = 1;
+ } else if (io_info->sz16) {
+ read_size = 2;
+ } else if (io_info->sz32) {
+ read_size = 4;
+ }
+
+
+ if (io_info->addr16) {
+ mask = 0xffff;
+ } else if (io_info->addr32) {
+ mask = 0xffffffff;
+ } else if (io_info->addr64) {
+ mask = 0xffffffffffffffffLL;
+ } else {
+ // should never happen
+ return -1;
+ }
+
+ if (io_info->rep) {
+ rep_num = info->vm_regs.rcx & mask;
+ }
+
+
+
+ while (rep_num > 0) {
+ addr_t host_addr;
+ dst_addr = get_addr_linear(info, info->vm_regs.rdi & mask, base_addr);
+
+ if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+ // either page fault or gpf...
+ }
+
+ if (hook->read(io_info->port, (char*)host_addr, read_size) != read_size) {
+ // not sure how we handle errors.....
+ return -1;
+ }
+
+ info->vm_regs.rdi += read_size * direction;
+
+ if (io_info->rep)
+ info->vm_regs.rcx--;
+
+ rep_num--;
+ }
+
+
+ info->rip = ctrl_area->exit_info2;
+
+ return 0;
+}
+
+int handle_svm_io_out(struct guest_info * info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+
+ vmm_io_hook_t * hook = get_io_hook(&(info->io_map), io_info->port);
+ uint_t write_size = 0;
+
+ if (hook == NULL) {
+ // error, we should not have exited on this port
+ return -1;
+ }
+
+ PrintDebug("OUT on port %d (0x%x)\n", io_info->port, io_info->port);
+
+ if (io_info->sz8) {
+ write_size = 1;
+ } else if (io_info->sz16) {
+ write_size = 2;
+ } else if (io_info->sz32) {
+ write_size = 4;
+ }
+
+
+ if (hook->write(io_info->port, &(info->vm_regs.rax), write_size) != write_size) {
+ // not sure how we handle errors.....
+ return -1;
+ }
+
+ info->rip = ctrl_area->exit_info2;
+
+ return 0;
+}
+
+
+/* We might not handle wrap around of the RSI register correctly...
+ * In that if we do wrap around the effect will manifest in the higher bits of the register
+ */
+
+int handle_svm_io_outs(struct guest_info * info) {
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t *)(info->vmm_data));
+ vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+ struct svm_io_info * io_info = (struct svm_io_info *)&(ctrl_area->exit_info1);
+
+ vmm_io_hook_t * hook = get_io_hook(&(info->io_map), io_info->port);
+ uint_t write_size = 0;
+ addr_t base_addr = guest_state->ds.base;
+ addr_t dst_addr = 0;
+ uint_t rep_num = 1;
+ ullong_t mask = 0;
+
+
+
+ // This is kind of hacky...
+ // direction can equal either 1 or -1
+ // We will multiply the final added offset by this value to go the correct direction
+ int direction = 1;
+ struct rflags * flags = (struct rflags *)&(guest_state->rflags);
+ if (flags->df) {
+ direction = -1;
+ }
+
+
+ if (hook == NULL) {
+ // error, we should not have exited on this port
+ return -1;
+ }
+
+ PrintDebug("OUTS on port %d (0x%x)\n", io_info->port, io_info->port);
+
+ if (io_info->sz8) {
+ write_size = 1;
+ } else if (io_info->sz16) {
+ write_size = 2;
+ } else if (io_info->sz32) {
+ write_size = 4;
+ }
+
+
+ if (io_info->addr16) {
+ mask = 0xffff;
+ } else if (io_info->addr32) {
+ mask = 0xffffffff;
+ } else if (io_info->addr64) {
+ mask = 0xffffffffffffffffLL;
+ } else {
+ // should never happen
+ return -1;
+ }
+
+ if (io_info->rep) {
+ rep_num = info->vm_regs.rcx & mask;
+ }
+
+
+ while (rep_num > 0) {
+ addr_t host_addr;
+ dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), base_addr);
+
+ if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
+ // either page fault or gpf...
+ }
+
+ if (hook->write(io_info->port, (char*)host_addr, write_size) != write_size) {
+ // not sure how we handle errors.....
+ return -1;
+ }
+
+ info->vm_regs.rsi += write_size * direction;
+
+ if (io_info->rep)
+ info->vm_regs.rcx--;
+
+ rep_num--;
+ }
+
+
+ info->rip = ctrl_area->exit_info2;
+
+
+ return 0;
+}
--- /dev/null
+; -*- fundamental -*-
+
+
+%ifndef SVM_ASM
+%define SVM_ASM
+
+;%include "defs.asm"
+%include "vmm_symbol.asm"
+
+SVM_ERROR equ 0xFFFFFFFF
+SVM_SUCCESS equ 0x00000000
+
+EXPORT DisableInts
+
+EXPORT GetGDTR
+EXPORT GetIDTR
+EXPORT GetTR
+
+EXPORT exit_test
+
+EXTERN handle_svm_exit
+
+EXPORT launch_svm
+EXPORT safe_svm_launch
+
+
+
+
+;; These need to be kept similar with the svm return values in svm.h
+SVM_HANDLER_SUCCESS equ 0x00
+SVM_HANDLER_ERROR equ 0x1
+SVM_HANDLER_HALT equ 0x2
+
+[BITS 32]
+
+
+; Save and restore registers needed by SVM
+%macro Save_SVM_Registers 1
+ push eax
+ mov eax, dword %1
+ mov [eax], edi
+ mov [eax + 8], esi
+ mov [eax + 16], ebp
+ mov [eax + 24], dword 0 ;; esp
+ mov [eax + 32], ebx
+ mov [eax + 40], edx
+ mov [eax + 48], ecx
+
+ push ebx
+ mov ebx, [esp + 4]
+ mov [eax + 56], ebx ;; eax
+ pop ebx
+
+ pop eax
+%endmacro
+
+
+%macro Restore_SVM_Registers 1
+ push eax
+ mov eax, dword %1
+ mov edi, [eax]
+ mov esi, [eax + 8]
+ mov ebp, [eax + 16]
+;; mov esp, [eax + 24]
+ mov ebx, [eax + 32]
+ mov edx, [eax + 40]
+ mov ecx, [eax + 48]
+;; mov eax, [eax + 56]
+ pop eax
+%endmacro
+
+%macro vmrun 0
+ db 00fh, 001h, 0d8h
+%endmacro
+
+%macro vmsave 0
+ db 00fh, 001h, 0dbh
+%endmacro
+
+%macro vmload 0
+ db 00fh, 001h, 0dah
+%endmacro
+
+;VMRUN equ db 0Fh, 01h, D8h
+;VMLOAD equ db 0x0F,0x01,0xDA
+;VMSAVE equ db 0x0F,0x01,0xDB
+;STGI equ db 0x0F,0x01,0xDC
+;CLGI equ db 0x0F,0x01,0xDD
+
+
+align 8
+DisableInts:
+ cli
+ ret
+
+
+align 8
+GetGDTR:
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ebx, [ebp + 8]
+ sgdt [ebx]
+
+ popa
+ pop ebp
+ ret
+
+
+align 8
+GetIDTR:
+ push ebp
+ mov ebp, esp
+ pusha
+
+ mov ebx, [ebp + 8]
+ sidt [ebx]
+
+ popa
+ pop ebp
+ ret
+
+
+
+align 8
+GetTR:
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ebx, [ebp + 8]
+ str [ebx]
+
+ popa
+ pop ebp
+ ret
+
+
+
+; I think its safe to say that there are some pretty serious register issues...
+align 8
+launch_svm:
+ push ebp
+ mov ebp, esp
+ pusha
+
+ mov eax, [ebp + 8]
+ vmrun
+; db 00fh, 001h, 0d8h
+ popa
+ pop ebp
+ ret
+
+
+
+
+exit_test:
+ mov cr4, eax
+ ret
+
+
+;; Need to check this..
+;; save_svm_launch(rax, struct guest_gprs * regs)
+align 8
+safe_svm_launch:
+ push ebp
+ mov ebp, esp
+ pushf
+ pusha ;; Save Host state
+
+
+ push dword [ebp + 12] ;; pointer to the guest GPR save area
+ push dword [ebp + 8] ;; pointer to the VMCB pointer
+
+;; mov eax, [esp + 4] ;; mov guest GPR pointer to eax
+
+ ;; this is plus 8 because we push eax in the macro
+ Restore_SVM_Registers [esp + 8] ;; Restore Guest GPR state
+ pop eax ;; pop VMCB pointer into eax
+
+ vmload
+ vmrun
+ vmsave
+
+;; pop eax ;; pop Guest GPR pointer into eax
+ ;; this is plus 4 because we push eax in the macro NEED TO CHANGE
+ Save_SVM_Registers [esp+4] ;; save guest GPRs
+
+ add esp, 4 ;; skip past the gpr ptr
+
+ popa ;; Restore Host state
+ popf
+ pop ebp
+ ret
+
+
+
+%endif
+
+
--- /dev/null
+#include <palacios/vm_guest.h>
--- /dev/null
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_paging.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+/**********************************/
+/* GROUP 0 */
+/**********************************/
+
+int host_va_to_host_pa(addr_t host_va, addr_t * host_pa) {
+ if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
+
+ *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
+
+ if (*host_pa == 0) {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+
+int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
+ if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
+
+ *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
+
+ if (*host_va == 0) {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+
+
+int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
+ // we use the shadow map here...
+ if (lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa) != HOST_REGION_PHYSICAL_MEMORY) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* !! Currently not implemented !! */
+// This is a scan of the shadow map
+// For now we ignore it
+//
+int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
+ *guest_pa = 0;
+
+ return -1;
+}
+
+
+
+/**********************************/
+/* GROUP 1 */
+/**********************************/
+
+
+/* !! Currently not implemented !! */
+// This will return negative until we implement host_pa_to_guest_pa()
+int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
+ addr_t host_pa;
+ *guest_pa = 0;
+
+ if (host_va_to_host_pa(host_va, &host_pa) != 0) {
+ return -1;
+ }
+
+ if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
+int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
+ addr_t host_pa;
+
+ *host_va = 0;
+
+ if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
+ return -1;
+ }
+
+ if (host_pa_to_host_va(host_pa, host_va) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
+ if (guest_info->page_mode == SHADOW_PAGING) {
+ switch (guest_info->cpu_mode) {
+ case REAL:
+ case PROTECTED:
+ case LONG:
+ case PROTECTED_PAE:
+ // guest virtual address is the same as the physical
+ *guest_pa = guest_va;
+ return 0;
+ case PROTECTED_PG:
+ {
+ addr_t tmp_pa;
+ pde32_t * pde;
+ addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3.r_reg);
+
+ if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
+ return -1;
+ }
+
+ switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
+ case NOT_PRESENT:
+ *guest_pa = 0;
+ return -1;
+ case LARGE_PAGE:
+ *guest_pa = tmp_pa;
+ return 0;
+ case PTE32:
+ {
+ pte32_t * pte;
+
+ if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
+ return -1;
+ }
+
+ if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
+ return -1;
+ }
+
+ return 0;
+ }
+ default:
+ return -1;
+ }
+ }
+ case PROTECTED_PAE_PG:
+ {
+ // Fill in
+ }
+ case LONG_PG:
+ {
+ // Fill in
+ }
+ default:
+ return -1;
+ }
+ } else if (guest_info->page_mode == NESTED_PAGING) {
+
+ // Fill in
+
+ } else {
+ return -1;
+ }
+
+
+ return 0;
+}
+
+
+
+/* !! Currently not implemented !! */
+/* This will be a real pain.... its your standard page table walker in guest memory
+ *
+ * For now we ignore it...
+ */
+int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
+ *guest_va = 0;
+ return -1;
+}
+
+
+/**********************************/
+/* GROUP 2 */
+/**********************************/
+
+
+int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
+ addr_t guest_pa;
+
+ *host_pa = 0;
+
+ if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
+ return -1;
+ }
+
+ if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* !! Currently not implemented !! */
+int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
+ addr_t guest_pa;
+
+ *guest_va = 0;
+
+ if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
+ return -1;
+ }
+
+ if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
+int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
+ addr_t guest_pa;
+ addr_t host_pa;
+
+ *host_va = 0;
+
+ if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
+ return -1;
+ }
+
+ if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
+ return -1;
+ }
+
+ if (host_pa_to_host_va(host_pa, host_va) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* !! Currently not implemented !! */
+int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
+ addr_t host_pa;
+ addr_t guest_pa;
+
+ *guest_va = 0;
+
+ if (host_va_to_host_pa(host_va, &host_pa) != 0) {
+ return -1;
+ }
+
+ if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
+ return -1;
+ }
+
+ if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+/* This is a straight address conversion + copy,
+ * except for the tiny little issue of crossing page boundries.....
+ */
+int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) {
+ addr_t cursor = guest_va;
+ int bytes_read = 0;
+
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr;
+
+ if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ return bytes_read;
+ }
+
+ memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
+
+ bytes_read += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
+
+ return bytes_read;
+}
+
+
+
+
+
+
+/* This is a straight address conversion + copy,
+ * except for the tiny little issue of crossing page boundries.....
+ */
+int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) {
+ addr_t cursor = guest_pa;
+ int bytes_read = 0;
+
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr;
+
+ if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ return bytes_read;
+ }
+
+ memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
+
+ bytes_read += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
+
+ return bytes_read;
+}
+
+
+
+
+/* This is a straight address conversion + copy,
+ * except for the tiny little issue of crossing page boundries.....
+ */
+int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) {
+ addr_t cursor = guest_pa;
+ int bytes_written = 0;
+
+ while (count > 0) {
+ int dist_to_pg_edge = (PAGE_OFFSET(cursor) + PAGE_SIZE) - cursor;
+ int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
+ addr_t host_addr;
+
+ if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
+ return bytes_written;
+ }
+
+ memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
+
+ bytes_written += bytes_to_copy;
+ count -= bytes_to_copy;
+ cursor += bytes_to_copy;
+ }
+
+ return bytes_written;
+}
+
--- /dev/null
+#include <palacios/vmcb.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_util.h>
+
+
+void PrintDebugVMCB(vmcb_t * vmcb) {
+ reg_ex_t tmp_reg;
+
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+
+ PrintDebug("VMCB (0x%.8x)\n", vmcb);
+
+ PrintDebug("--Control Area--\n");
+ PrintDebug("CR Reads: %x\n", ctrl_area->cr_reads.bitmap);
+ PrintDebug("CR Writes: %x\n", ctrl_area->cr_writes.bitmap);
+ PrintDebug("DR Reads: %x\n", ctrl_area->dr_reads.bitmap);
+ PrintDebug("DR Writes: %x\n", ctrl_area->dr_writes.bitmap);
+
+ PrintDebug("Exception Bitmap: %x (at 0x%.8x)\n", ctrl_area->exceptions.bitmap, &(ctrl_area->exceptions));
+ PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.ex_names.de);
+ PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.ex_names.db);
+ PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.ex_names.nmi);
+ PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.ex_names.bp);
+ PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.ex_names.of);
+ PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.ex_names.br);
+ PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ex_names.ud);
+ PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.ex_names.nm);
+ PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.ex_names.df);
+ PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ex_names.ts);
+ PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.ex_names.np);
+ PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ex_names.ss);
+ PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.ex_names.gp);
+ PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.ex_names.pf);
+ PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.ex_names.mf);
+ PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ex_names.ac);
+ PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.ex_names.mc);
+ PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.ex_names.xf);
+ PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.ex_names.sx);
+
+ PrintDebug("Instructions bitmap: %.8x (at 0x%.8x)\n", ctrl_area->instrs.bitmap, &(ctrl_area->instrs));
+ PrintDebug("\tINTR: %d\n", ctrl_area->instrs.instrs.INTR);
+ PrintDebug("\tNMI: %d\n", ctrl_area->instrs.instrs.NMI);
+ PrintDebug("\tSMI: %d\n", ctrl_area->instrs.instrs.SMI);
+ PrintDebug("\tINIT: %d\n", ctrl_area->instrs.instrs.INIT);
+ PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.instrs.VINTR);
+ PrintDebug("\tCR0: %d\n", ctrl_area->instrs.instrs.CR0);
+ PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.instrs.RD_IDTR);
+ PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.instrs.RD_GDTR);
+ PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.instrs.RD_LDTR);
+ PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.instrs.RD_TR);
+ PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.instrs.WR_IDTR);
+ PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.instrs.WR_GDTR);
+ PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.instrs.WR_LDTR);
+ PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.instrs.WR_TR);
+ PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.instrs.RDTSC);
+ PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.instrs.RDPMC);
+ PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.instrs.PUSHF);
+ PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.instrs.POPF);
+ PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.instrs.CPUID);
+ PrintDebug("\tRSM: %d\n", ctrl_area->instrs.instrs.RSM);
+ PrintDebug("\tIRET: %d\n", ctrl_area->instrs.instrs.IRET);
+ PrintDebug("\tINTn: %d\n", ctrl_area->instrs.instrs.INTn);
+ PrintDebug("\tINVD: %d\n", ctrl_area->instrs.instrs.INVD);
+ PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.instrs.PAUSE);
+ PrintDebug("\tHLT: %d\n", ctrl_area->instrs.instrs.HLT);
+ PrintDebug("\tINVLPG: %d\n", ctrl_area->instrs.instrs.INVLPG);
+ PrintDebug("\tINVLPGA: %d\n", ctrl_area->instrs.instrs.INVLPGA);
+ PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.instrs.IOIO_PROT);
+ PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.instrs.MSR_PROT);
+ PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.instrs.task_switch);
+ PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.instrs.FERR_FREEZE);
+ PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.instrs.shutdown_evts);
+
+ PrintDebug("SVM Instruction Bitmap: %.8x (at 0x%.8x)\n", ctrl_area->svm_instrs.bitmap, &(ctrl_area->svm_instrs));
+ PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.instrs.VMRUN);
+ PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.instrs.VMMCALL);
+ PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.instrs.VMLOAD);
+ PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.instrs.VMSAVE);
+ PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.instrs.STGI);
+ PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.instrs.CLGI);
+ PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.instrs.SKINIT);
+ PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.instrs.RDTSCP);
+ PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.instrs.ICEBP);
+ PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.instrs.WBINVD);
+ PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.instrs.MONITOR);
+ PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_always);
+ PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_if_armed);
+
+
+
+ tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA;
+ PrintDebug("IOPM_BASE_PA: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+ tmp_reg.r_reg = ctrl_area->MSRPM_BASE_PA;
+ PrintDebug("MSRPM_BASE_PA: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+ tmp_reg.r_reg = ctrl_area->TSC_OFFSET;
+ PrintDebug("TSC_OFFSET: lo: 0x%.8x, hi: 0x%.8x\n", tmp_reg.e_reg.low, tmp_reg.e_reg.high);
+
+ PrintDebug("guest_ASID: %d\n", ctrl_area->guest_ASID);
+ PrintDebug("TLB_CONTROL: %d\n", ctrl_area->TLB_CONTROL);
+
+
+ PrintDebug("Guest Control Bitmap: %x (at 0x%.8x)\n", ctrl_area->guest_ctrl.bitmap, &(ctrl_area->guest_ctrl));
+ PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_TPR);
+ PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.ctrls.V_IRQ);
+ PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_PRIO);
+ PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_IGN_TPR);
+ PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_MASKING);
+ PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_VECTOR);
+
+ PrintDebug("Interrupt_shadow: %d\n", ctrl_area->interrupt_shadow);
+
+
+ tmp_reg.r_reg = ctrl_area->exit_code;
+ PrintDebug("exit_code: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = ctrl_area->exit_info1;
+ PrintDebug("exit_info1: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = ctrl_area->exit_info2;
+ PrintDebug("exit_info2: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = ctrl_area->exit_int_info;
+ PrintDebug("exit_int_info: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ tmp_reg.r_reg = ctrl_area->NP_ENABLE;
+ PrintDebug("NP_ENABLE: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = ctrl_area->EVENTINJ;
+ PrintDebug("EVENTINJ: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ tmp_reg.r_reg = ctrl_area->N_CR3;
+ PrintDebug("N_CR3: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ PrintDebug("LBR_VIRTUALIZATION_ENABLE: %d\n", ctrl_area->LBR_VIRTUALIZATION_ENABLE);
+
+
+ PrintDebug("\n--Guest Saved State--\n");
+
+ PrintDebug("es Selector (at 0x%.8x): \n", &(guest_area->es));
+ PrintDebug("\tSelector: %d\n", guest_area->es.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->es.attrib.fields.type, guest_area->es.attrib.fields.S,
+ guest_area->es.attrib.fields.dpl, guest_area->es.attrib.fields.P,
+ guest_area->es.attrib.fields.avl, guest_area->es.attrib.fields.L,
+ guest_area->es.attrib.fields.db, guest_area->es.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->es.limit);
+ tmp_reg.r_reg = guest_area->es.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("cs Selector (at 0x%.8x): \n", &(guest_area->cs));
+ PrintDebug("\tSelector: %d\n", guest_area->cs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->cs.attrib.fields.type, guest_area->cs.attrib.fields.S,
+ guest_area->cs.attrib.fields.dpl, guest_area->cs.attrib.fields.P,
+ guest_area->cs.attrib.fields.avl, guest_area->cs.attrib.fields.L,
+ guest_area->cs.attrib.fields.db, guest_area->cs.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->cs.limit);
+ tmp_reg.r_reg = guest_area->cs.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ss Selector (at 0x%.8x): \n", &(guest_area->ss));
+ PrintDebug("\tSelector: %d\n", guest_area->ss.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ss.attrib.fields.type, guest_area->ss.attrib.fields.S,
+ guest_area->ss.attrib.fields.dpl, guest_area->ss.attrib.fields.P,
+ guest_area->ss.attrib.fields.avl, guest_area->ss.attrib.fields.L,
+ guest_area->ss.attrib.fields.db, guest_area->ss.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->ss.limit);
+ tmp_reg.r_reg = guest_area->ss.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ds Selector (at 0x%.8x): \n", &(guest_area->ds));
+ PrintDebug("\tSelector: %d\n", guest_area->ds.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ds.attrib.fields.type, guest_area->ds.attrib.fields.S,
+ guest_area->ds.attrib.fields.dpl, guest_area->ds.attrib.fields.P,
+ guest_area->ds.attrib.fields.avl, guest_area->ds.attrib.fields.L,
+ guest_area->ds.attrib.fields.db, guest_area->ds.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->ds.limit);
+ tmp_reg.r_reg = guest_area->ds.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("fs Selector (at 0x%.8x): \n", &(guest_area->fs));
+ PrintDebug("\tSelector: %d\n", guest_area->fs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->fs.attrib.fields.type, guest_area->fs.attrib.fields.S,
+ guest_area->fs.attrib.fields.dpl, guest_area->fs.attrib.fields.P,
+ guest_area->fs.attrib.fields.avl, guest_area->fs.attrib.fields.L,
+ guest_area->fs.attrib.fields.db, guest_area->fs.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->fs.limit);
+ tmp_reg.r_reg = guest_area->fs.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("gs Selector (at 0x%.8x): \n", &(guest_area->gs));
+ PrintDebug("\tSelector: %d\n", guest_area->gs.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->gs.attrib.fields.type, guest_area->gs.attrib.fields.S,
+ guest_area->gs.attrib.fields.dpl, guest_area->gs.attrib.fields.P,
+ guest_area->gs.attrib.fields.avl, guest_area->gs.attrib.fields.L,
+ guest_area->gs.attrib.fields.db, guest_area->gs.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->gs.limit);
+ tmp_reg.r_reg = guest_area->gs.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("gdtr Selector (at 0x%.8x): \n", &(guest_area->gdtr));
+ PrintDebug("\tSelector: %d\n", guest_area->gdtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->gdtr.attrib.fields.type, guest_area->gdtr.attrib.fields.S,
+ guest_area->gdtr.attrib.fields.dpl, guest_area->gdtr.attrib.fields.P,
+ guest_area->gdtr.attrib.fields.avl, guest_area->gdtr.attrib.fields.L,
+ guest_area->gdtr.attrib.fields.db, guest_area->gdtr.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->gdtr.limit);
+ tmp_reg.r_reg = guest_area->gdtr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("ldtr Selector (at 0x%.8x): \n", &(guest_area->ldtr));
+ PrintDebug("\tSelector: %d\n", guest_area->ldtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->ldtr.attrib.fields.type, guest_area->ldtr.attrib.fields.S,
+ guest_area->ldtr.attrib.fields.dpl, guest_area->ldtr.attrib.fields.P,
+ guest_area->ldtr.attrib.fields.avl, guest_area->ldtr.attrib.fields.L,
+ guest_area->ldtr.attrib.fields.db, guest_area->ldtr.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->ldtr.limit);
+ tmp_reg.r_reg = guest_area->ldtr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("idtr Selector (at 0x%.8x): \n", &(guest_area->idtr));
+ PrintDebug("\tSelector: %d\n", guest_area->idtr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->idtr.attrib.fields.type, guest_area->idtr.attrib.fields.S,
+ guest_area->idtr.attrib.fields.dpl, guest_area->idtr.attrib.fields.P,
+ guest_area->idtr.attrib.fields.avl, guest_area->idtr.attrib.fields.L,
+ guest_area->idtr.attrib.fields.db, guest_area->idtr.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->idtr.limit);
+ tmp_reg.r_reg = guest_area->idtr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("tr Selector (at 0x%.8x): \n", &(guest_area->tr));
+ PrintDebug("\tSelector: %d\n", guest_area->tr.selector);
+ PrintDebug("\t(type=%x), (S=%d), (dpl=%d), (P=%d), (avl=%d), (L=%d), (db=%d), (G=%d)\n",
+ guest_area->tr.attrib.fields.type, guest_area->tr.attrib.fields.S,
+ guest_area->tr.attrib.fields.dpl, guest_area->tr.attrib.fields.P,
+ guest_area->tr.attrib.fields.avl, guest_area->tr.attrib.fields.L,
+ guest_area->tr.attrib.fields.db, guest_area->tr.attrib.fields.G);
+ PrintDebug("\tlimit: %lu\n", guest_area->tr.limit);
+ tmp_reg.r_reg = guest_area->tr.base;
+ PrintDebug("\tBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ PrintDebug("cpl: %d\n", guest_area->cpl);
+
+
+ tmp_reg.r_reg = guest_area->efer;
+ PrintDebug("EFER: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = guest_area->cr4;
+ PrintDebug("CR4: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr3;
+ PrintDebug("CR3: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr0;
+ PrintDebug("CR0: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dr7;
+ PrintDebug("DR7: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dr6;
+ PrintDebug("DR6: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->rflags;
+ PrintDebug("RFLAGS: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->rip;
+ PrintDebug("RIP: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ tmp_reg.r_reg = guest_area->rsp;
+ PrintDebug("RSP: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+ tmp_reg.r_reg = guest_area->rax;
+ PrintDebug("RAX: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->star;
+ PrintDebug("STAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lstar;
+ PrintDebug("LSTAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cstar;
+ PrintDebug("CSTAR: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sfmask;
+ PrintDebug("SFMASK: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->KernelGsBase;
+ PrintDebug("KernelGsBase: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_cs;
+ PrintDebug("sysenter_cs: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_esp;
+ PrintDebug("sysenter_esp: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->sysenter_eip;
+ PrintDebug("sysenter_eip: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->cr2;
+ PrintDebug("CR2: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+ tmp_reg.r_reg = guest_area->g_pat;
+ PrintDebug("g_pat: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->dbgctl;
+ PrintDebug("dbgctl: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->br_from;
+ PrintDebug("br_from: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->br_to;
+ PrintDebug("br_to: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lastexcpfrom;
+ PrintDebug("lastexcpfrom: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ tmp_reg.r_reg = guest_area->lastexcpto;
+ PrintDebug("lastexcpto: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+
+
+
+
+
+
+}
--- /dev/null
+#include <palacios/vmcs.h>
+
+
+
+
+
+
+//extern char * exception_names;
+//
+// Ignores "HIGH" addresses - 32 bit only for now
+//
+
+
+#define CHK_VMCS_READ(tag, val) {if (VMCS_READ(tag, val) != 0) return -1;}
+#define CHK_VMCS_WRITE(tag, val) {if (VMCS_WRITE(tag, val) != 0) return -1;}
+
+
+
+int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea *p) {
+ CHK_VMCS_READ(GUEST_CR0, &(p->cr0));
+ CHK_VMCS_READ(GUEST_CR3, &(p->cr3));
+ CHK_VMCS_READ(GUEST_CR4, &(p->cr4));
+ CHK_VMCS_READ(GUEST_DR7, &(p->dr7));
+ CHK_VMCS_READ(GUEST_RSP, &(p->rsp));
+ CHK_VMCS_READ(GUEST_RIP, &(p->rip));
+ CHK_VMCS_READ(GUEST_RFLAGS, &(p->rflags));
+ CHK_VMCS_READ(VMCS_GUEST_CS_SELECTOR, &(p->cs.selector));
+ CHK_VMCS_READ(VMCS_GUEST_SS_SELECTOR, &(p->ss.selector));
+ CHK_VMCS_READ(VMCS_GUEST_DS_SELECTOR, &(p->ds.selector));
+ CHK_VMCS_READ(VMCS_GUEST_ES_SELECTOR, &(p->es.selector));
+ CHK_VMCS_READ(VMCS_GUEST_FS_SELECTOR, &(p->fs.selector));
+ CHK_VMCS_READ(VMCS_GUEST_GS_SELECTOR, &(p->gs.selector));
+ CHK_VMCS_READ(VMCS_GUEST_LDTR_SELECTOR, &(p->ldtr.selector));
+ CHK_VMCS_READ(VMCS_GUEST_TR_SELECTOR, &(p->tr.selector));
+ CHK_VMCS_READ(GUEST_CS_BASE, &(p->cs.baseAddr));
+ CHK_VMCS_READ(GUEST_SS_BASE, &(p->ss.baseAddr));
+ CHK_VMCS_READ(GUEST_DS_BASE, &(p->ds.baseAddr));
+ CHK_VMCS_READ(GUEST_ES_BASE, &(p->es.baseAddr));
+ CHK_VMCS_READ(GUEST_FS_BASE, &(p->fs.baseAddr));
+ CHK_VMCS_READ(GUEST_GS_BASE, &(p->gs.baseAddr));
+ CHK_VMCS_READ(GUEST_LDTR_BASE, &(p->ldtr.baseAddr));
+ CHK_VMCS_READ(GUEST_TR_BASE, &(p->tr.baseAddr));
+ CHK_VMCS_READ(GUEST_CS_LIMIT, &(p->cs.limit));
+ CHK_VMCS_READ(GUEST_SS_LIMIT, &(p->ss.limit));
+ CHK_VMCS_READ(GUEST_DS_LIMIT, &(p->ds.limit));
+ CHK_VMCS_READ(GUEST_ES_LIMIT, &(p->es.limit));
+ CHK_VMCS_READ(GUEST_FS_LIMIT, &(p->fs.limit));
+ CHK_VMCS_READ(GUEST_GS_LIMIT, &(p->gs.limit));
+ CHK_VMCS_READ(GUEST_LDTR_LIMIT, &(p->ldtr.limit));
+ CHK_VMCS_READ(GUEST_TR_LIMIT, &(p->tr.limit));
+ CHK_VMCS_READ(GUEST_CS_ACCESS, &(p->cs.access));
+ CHK_VMCS_READ(GUEST_SS_ACCESS, &(p->ss.access));
+ CHK_VMCS_READ(GUEST_DS_ACCESS, &(p->ds.access));
+ CHK_VMCS_READ(GUEST_ES_ACCESS, &(p->es.access));
+ CHK_VMCS_READ(GUEST_FS_ACCESS, &(p->fs.access));
+ CHK_VMCS_READ(GUEST_GS_ACCESS, &(p->gs.access));
+ CHK_VMCS_READ(GUEST_LDTR_ACCESS, &(p->ldtr.access));
+ CHK_VMCS_READ(GUEST_TR_ACCESS, &(p->tr.access));
+ CHK_VMCS_READ(GUEST_GDTR_BASE, &(p->gdtr.baseAddr));
+ CHK_VMCS_READ(GUEST_IDTR_BASE, &(p->idtr.baseAddr));
+ CHK_VMCS_READ(GUEST_GDTR_LIMIT, &(p->gdtr.limit));
+ CHK_VMCS_READ(GUEST_IDTR_LIMIT, &(p->idtr.limit));
+ CHK_VMCS_READ(GUEST_IA32_DEBUGCTL, &(p->dbg_ctrl));
+ CHK_VMCS_READ(GUEST_IA32_DEBUGCTL_HIGH, ((char *)&(p->dbg_ctrl)) + 4);
+ CHK_VMCS_READ(GUEST_IA32_SYSENTER_CS, &(p->sysenter_cs));
+ CHK_VMCS_READ(GUEST_IA32_SYSENTER_ESP, &(p->sysenter_esp));
+ CHK_VMCS_READ(GUEST_IA32_SYSENTER_EIP, &(p->sysenter_eip));
+ CHK_VMCS_READ(GUEST_SMBASE, &(p->smbase));
+
+ CHK_VMCS_READ(GUEST_ACTIVITY_STATE, &(p->activity));
+ CHK_VMCS_READ(GUEST_INT_STATE, &(p->interrupt_state));
+ CHK_VMCS_READ(GUEST_PENDING_DEBUG_EXCS, &(p->pending_dbg_exceptions));
+ CHK_VMCS_READ(VMCS_LINK_PTR, &(p->vmcs_link));
+ CHK_VMCS_READ(VMCS_LINK_PTR_HIGH, ((char *)&(p->vmcs_link)) + 4);
+ return 0;
+}
+
+
+int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea *p) {
+ CHK_VMCS_WRITE(GUEST_CR0, &(p->cr0));
+ CHK_VMCS_WRITE(GUEST_CR3, &(p->cr3));
+ CHK_VMCS_WRITE(GUEST_CR4, &(p->cr4));
+ CHK_VMCS_WRITE(GUEST_DR7, &(p->dr7));
+ CHK_VMCS_WRITE(GUEST_RSP, &(p->rsp));
+ CHK_VMCS_WRITE(GUEST_RIP, &(p->rip));
+ CHK_VMCS_WRITE(GUEST_RFLAGS, &(p->rflags));
+ CHK_VMCS_WRITE(VMCS_GUEST_CS_SELECTOR, &(p->cs.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_SS_SELECTOR, &(p->ss.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_DS_SELECTOR, &(p->ds.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_ES_SELECTOR, &(p->es.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_FS_SELECTOR, &(p->fs.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_GS_SELECTOR, &(p->gs.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_LDTR_SELECTOR, &(p->ldtr.selector));
+ CHK_VMCS_WRITE(VMCS_GUEST_TR_SELECTOR, &(p->tr.selector));
+ CHK_VMCS_WRITE(GUEST_CS_BASE, &(p->cs.baseAddr));
+ CHK_VMCS_WRITE(GUEST_SS_BASE, &(p->ss.baseAddr));
+ CHK_VMCS_WRITE(GUEST_DS_BASE, &(p->ds.baseAddr));
+ CHK_VMCS_WRITE(GUEST_ES_BASE, &(p->es.baseAddr));
+ CHK_VMCS_WRITE(GUEST_FS_BASE, &(p->fs.baseAddr));
+ CHK_VMCS_WRITE(GUEST_GS_BASE, &(p->gs.baseAddr));
+ CHK_VMCS_WRITE(GUEST_LDTR_BASE, &(p->ldtr.baseAddr));
+ CHK_VMCS_WRITE(GUEST_TR_BASE, &(p->tr.baseAddr));
+ CHK_VMCS_WRITE(GUEST_CS_LIMIT, &(p->cs.limit));
+ CHK_VMCS_WRITE(GUEST_SS_LIMIT, &(p->ss.limit));
+ CHK_VMCS_WRITE(GUEST_DS_LIMIT, &(p->ds.limit));
+ CHK_VMCS_WRITE(GUEST_ES_LIMIT, &(p->es.limit));
+ CHK_VMCS_WRITE(GUEST_FS_LIMIT, &(p->fs.limit));
+ CHK_VMCS_WRITE(GUEST_GS_LIMIT, &(p->gs.limit));
+ CHK_VMCS_WRITE(GUEST_LDTR_LIMIT, &(p->ldtr.limit));
+ CHK_VMCS_WRITE(GUEST_TR_LIMIT, &(p->tr.limit));
+ CHK_VMCS_WRITE(GUEST_CS_ACCESS, &(p->cs.access));
+ CHK_VMCS_WRITE(GUEST_SS_ACCESS, &(p->ss.access));
+ CHK_VMCS_WRITE(GUEST_DS_ACCESS, &(p->ds.access));
+ CHK_VMCS_WRITE(GUEST_ES_ACCESS, &(p->es.access));
+ CHK_VMCS_WRITE(GUEST_FS_ACCESS, &(p->fs.access));
+ CHK_VMCS_WRITE(GUEST_GS_ACCESS, &(p->gs.access));
+ CHK_VMCS_WRITE(GUEST_LDTR_ACCESS, &(p->ldtr.access));
+ CHK_VMCS_WRITE(GUEST_TR_ACCESS, &(p->tr.access));
+ CHK_VMCS_WRITE(GUEST_GDTR_BASE, &(p->gdtr.baseAddr));
+ CHK_VMCS_WRITE(GUEST_IDTR_BASE, &(p->idtr.baseAddr));
+ CHK_VMCS_WRITE(GUEST_GDTR_LIMIT, &(p->gdtr.limit));
+ CHK_VMCS_WRITE(GUEST_IDTR_LIMIT, &(p->idtr.limit));
+ CHK_VMCS_WRITE(GUEST_IA32_DEBUGCTL, &(p->dbg_ctrl));
+ CHK_VMCS_WRITE(GUEST_IA32_DEBUGCTL_HIGH, ((char *)&(p->dbg_ctrl)) + 4);
+ CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_CS, &(p->sysenter_cs));
+ CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_ESP, &(p->sysenter_esp));
+ CHK_VMCS_WRITE(GUEST_IA32_SYSENTER_EIP, &(p->sysenter_eip));
+ CHK_VMCS_WRITE(GUEST_SMBASE, &(p->smbase));
+
+ CHK_VMCS_WRITE(GUEST_ACTIVITY_STATE, &(p->activity));
+ CHK_VMCS_WRITE(GUEST_INT_STATE, &(p->interrupt_state));
+ CHK_VMCS_WRITE(GUEST_PENDING_DEBUG_EXCS, &(p->pending_dbg_exceptions));
+ CHK_VMCS_WRITE(VMCS_LINK_PTR, &(p->vmcs_link));
+ CHK_VMCS_WRITE(VMCS_LINK_PTR_HIGH, ((char *)&(p->vmcs_link)) + 4);
+ return 0;
+}
+
+
+
+int CopyOutVMCSHostStateArea(struct VMCSHostStateArea *p) {
+ CHK_VMCS_READ(HOST_CR0, &(p->cr0));
+ CHK_VMCS_READ(HOST_CR3, &(p->cr3));
+ CHK_VMCS_READ(HOST_CR4, &(p->cr4));
+ CHK_VMCS_READ(HOST_RSP, &(p->rsp));
+ CHK_VMCS_READ(HOST_RIP, &(p->rip));
+ CHK_VMCS_READ(VMCS_HOST_CS_SELECTOR, &(p->csSelector));
+ CHK_VMCS_READ(VMCS_HOST_SS_SELECTOR, &(p->ssSelector));
+ CHK_VMCS_READ(VMCS_HOST_DS_SELECTOR, &(p->dsSelector));
+ CHK_VMCS_READ(VMCS_HOST_ES_SELECTOR, &(p->esSelector));
+ CHK_VMCS_READ(VMCS_HOST_FS_SELECTOR, &(p->fsSelector));
+ CHK_VMCS_READ(VMCS_HOST_GS_SELECTOR, &(p->gsSelector));
+ CHK_VMCS_READ(VMCS_HOST_TR_SELECTOR, &(p->trSelector));
+ CHK_VMCS_READ(HOST_FS_BASE, &(p->fsBaseAddr));
+ CHK_VMCS_READ(HOST_GS_BASE, &(p->gsBaseAddr));
+ CHK_VMCS_READ(HOST_TR_BASE, &(p->trBaseAddr));
+ CHK_VMCS_READ(HOST_GDTR_BASE, &(p->gdtrBaseAddr));
+ CHK_VMCS_READ(HOST_IDTR_BASE, &(p->idtrBaseAddr));
+ CHK_VMCS_READ(HOST_IA32_SYSENTER_CS, &(p->sysenter_cs));
+ CHK_VMCS_READ(HOST_IA32_SYSENTER_ESP, &(p->sysenter_esp));
+ CHK_VMCS_READ(HOST_IA32_SYSENTER_EIP, &(p->sysenter_eip));
+ return 0;
+}
+
+
+
+int CopyInVMCSHostStateArea(struct VMCSHostStateArea *p) {
+ CHK_VMCS_WRITE(HOST_CR0, &(p->cr0));
+ CHK_VMCS_WRITE(HOST_CR3, &(p->cr3));
+ CHK_VMCS_WRITE(HOST_CR4, &(p->cr4));
+ CHK_VMCS_WRITE(HOST_RSP, &(p->rsp));
+ CHK_VMCS_WRITE(HOST_RIP, &(p->rip));
+ CHK_VMCS_WRITE(VMCS_HOST_CS_SELECTOR, &(p->csSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_SS_SELECTOR, &(p->ssSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_DS_SELECTOR, &(p->dsSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_ES_SELECTOR, &(p->esSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_FS_SELECTOR, &(p->fsSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_GS_SELECTOR, &(p->gsSelector));
+ CHK_VMCS_WRITE(VMCS_HOST_TR_SELECTOR, &(p->trSelector));
+ CHK_VMCS_WRITE(HOST_FS_BASE, &(p->fsBaseAddr));
+ CHK_VMCS_WRITE(HOST_GS_BASE, &(p->gsBaseAddr));
+ CHK_VMCS_WRITE(HOST_TR_BASE, &(p->trBaseAddr));
+ CHK_VMCS_WRITE(HOST_GDTR_BASE, &(p->gdtrBaseAddr));
+ CHK_VMCS_WRITE(HOST_IDTR_BASE, &(p->idtrBaseAddr));
+ CHK_VMCS_WRITE(HOST_IA32_SYSENTER_CS, &(p->sysenter_cs));
+ CHK_VMCS_WRITE(HOST_IA32_SYSENTER_ESP, &(p->sysenter_esp));
+ CHK_VMCS_WRITE(HOST_IA32_SYSENTER_EIP, &(p->sysenter_eip));
+ return 0;
+}
+
+
+int CopyOutVMCSExitCtrlFields(struct VMCSExitCtrlFields *p)
+{
+ CHK_VMCS_READ(VM_EXIT_CTRLS,&(p->exitCtrls));
+ CHK_VMCS_READ(VM_EXIT_MSR_STORE_COUNT,&(p->msrStoreCount));
+ CHK_VMCS_READ(VM_EXIT_MSR_STORE_ADDR,&(p->msrStoreAddr));
+ CHK_VMCS_READ(VM_EXIT_MSR_LOAD_COUNT,&(p->msrLoadCount));
+ CHK_VMCS_READ(VM_EXIT_MSR_LOAD_ADDR,&(p->msrLoadAddr));
+ return 0;
+}
+
+int CopyInVMCSExitCtrlFields(struct VMCSExitCtrlFields *p)
+{
+ CHK_VMCS_WRITE(VM_EXIT_CTRLS,&(p->exitCtrls));
+ CHK_VMCS_WRITE(VM_EXIT_MSR_STORE_COUNT,&(p->msrStoreCount));
+ CHK_VMCS_WRITE(VM_EXIT_MSR_STORE_ADDR,&(p->msrStoreAddr));
+ CHK_VMCS_WRITE(VM_EXIT_MSR_LOAD_COUNT,&(p->msrLoadCount));
+ CHK_VMCS_WRITE(VM_EXIT_MSR_LOAD_ADDR,&(p->msrLoadAddr));
+ return 0;
+}
+
+
+int CopyOutVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p)
+{
+ CHK_VMCS_READ(VM_ENTRY_CTRLS,&(p->entryCtrls));
+ CHK_VMCS_READ(VM_ENTRY_MSR_LOAD_COUNT,&(p->msrLoadCount));
+ CHK_VMCS_READ(VM_ENTRY_MSR_LOAD_ADDR,&(p->msrLoadAddr));
+ CHK_VMCS_READ(VM_ENTRY_INT_INFO_FIELD,&(p->intInfo));
+ CHK_VMCS_READ(VM_ENTRY_EXCEPTION_ERROR,&(p->exceptionErrorCode));
+ CHK_VMCS_READ(VM_ENTRY_INSTR_LENGTH,&(p->instrLength));
+ return 0;
+}
+
+int CopyInVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p)
+{
+ CHK_VMCS_WRITE(VM_ENTRY_CTRLS,&(p->entryCtrls));
+ CHK_VMCS_WRITE(VM_ENTRY_MSR_LOAD_COUNT,&(p->msrLoadCount));
+ CHK_VMCS_WRITE(VM_ENTRY_MSR_LOAD_ADDR,&(p->msrLoadAddr));
+ CHK_VMCS_WRITE(VM_ENTRY_INT_INFO_FIELD,&(p->intInfo));
+ CHK_VMCS_WRITE(VM_ENTRY_EXCEPTION_ERROR,&(p->exceptionErrorCode));
+ CHK_VMCS_WRITE(VM_ENTRY_INSTR_LENGTH,&(p->instrLength));
+ return 0;
+}
+
+int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p) {
+ CHK_VMCS_READ(EXIT_REASON,&(p->reason));
+ CHK_VMCS_READ(EXIT_QUALIFICATION,&(p->qualification));
+ CHK_VMCS_READ(VM_EXIT_INT_INFO,&(p->intInfo));
+ CHK_VMCS_READ(VM_EXIT_INT_ERROR,&(p->intErrorCode));
+ CHK_VMCS_READ(IDT_VECTOR_INFO,&(p->idtVectorInfo));
+ CHK_VMCS_READ(IDT_VECTOR_ERROR,&(p->idtVectorErrorCode));
+ CHK_VMCS_READ(VM_EXIT_INSTR_LENGTH,&(p->instrLength));
+ CHK_VMCS_READ(GUEST_LINEAR_ADDR,&(p->guestLinearAddr));
+ CHK_VMCS_READ(VMX_INSTR_INFO,&(p->instrInfo));
+ CHK_VMCS_READ(IO_RCX,&(p->ioRCX));
+ CHK_VMCS_READ(IO_RSI,&(p->ioRSI));
+ CHK_VMCS_READ(IO_RDI,&(p->ioRDI));
+ CHK_VMCS_READ(IO_RIP,&(p->ioRIP));
+ CHK_VMCS_READ(VM_INSTR_ERROR,&(p->instrErrorField));
+ return 0;
+}
+
+
+int CopyOutVMCSExecCtrlFields(struct VMCSExecCtrlFields *p)
+{
+ CHK_VMCS_READ(PIN_VM_EXEC_CTRLS,&(p->pinCtrls));
+ CHK_VMCS_READ(PROC_VM_EXEC_CTRLS,&(p->procCtrls));
+ CHK_VMCS_READ(EXCEPTION_BITMAP,&(p->execBitmap));
+ CHK_VMCS_READ(PAGE_FAULT_ERROR_MASK,&(p->pageFaultErrorMask));
+ CHK_VMCS_READ(PAGE_FAULT_ERROR_MATCH,&(p->pageFaultErrorMatch));
+ CHK_VMCS_READ(IO_BITMAP_A_ADDR,&(p->ioBitmapA));
+ CHK_VMCS_READ(IO_BITMAP_B_ADDR,&(p->ioBitmapB));
+ CHK_VMCS_READ(TSC_OFFSET,&(p->tscOffset));
+ CHK_VMCS_READ(CR0_GUEST_HOST_MASK,&(p->cr0GuestHostMask));
+ CHK_VMCS_READ(CR0_READ_SHADOW,&(p->cr0ReadShadow));
+ CHK_VMCS_READ(CR4_GUEST_HOST_MASK,&(p->cr4GuestHostMask));
+ CHK_VMCS_READ(CR4_READ_SHADOW,&(p->cr4ReadShadow));
+ CHK_VMCS_READ(CR3_TARGET_COUNT, &(p->cr3TargetCount));
+ CHK_VMCS_READ(CR3_TARGET_VALUE_0, &(p->cr3TargetValue0));
+ CHK_VMCS_READ(CR3_TARGET_VALUE_1, &(p->cr3TargetValue1));
+ CHK_VMCS_READ(CR3_TARGET_VALUE_2, &(p->cr3TargetValue2));
+ CHK_VMCS_READ(CR3_TARGET_VALUE_3, &(p->cr3TargetValue3));
+ CHK_VMCS_READ(VIRT_APIC_PAGE_ADDR, &(p->virtApicPageAddr));
+ CHK_VMCS_READ(TPR_THRESHOLD, &(p->tprThreshold));
+ CHK_VMCS_READ(MSR_BITMAPS, &(p->MSRBitmapsBaseAddr));
+ CHK_VMCS_READ(VMCS_EXEC_PTR,&(p->vmcsExecPtr));
+ return 0;
+}
+
+
+int CopyInVMCSExecCtrlFields(struct VMCSExecCtrlFields *p)
+{
+ CHK_VMCS_WRITE(PIN_VM_EXEC_CTRLS,&(p->pinCtrls));
+ CHK_VMCS_WRITE(PROC_VM_EXEC_CTRLS,&(p->procCtrls));
+ CHK_VMCS_WRITE(EXCEPTION_BITMAP,&(p->execBitmap));
+ CHK_VMCS_WRITE(PAGE_FAULT_ERROR_MASK,&(p->pageFaultErrorMask));
+ CHK_VMCS_WRITE(PAGE_FAULT_ERROR_MATCH,&(p->pageFaultErrorMatch));
+ CHK_VMCS_WRITE(IO_BITMAP_A_ADDR,&(p->ioBitmapA));
+ CHK_VMCS_WRITE(IO_BITMAP_B_ADDR,&(p->ioBitmapB));
+ CHK_VMCS_WRITE(TSC_OFFSET,&(p->tscOffset));
+ CHK_VMCS_WRITE(CR0_GUEST_HOST_MASK,&(p->cr0GuestHostMask));
+ CHK_VMCS_WRITE(CR0_READ_SHADOW,&(p->cr0ReadShadow));
+ CHK_VMCS_WRITE(CR4_GUEST_HOST_MASK,&(p->cr4GuestHostMask));
+ CHK_VMCS_WRITE(CR4_READ_SHADOW,&(p->cr4ReadShadow));
+ CHK_VMCS_WRITE(CR3_TARGET_COUNT, &(p->cr3TargetCount));
+ CHK_VMCS_WRITE(CR3_TARGET_VALUE_0, &(p->cr3TargetValue0));
+ CHK_VMCS_WRITE(CR3_TARGET_VALUE_1, &(p->cr3TargetValue1));
+ CHK_VMCS_WRITE(CR3_TARGET_VALUE_2, &(p->cr3TargetValue2));
+ CHK_VMCS_WRITE(CR3_TARGET_VALUE_3, &(p->cr3TargetValue3));
+ CHK_VMCS_WRITE(VIRT_APIC_PAGE_ADDR, &(p->virtApicPageAddr));
+ CHK_VMCS_WRITE(TPR_THRESHOLD, &(p->tprThreshold));
+ CHK_VMCS_WRITE(MSR_BITMAPS, &(p->MSRBitmapsBaseAddr));
+ CHK_VMCS_WRITE(VMCS_EXEC_PTR,&(p->vmcsExecPtr));
+ return 0;
+}
+
+
+int CopyOutVMCSData(struct VMCSData *p) {
+ if (CopyOutVMCSGuestStateArea(&(p->guestStateArea)) != 0) {
+ return -1;
+ }
+ if (CopyOutVMCSHostStateArea(&(p->hostStateArea)) != 0) {
+ return -1;
+ }
+ if (CopyOutVMCSExecCtrlFields(&(p->execCtrlFields)) != 0) {
+ return -1;
+ }
+ if (CopyOutVMCSExitCtrlFields(&(p->exitCtrlFields)) != 0) {
+ return -1;
+ }
+ if (CopyOutVMCSEntryCtrlFields(&(p->entryCtrlFields)) != 0) {
+ return -1;
+ }
+ if (CopyOutVMCSExitInfoFields(&(p->exitInfoFields)) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+
+int CopyInVMCSData(struct VMCSData *p) {
+ if (CopyInVMCSGuestStateArea(&(p->guestStateArea)) != 0) {
+ return -1;
+ }
+ if (CopyInVMCSHostStateArea(&(p->hostStateArea)) != 0) {
+ return -1;
+ }
+ if (CopyInVMCSExecCtrlFields(&(p->execCtrlFields)) != 0) {
+ return -1;
+ }
+ if (CopyInVMCSExitCtrlFields(&(p->exitCtrlFields)) != 0) {
+ return -1;
+ }
+ if (CopyInVMCSEntryCtrlFields(&(p->entryCtrlFields)) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+
+void PrintTrace_VMX_Regs(struct VMXRegs * regs) {
+ PrintTrace("==>VMX Register values:\n");
+ PrintTrace("EAX: %x\n", regs->eax);
+ PrintTrace("ECX: %x\n", regs->ecx);
+ PrintTrace("EDX: %x\n", regs->edx);
+ PrintTrace("EBX: %x\n", regs->ebx);
+ PrintTrace("ESP: %x\n", regs->esp);
+ PrintTrace("EBP: %x\n", regs->ebp);
+ PrintTrace("ESI: %x\n", regs->esi);
+ PrintTrace("EDI: %x\n", regs->edi);
+ PrintTrace("\n");
+}
+
+
+void PrintTrace_VMCSSegment(char * segname, struct VMCSSegment * seg, int abbr) {
+ PrintTrace("Segment: %s\n", segname);
+ if (abbr == 0) {
+ PrintTrace("\tSelector: %x\n", (uint_t)seg->selector);
+ PrintTrace("\tAccess: %x\n", *(uint_t*)&(seg->access));
+ }
+ PrintTrace("\tBase Addr: %x\n", (uint_t)seg->baseAddr);
+ PrintTrace("\tLimit: %x\n", (uint_t)seg->limit);
+
+}
+
+
+void PrintTrace_VMCSGuestStateArea(struct VMCSGuestStateArea * guestState) {
+ PrintTrace("==>Guest State Area\n");
+ PrintTrace("==>==> Guest Register State\n");
+ PrintTrace("GUEST_CR0: %x\n",(uint_t) guestState->cr0);
+ PrintTrace("GUEST_CR3: %x\n",(uint_t)guestState->cr3);
+ PrintTrace("GUEST_CR4: %x\n",(uint_t)guestState->cr4);
+ PrintTrace("GUEST_DR7: %x\n",(uint_t)guestState->dr7);
+ PrintTrace("GUEST_RSP: %x\n",(uint_t)guestState->rsp);
+ PrintTrace("GUEST_RIP: %x\n",(uint_t)guestState->rip);
+ PrintTrace("GUEST_RFLAGS: %x\n",(uint_t)guestState->rflags);
+
+ PrintTrace_VMCSSegment("Guest CS", &(guestState->cs), 0);
+ PrintTrace_VMCSSegment("Guest SS", &(guestState->ss), 0);
+ PrintTrace_VMCSSegment("Guest DS",&(guestState->ds), 0);
+ PrintTrace_VMCSSegment("Guest ES", &(guestState->es), 0);
+ PrintTrace_VMCSSegment("Guest FS", &(guestState->fs), 0);
+ PrintTrace_VMCSSegment("Guest GS", &(guestState->gs), 0);
+ PrintTrace_VMCSSegment("Guest LDTR", &(guestState->ldtr), 0);
+ PrintTrace_VMCSSegment("Guest TR", &(guestState->tr), 0);
+ PrintTrace_VMCSSegment("Guest GDTR", &(guestState->gdtr), 1);
+ PrintTrace_VMCSSegment("Guest IDTR", &(guestState->idtr), 1);
+
+
+ PrintTrace("GUEST_IA32_DEBUGCTL: %x\n",(uint_t)(guestState->dbg_ctrl & 0xffffffff));
+ PrintTrace("GUEST_IA32_DEBUGCTL_HIGH: %x\n",(uint_t)(guestState->dbg_ctrl >> 32) & 0xffffffff);
+ PrintTrace("GUEST_IA32_SYSENTER_CS: %x\n",guestState->sysenter_cs);
+ PrintTrace("GUEST_IA32_SYSENTER_ESP: %x\n",(uint_t)guestState->sysenter_esp);
+ PrintTrace("GUEST_IA32_SYSENTER_EIP: %x\n",(uint_t)guestState->sysenter_eip);
+ PrintTrace("GUEST_SMBASE: %x\n", (uint_t)guestState->smbase);
+
+ PrintTrace("==>==> Guest Non-Register State\n");
+ PrintTrace("GUEST_ACTIVITY_STATE: %x\n", (uint_t)guestState->activity);
+ PrintTrace("GUEST_INT_STATE: %x\n", (uint_t)guestState->interrupt_state);
+ PrintTrace("GUEST_PENDING_DEBUG_EXCS: %x\n", (uint_t)guestState->pending_dbg_exceptions);
+ PrintTrace("VMCS_LINK_PTR: %x\n", (uint_t)guestState->vmcs_link & 0xffffffff);
+ PrintTrace("VMCS_LINK_PTR_HIGH: %x\n", (uint_t)(guestState->vmcs_link >> 32) & 0xffffffff);
+}
+
+
+void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState) {
+ PrintTrace("\n==> Host State Area\n");
+ PrintTrace("HOST_CR0: %x\n", (uint_t)hostState->cr0);
+ PrintTrace("HOST_CR3: %x\n", (uint_t)hostState->cr3);
+ PrintTrace("HOST_CR4: %x\n", (uint_t)hostState->cr4);
+ PrintTrace("HOST_RSP: %x\n", (uint_t)hostState->rsp);
+ PrintTrace("HOST_RIP: %x\n", (uint_t)hostState->rip);
+ PrintTrace("VMCS_HOST_CS_SELECTOR: %x\n", (uint_t)hostState->csSelector);
+ PrintTrace("VMCS_HOST_SS_SELECTOR: %x\n", (uint_t)hostState->ssSelector);
+ PrintTrace("VMCS_HOST_DS_SELECTOR: %x\n", (uint_t)hostState->dsSelector);
+ PrintTrace("VMCS_HOST_ES_SELECTOR: %x\n", (uint_t)hostState->esSelector);
+ PrintTrace("VMCS_HOST_FS_SELECTOR: %x\n", (uint_t)hostState->fsSelector);
+ PrintTrace("VMCS_HOST_GS_SELECTOR: %x\n", (uint_t)hostState->gsSelector);
+ PrintTrace("VMCS_HOST_TR_SELECTOR: %x\n", (uint_t)hostState->trSelector);
+ PrintTrace("HOST_FS_BASE: %x\n", (uint_t)hostState->fsBaseAddr);
+ PrintTrace("HOST_GS_BASE: %x\n", (uint_t)hostState->gsBaseAddr);
+ PrintTrace("HOST_TR_BASE: %x\n", (uint_t)hostState->trBaseAddr);
+ PrintTrace("HOST_GDTR_BASE: %x\n", (uint_t)hostState->gdtrBaseAddr);
+ PrintTrace("HOST_IDTR_BASE: %x\n", (uint_t)hostState->idtrBaseAddr);
+ PrintTrace("HOST_IA32_SYSENTER_CS: %x\n", (uint_t)hostState->sysenter_cs);
+ PrintTrace("HOST_IA32_SYSENTER_ESP: %x\n", (uint_t)hostState->sysenter_esp);
+ PrintTrace("HOST_IA32_SYSENTER_EIP: %x\n", (uint_t)hostState->sysenter_eip);
+}
+
+void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls) {
+ PrintTrace("\n==> VM-Execution Controls:\n");
+ PrintTrace("PIN_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->pinCtrls);
+ PrintTrace("PROC_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->procCtrls);
+ PrintTrace("EXCEPTION_BITMAP: %x\n", (uint_t) execCtrls->execBitmap);
+ PrintTrace("PAGE_FAULT_ERROR_MASK: %x\n", (uint_t) execCtrls->pageFaultErrorMask);
+ PrintTrace("PAGE_FAULT_ERROR_MATCH: %x\n", (uint_t) execCtrls->pageFaultErrorMatch);
+ PrintTrace("IO_BITMAP_A_ADDR: %x\n", (uint_t) execCtrls->ioBitmapA);
+ // PrintTrace("IO_BITMAP_A_ADDR_HIGH: %x\n", (uint_t) execCtrls->);
+ PrintTrace("IO_BITMAP_B_ADDR: %x\n", (uint_t) execCtrls->ioBitmapB);
+ // PrintTrace("IO_BITMAP_B_ADDR_HIGH: %x\n", (uint_t) execCtrls->);
+ PrintTrace("TSC_OFFSET: %x\n", (uint_t) execCtrls->tscOffset & 0xffffffff);
+ PrintTrace("TSC_OFFSET_HIGH: %x\n", (uint_t) (execCtrls->tscOffset >> 32) & 0xffffffff);
+ PrintTrace("CR0_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr0GuestHostMask);
+ PrintTrace("CR0_READ_SHADOW: %x\n", (uint_t) execCtrls->cr0ReadShadow);
+ PrintTrace("CR4_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr4GuestHostMask);
+ PrintTrace("CR4_READ_SHADOW: %x\n", (uint_t) execCtrls->cr4ReadShadow);
+ PrintTrace("CR3_TARGET_COUNT: %x\n", (uint_t) execCtrls->cr3TargetCount);
+ PrintTrace("CR3_TARGET_VALUE_0: %x\n", (uint_t) execCtrls->cr3TargetValue0);
+ PrintTrace("CR3_TARGET_VALUE_1: %x\n", (uint_t) execCtrls->cr3TargetValue1);
+ PrintTrace("CR3_TARGET_VALUE_2: %x\n", (uint_t) execCtrls->cr3TargetValue2);
+ PrintTrace("CR3_TARGET_VALUE_3: %x\n", (uint_t) execCtrls->cr3TargetValue3);
+ PrintTrace("VIRT_APIC_PAGE_ADDR: %x\n", (uint_t) execCtrls->virtApicPageAddr & 0xffffffff);
+ PrintTrace("VIRT_APIC_PAGE_ADDR_HIGH: %x\n", (uint_t) (execCtrls->virtApicPageAddr >> 32) & 0xffffffff);
+ PrintTrace("TPR_THRESHOLD: %x\n", (uint_t) execCtrls->tprThreshold);
+ PrintTrace("MSR_BITMAPS: %x\n", (uint_t) execCtrls->MSRBitmapsBaseAddr & 0xffffffff);
+ PrintTrace("MSR_BITMAPS_HIGH: %x\n", (uint_t) (execCtrls->MSRBitmapsBaseAddr >> 32) & 0xffffffff);
+ PrintTrace("VMCS_EXEC_PTR: %x\n", (uint_t) execCtrls->vmcsExecPtr & 0xffffffff);
+ PrintTrace("VMCS_EXEC_PTR_HIGH: %x\n", (uint_t) (execCtrls->vmcsExecPtr >> 32) & 0xffffffff);
+}
+
+void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls) {
+ PrintTrace("\n==> VM Exit Controls\n");
+ PrintTrace("VM_EXIT_CTRLS: %x\n", (uint_t) exitCtrls->exitCtrls);
+ PrintTrace("VM_EXIT_MSR_STORE_COUNT: %x\n", (uint_t) exitCtrls->msrStoreCount);
+ PrintTrace("VM_EXIT_MSR_STORE_ADDR: %x\n", (uint_t) exitCtrls->msrStoreAddr & 0xffffffff);
+ PrintTrace("VM_EXIT_MSR_STORE_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrStoreAddr >> 32) & 0xffffffff);
+ PrintTrace("VM_EXIT_MSR_LOAD_COUNT: %x\n", (uint_t) exitCtrls->msrLoadCount);
+ PrintTrace("VM_EXIT_MSR_LOAD_ADDR: %x\n", (uint_t) exitCtrls->msrLoadAddr & 0xffffffff);
+ PrintTrace("VM_EXIT_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrLoadAddr >> 32) & 0xffffffff);
+}
+
+void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls) {
+ PrintTrace("\n==> VM Entry Controls\n");
+ PrintTrace("VM_ENTRY_CTRLS: %x\n", (uint_t) entryCtrls->entryCtrls);
+ PrintTrace("VM_ENTRY_MSR_LOAD_COUNT: %x\n", (uint_t) entryCtrls->msrLoadCount);
+ PrintTrace("VM_ENTRY_MSR_LOAD_ADDR: %x\n", (uint_t) entryCtrls->msrLoadAddr & 0xffffffff);
+ PrintTrace("VM_ENTRY_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (entryCtrls->msrLoadAddr >> 32) & 0xffffffff);
+ PrintTrace("VM_ENTRY_INT_INFO_FIELD: %x\n", (uint_t) entryCtrls->intInfo);
+ PrintTrace("VM_ENTRY_EXCEPTION_ERROR: %x\n", (uint_t) entryCtrls->exceptionErrorCode);
+ PrintTrace("VM_ENTRY_INSTR_LENGTH: %x\n", (uint_t) entryCtrls->instrLength);
+}
+
+void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo) {
+ PrintTrace("\n==> VM Exit Info\n");
+ PrintTrace("EXIT_REASON: %x\n", (uint_t) exitInfo->reason);
+ PrintTrace("EXIT_QUALIFICATION: %x\n", (uint_t) exitInfo->qualification);
+ PrintTrace("VM_EXIT_INT_INFO: %x\n", (uint_t) exitInfo->intInfo);
+ PrintTrace("VM_EXIT_INT_ERROR: %x\n", (uint_t) exitInfo->intErrorCode);
+ PrintTrace("IDT_VECTOR_INFO: %x\n", (uint_t) exitInfo->idtVectorInfo);
+ PrintTrace("IDT_VECTOR_ERROR: %x\n", (uint_t) exitInfo->idtVectorErrorCode);
+ PrintTrace("VM_EXIT_INSTR_LENGTH: %x\n", (uint_t) exitInfo->instrLength);
+ PrintTrace("GUEST_LINEAR_ADDR: %x\n", (uint_t) exitInfo->guestLinearAddr);
+ PrintTrace("VMX_INSTR_INFO: %x\n", (uint_t) exitInfo->instrInfo);
+ PrintTrace("IO_RCX: %x\n", (uint_t) exitInfo->ioRCX);
+ PrintTrace("IO_RSI: %x\n", (uint_t) exitInfo->ioRSI);
+ PrintTrace("IO_RDI: %x\n", (uint_t) exitInfo->ioRDI);
+ PrintTrace("IO_RIP: %x\n", (uint_t) exitInfo->ioRIP);
+ PrintTrace("VM_INSTR_ERROR: %x\n", (uint_t) exitInfo->instrErrorField);
+}
+
+
+void PrintTrace_VMCSData(struct VMCSData * vmcs) {
+ PrintTrace("VMCSData Structure\n");
+
+ PrintTrace_VMCSGuestStateArea(&(vmcs->guestStateArea));
+ PrintTrace_VMCSHostStateArea(&(vmcs->hostStateArea));
+ PrintTrace_VMCSExecCtrlFields(&(vmcs->execCtrlFields));
+ PrintTrace_VMCSExitCtrlFields(&(vmcs->exitCtrlFields));
+ PrintTrace_VMCSEntryCtrlFields(&(vmcs->entryCtrlFields));
+ PrintTrace_VMCSExitInfoFields(&(vmcs->exitInfoFields));
+ PrintTrace("\n");
+}
--- /dev/null
+%ifndef VMCS_FIELDS_ASM
+%define VMCS_FIELDS_ASM
+
+VMCS_GUEST_ES_SELECTOR equ 0x00000800
+VMCS_GUEST_CS_SELECTOR equ 0x00000802
+VMCS_GUEST_SS_SELECTOR equ 0x00000804
+VMCS_GUEST_DS_SELECTOR equ 0x00000806
+VMCS_GUEST_FS_SELECTOR equ 0x00000808
+VMCS_GUEST_GS_SELECTOR equ 0x0000080A
+VMCS_GUEST_LDTR_SELECTOR equ 0x0000080C
+VMCS_GUEST_TR_SELECTOR equ 0x0000080E
+VMCS_HOST_ES_SELECTOR equ 0x00000C00
+VMCS_HOST_CS_SELECTOR equ 0x00000C02
+VMCS_HOST_SS_SELECTOR equ 0x00000C04
+VMCS_HOST_DS_SELECTOR equ 0x00000C06
+VMCS_HOST_FS_SELECTOR equ 0x00000C08
+VMCS_HOST_GS_SELECTOR equ 0x00000C0A
+VMCS_HOST_TR_SELECTOR equ 0x00000C0C
+IO_BITMAP_A_ADDR equ 0x00002000
+IO_BITMAP_A_ADDR_HIGH equ 0x00002001
+IO_BITMAP_B_ADDR equ 0x00002002
+IO_BITMAP_B_ADDR_HIGH equ 0x00002003
+MSR_BITMAPS equ 0x00002004
+MSR_BITMAPS_HIGH equ 0x00002005
+VM_EXIT_MSR_STORE_ADDR equ 0x00002006
+VM_EXIT_MSR_STORE_ADDR_HIGH equ 0x00002007
+VM_EXIT_MSR_LOAD_ADDR equ 0x00002008
+VM_EXIT_MSR_LOAD_ADDR_HIGH equ 0x00002009
+VM_ENTRY_MSR_LOAD_ADDR equ 0x0000200A
+VM_ENTRY_MSR_LOAD_ADDR_HIGH equ 0x0000200B
+VMCS_EXEC_PTR equ 0x0000200C
+VMCS_EXEC_PTR_HIGH equ 0x0000200D
+TSC_OFFSET equ 0x00002010
+TSC_OFFSET_HIGH equ 0x00002011
+VIRT_APIC_PAGE_ADDR equ 0x00002012
+VIRT_APIC_PAGE_ADDR_HIGH equ 0x00002013
+VMCS_LINK_PTR equ 0x00002800
+VMCS_LINK_PTR_HIGH equ 0x00002801
+GUEST_IA32_DEBUGCTL equ 0x00002802
+GUEST_IA32_DEBUGCTL_HIGH equ 0x00002803
+PIN_VM_EXEC_CTRLS equ 0x00004000
+PROC_VM_EXEC_CTRLS equ 0x00004002
+EXCEPTION_BITMAP equ 0x00004004
+PAGE_FAULT_ERROR_MASK equ 0x00004006
+PAGE_FAULT_ERROR_MATCH equ 0x00004008
+CR3_TARGET_COUNT equ 0x0000400A
+VM_EXIT_CTRLS equ 0x0000400C
+VM_EXIT_MSR_STORE_COUNT equ 0x0000400E
+VM_EXIT_MSR_LOAD_COUNT equ 0x00004010
+VM_ENTRY_CTRLS equ 0x00004012
+VM_ENTRY_MSR_LOAD_COUNT equ 0x00004014
+VM_ENTRY_INT_INFO_FIELD equ 0x00004016
+VM_ENTRY_EXCEPTION_ERROR equ 0x00004018
+VM_ENTRY_INSTR_LENGTH equ 0x0000401A
+TPR_THRESHOLD equ 0x0000401C
+VM_INSTR_ERROR equ 0x00004400
+EXIT_REASON equ 0x00004402
+VM_EXIT_INT_INFO equ 0x00004404
+VM_EXIT_INT_ERROR equ 0x00004406
+IDT_VECTOR_INFO equ 0x00004408
+IDT_VECTOR_ERROR equ 0x0000440A
+VM_EXIT_INSTR_LENGTH equ 0x0000440C
+VMX_INSTR_INFO equ 0x0000440E
+GUEST_ES_LIMIT equ 0x00004800
+GUEST_CS_LIMIT equ 0x00004802
+GUEST_SS_LIMIT equ 0x00004804
+GUEST_DS_LIMIT equ 0x00004806
+GUEST_FS_LIMIT equ 0x00004808
+GUEST_GS_LIMIT equ 0x0000480A
+GUEST_LDTR_LIMIT equ 0x0000480C
+GUEST_TR_LIMIT equ 0x0000480E
+GUEST_GDTR_LIMIT equ 0x00004810
+GUEST_IDTR_LIMIT equ 0x00004812
+GUEST_ES_ACCESS equ 0x00004814
+GUEST_CS_ACCESS equ 0x00004816
+GUEST_SS_ACCESS equ 0x00004818
+GUEST_DS_ACCESS equ 0x0000481A
+GUEST_FS_ACCESS equ 0x0000481C
+GUEST_GS_ACCESS equ 0x0000481E
+GUEST_LDTR_ACCESS equ 0x00004820
+GUEST_TR_ACCESS equ 0x00004822
+GUEST_INT_STATE equ 0x00004824
+GUEST_ACTIVITY_STATE equ 0x00004826
+GUEST_SMBASE equ 0x00004828
+GUEST_IA32_SYSENTER_CS equ 0x0000482A
+HOST_IA32_SYSENTER_CS equ 0x00004C00
+CR0_GUEST_HOST_MASK equ 0x00006000
+CR4_GUEST_HOST_MASK equ 0x00006002
+CR0_READ_SHADOW equ 0x00006004
+CR4_READ_SHADOW equ 0x00006006
+CR3_TARGET_VALUE_0 equ 0x00006008
+CR3_TARGET_VALUE_1 equ 0x0000600A
+CR3_TARGET_VALUE_2 equ 0x0000600C
+CR3_TARGET_VALUE_3 equ 0x0000600E
+EXIT_QUALIFICATION equ 0x00006400
+IO_RCX equ 0x00006402
+IO_RSI equ 0x00006404
+IO_RDI equ 0x00006406
+IO_RIP equ 0x00006408
+GUEST_LINEAR_ADDR equ 0x0000640A
+GUEST_CR0 equ 0x00006800
+GUEST_CR3 equ 0x00006802
+GUEST_CR4 equ 0x00006804
+GUEST_ES_BASE equ 0x00006806
+GUEST_CS_BASE equ 0x00006808
+GUEST_SS_BASE equ 0x0000680A
+GUEST_DS_BASE equ 0x0000680C
+GUEST_FS_BASE equ 0x0000680E
+GUEST_GS_BASE equ 0x00006810
+GUEST_LDTR_BASE equ 0x00006812
+GUEST_TR_BASE equ 0x00006814
+GUEST_GDTR_BASE equ 0x00006816
+GUEST_IDTR_BASE equ 0x00006818
+GUEST_DR7 equ 0x0000681A
+GUEST_RSP equ 0x0000681C
+GUEST_RIP equ 0x0000681E
+GUEST_RFLAGS equ 0x00006820
+GUEST_PENDING_DEBUG_EXCS equ 0x00006822
+GUEST_IA32_SYSENTER_ESP equ 0x00006824
+GUEST_IA32_SYSENTER_EIP equ 0x00006826
+HOST_CR0 equ 0x00006C00
+HOST_CR3 equ 0x00006C02
+HOST_CR4 equ 0x00006C04
+HOST_FS_BASE equ 0x00006C06
+HOST_GS_BASE equ 0x00006C08
+HOST_TR_BASE equ 0x00006C0A
+HOST_GDTR_BASE equ 0x00006C0C
+HOST_IDTR_BASE equ 0x00006C0E
+HOST_IA32_SYSENTER_ESP equ 0x00006C10
+HOST_IA32_SYSENTER_EIP equ 0x00006C12
+HOST_RSP equ 0x00006C14
+HOST_RIP equ 0x00006C16
+
+%endif
+
--- /dev/null
+#include <palacios/vmcs_gen.h>
+
+
+
+
+void Set_VMCS_GUEST_ES_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_ES_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_ES_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_ES_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_ES_SELECTOR() { PrintTrace("VMCS_GUEST_ES_SELECTOR = %x\n", Get_VMCS_GUEST_ES_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_CS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_CS_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_CS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_CS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_CS_SELECTOR() { PrintTrace("VMCS_GUEST_CS_SELECTOR = %x\n", Get_VMCS_GUEST_CS_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_SS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_SS_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_SS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_SS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_SS_SELECTOR() { PrintTrace("VMCS_GUEST_SS_SELECTOR = %x\n", Get_VMCS_GUEST_SS_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_DS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_DS_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_DS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_DS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_DS_SELECTOR() { PrintTrace("VMCS_GUEST_DS_SELECTOR = %x\n", Get_VMCS_GUEST_DS_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_FS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_FS_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_FS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_FS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_FS_SELECTOR() { PrintTrace("VMCS_GUEST_FS_SELECTOR = %x\n", Get_VMCS_GUEST_FS_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_GS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_GS_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_GS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_GS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_GS_SELECTOR() { PrintTrace("VMCS_GUEST_GS_SELECTOR = %x\n", Get_VMCS_GUEST_GS_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_LDTR_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_LDTR_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_LDTR_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_LDTR_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_LDTR_SELECTOR() { PrintTrace("VMCS_GUEST_LDTR_SELECTOR = %x\n", Get_VMCS_GUEST_LDTR_SELECTOR()); }
+
+
+void Set_VMCS_GUEST_TR_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_GUEST_TR_SELECTOR,val); }
+uint_t Get_VMCS_GUEST_TR_SELECTOR() { uint_t rc; VMCS_READ(VMCS_GUEST_TR_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_GUEST_TR_SELECTOR() { PrintTrace("VMCS_GUEST_TR_SELECTOR = %x\n", Get_VMCS_GUEST_TR_SELECTOR()); }
+
+
+void Set_VMCS_HOST_ES_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_ES_SELECTOR,val); }
+uint_t Get_VMCS_HOST_ES_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_ES_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_ES_SELECTOR() { PrintTrace("VMCS_HOST_ES_SELECTOR = %x\n", Get_VMCS_HOST_ES_SELECTOR()); }
+
+
+void Set_VMCS_HOST_CS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_CS_SELECTOR,val); }
+uint_t Get_VMCS_HOST_CS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_CS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_CS_SELECTOR() { PrintTrace("VMCS_HOST_CS_SELECTOR = %x\n", Get_VMCS_HOST_CS_SELECTOR()); }
+
+
+void Set_VMCS_HOST_SS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_SS_SELECTOR,val); }
+uint_t Get_VMCS_HOST_SS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_SS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_SS_SELECTOR() { PrintTrace("VMCS_HOST_SS_SELECTOR = %x\n", Get_VMCS_HOST_SS_SELECTOR()); }
+
+
+void Set_VMCS_HOST_DS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_DS_SELECTOR,val); }
+uint_t Get_VMCS_HOST_DS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_DS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_DS_SELECTOR() { PrintTrace("VMCS_HOST_DS_SELECTOR = %x\n", Get_VMCS_HOST_DS_SELECTOR()); }
+
+
+void Set_VMCS_HOST_FS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_FS_SELECTOR,val); }
+uint_t Get_VMCS_HOST_FS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_FS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_FS_SELECTOR() { PrintTrace("VMCS_HOST_FS_SELECTOR = %x\n", Get_VMCS_HOST_FS_SELECTOR()); }
+
+
+void Set_VMCS_HOST_GS_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_GS_SELECTOR,val); }
+uint_t Get_VMCS_HOST_GS_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_GS_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_GS_SELECTOR() { PrintTrace("VMCS_HOST_GS_SELECTOR = %x\n", Get_VMCS_HOST_GS_SELECTOR()); }
+
+
+void Set_VMCS_HOST_TR_SELECTOR(uint_t val) { VMCS_WRITE(VMCS_HOST_TR_SELECTOR,val); }
+uint_t Get_VMCS_HOST_TR_SELECTOR() { uint_t rc; VMCS_READ(VMCS_HOST_TR_SELECTOR,&rc); return rc; }
+
+void PrintTrace_VMCS_HOST_TR_SELECTOR() { PrintTrace("VMCS_HOST_TR_SELECTOR = %x\n", Get_VMCS_HOST_TR_SELECTOR()); }
+
+
+void Set_IO_BITMAP_A_ADDR(uint_t val) { VMCS_WRITE(IO_BITMAP_A_ADDR,val); }
+uint_t Get_IO_BITMAP_A_ADDR() { uint_t rc; VMCS_READ(IO_BITMAP_A_ADDR,&rc); return rc; }
+
+void PrintTrace_IO_BITMAP_A_ADDR() { PrintTrace("IO_BITMAP_A_ADDR = %x\n", Get_IO_BITMAP_A_ADDR()); }
+
+
+void Set_IO_BITMAP_A_ADDR_HIGH(uint_t val) { VMCS_WRITE(IO_BITMAP_A_ADDR_HIGH,val); }
+uint_t Get_IO_BITMAP_A_ADDR_HIGH() { uint_t rc; VMCS_READ(IO_BITMAP_A_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_IO_BITMAP_A_ADDR_HIGH() { PrintTrace("IO_BITMAP_A_ADDR_HIGH = %x\n", Get_IO_BITMAP_A_ADDR_HIGH()); }
+
+
+void Set_IO_BITMAP_B_ADDR(uint_t val) { VMCS_WRITE(IO_BITMAP_B_ADDR,val); }
+uint_t Get_IO_BITMAP_B_ADDR() { uint_t rc; VMCS_READ(IO_BITMAP_B_ADDR,&rc); return rc; }
+
+void PrintTrace_IO_BITMAP_B_ADDR() { PrintTrace("IO_BITMAP_B_ADDR = %x\n", Get_IO_BITMAP_B_ADDR()); }
+
+
+void Set_IO_BITMAP_B_ADDR_HIGH(uint_t val) { VMCS_WRITE(IO_BITMAP_B_ADDR_HIGH,val); }
+uint_t Get_IO_BITMAP_B_ADDR_HIGH() { uint_t rc; VMCS_READ(IO_BITMAP_B_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_IO_BITMAP_B_ADDR_HIGH() { PrintTrace("IO_BITMAP_B_ADDR_HIGH = %x\n", Get_IO_BITMAP_B_ADDR_HIGH()); }
+
+
+void Set_MSR_BITMAPS(uint_t val) { VMCS_WRITE(MSR_BITMAPS,val); }
+uint_t Get_MSR_BITMAPS() { uint_t rc; VMCS_READ(MSR_BITMAPS,&rc); return rc; }
+
+void PrintTrace_MSR_BITMAPS() { PrintTrace("MSR_BITMAPS = %x\n", Get_MSR_BITMAPS()); }
+
+
+void Set_MSR_BITMAPS_HIGH(uint_t val) { VMCS_WRITE(MSR_BITMAPS_HIGH,val); }
+uint_t Get_MSR_BITMAPS_HIGH() { uint_t rc; VMCS_READ(MSR_BITMAPS_HIGH,&rc); return rc; }
+
+void PrintTrace_MSR_BITMAPS_HIGH() { PrintTrace("MSR_BITMAPS_HIGH = %x\n", Get_MSR_BITMAPS_HIGH()); }
+
+
+void Set_VM_EXIT_MSR_STORE_ADDR(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_STORE_ADDR,val); }
+uint_t Get_VM_EXIT_MSR_STORE_ADDR() { uint_t rc; VMCS_READ(VM_EXIT_MSR_STORE_ADDR,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_STORE_ADDR() { PrintTrace("VM_EXIT_MSR_STORE_ADDR = %x\n", Get_VM_EXIT_MSR_STORE_ADDR()); }
+
+
+void Set_VM_EXIT_MSR_STORE_ADDR_HIGH(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_STORE_ADDR_HIGH,val); }
+uint_t Get_VM_EXIT_MSR_STORE_ADDR_HIGH() { uint_t rc; VMCS_READ(VM_EXIT_MSR_STORE_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_STORE_ADDR_HIGH() { PrintTrace("VM_EXIT_MSR_STORE_ADDR_HIGH = %x\n", Get_VM_EXIT_MSR_STORE_ADDR_HIGH()); }
+
+
+void Set_VM_EXIT_MSR_LOAD_ADDR(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_LOAD_ADDR,val); }
+uint_t Get_VM_EXIT_MSR_LOAD_ADDR() { uint_t rc; VMCS_READ(VM_EXIT_MSR_LOAD_ADDR,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_LOAD_ADDR() { PrintTrace("VM_EXIT_MSR_LOAD_ADDR = %x\n", Get_VM_EXIT_MSR_LOAD_ADDR()); }
+
+
+void Set_VM_EXIT_MSR_LOAD_ADDR_HIGH(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_LOAD_ADDR_HIGH,val); }
+uint_t Get_VM_EXIT_MSR_LOAD_ADDR_HIGH() { uint_t rc; VMCS_READ(VM_EXIT_MSR_LOAD_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_LOAD_ADDR_HIGH() { PrintTrace("VM_EXIT_MSR_LOAD_ADDR_HIGH = %x\n", Get_VM_EXIT_MSR_LOAD_ADDR_HIGH()); }
+
+
+void Set_VM_ENTRY_MSR_LOAD_ADDR(uint_t val) { VMCS_WRITE(VM_ENTRY_MSR_LOAD_ADDR,val); }
+uint_t Get_VM_ENTRY_MSR_LOAD_ADDR() { uint_t rc; VMCS_READ(VM_ENTRY_MSR_LOAD_ADDR,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_MSR_LOAD_ADDR() { PrintTrace("VM_ENTRY_MSR_LOAD_ADDR = %x\n", Get_VM_ENTRY_MSR_LOAD_ADDR()); }
+
+
+void Set_VM_ENTRY_MSR_LOAD_ADDR_HIGH(uint_t val) { VMCS_WRITE(VM_ENTRY_MSR_LOAD_ADDR_HIGH,val); }
+uint_t Get_VM_ENTRY_MSR_LOAD_ADDR_HIGH() { uint_t rc; VMCS_READ(VM_ENTRY_MSR_LOAD_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_MSR_LOAD_ADDR_HIGH() { PrintTrace("VM_ENTRY_MSR_LOAD_ADDR_HIGH = %x\n", Get_VM_ENTRY_MSR_LOAD_ADDR_HIGH()); }
+
+
+void Set_VMCS_EXEC_PTR(uint_t val) { VMCS_WRITE(VMCS_EXEC_PTR,val); }
+uint_t Get_VMCS_EXEC_PTR() { uint_t rc; VMCS_READ(VMCS_EXEC_PTR,&rc); return rc; }
+
+void PrintTrace_VMCS_EXEC_PTR() { PrintTrace("VMCS_EXEC_PTR = %x\n", Get_VMCS_EXEC_PTR()); }
+
+
+void Set_VMCS_EXEC_PTR_HIGH(uint_t val) { VMCS_WRITE(VMCS_EXEC_PTR_HIGH,val); }
+uint_t Get_VMCS_EXEC_PTR_HIGH() { uint_t rc; VMCS_READ(VMCS_EXEC_PTR_HIGH,&rc); return rc; }
+
+void PrintTrace_VMCS_EXEC_PTR_HIGH() { PrintTrace("VMCS_EXEC_PTR_HIGH = %x\n", Get_VMCS_EXEC_PTR_HIGH()); }
+
+
+void Set_TSC_OFFSET(uint_t val) { VMCS_WRITE(TSC_OFFSET,val); }
+uint_t Get_TSC_OFFSET() { uint_t rc; VMCS_READ(TSC_OFFSET,&rc); return rc; }
+
+void PrintTrace_TSC_OFFSET() { PrintTrace("TSC_OFFSET = %x\n", Get_TSC_OFFSET()); }
+
+
+void Set_TSC_OFFSET_HIGH(uint_t val) { VMCS_WRITE(TSC_OFFSET_HIGH,val); }
+uint_t Get_TSC_OFFSET_HIGH() { uint_t rc; VMCS_READ(TSC_OFFSET_HIGH,&rc); return rc; }
+
+void PrintTrace_TSC_OFFSET_HIGH() { PrintTrace("TSC_OFFSET_HIGH = %x\n", Get_TSC_OFFSET_HIGH()); }
+
+
+void Set_VIRT_APIC_PAGE_ADDR(uint_t val) { VMCS_WRITE(VIRT_APIC_PAGE_ADDR,val); }
+uint_t Get_VIRT_APIC_PAGE_ADDR() { uint_t rc; VMCS_READ(VIRT_APIC_PAGE_ADDR,&rc); return rc; }
+
+void PrintTrace_VIRT_APIC_PAGE_ADDR() { PrintTrace("VIRT_APIC_PAGE_ADDR = %x\n", Get_VIRT_APIC_PAGE_ADDR()); }
+
+
+void Set_VIRT_APIC_PAGE_ADDR_HIGH(uint_t val) { VMCS_WRITE(VIRT_APIC_PAGE_ADDR_HIGH,val); }
+uint_t Get_VIRT_APIC_PAGE_ADDR_HIGH() { uint_t rc; VMCS_READ(VIRT_APIC_PAGE_ADDR_HIGH,&rc); return rc; }
+
+void PrintTrace_VIRT_APIC_PAGE_ADDR_HIGH() { PrintTrace("VIRT_APIC_PAGE_ADDR_HIGH = %x\n", Get_VIRT_APIC_PAGE_ADDR_HIGH()); }
+
+
+void Set_VMCS_LINK_PTR(uint_t val) { VMCS_WRITE(VMCS_LINK_PTR,val); }
+uint_t Get_VMCS_LINK_PTR() { uint_t rc; VMCS_READ(VMCS_LINK_PTR,&rc); return rc; }
+
+void PrintTrace_VMCS_LINK_PTR() { PrintTrace("VMCS_LINK_PTR = %x\n", Get_VMCS_LINK_PTR()); }
+
+
+void Set_VMCS_LINK_PTR_HIGH(uint_t val) { VMCS_WRITE(VMCS_LINK_PTR_HIGH,val); }
+uint_t Get_VMCS_LINK_PTR_HIGH() { uint_t rc; VMCS_READ(VMCS_LINK_PTR_HIGH,&rc); return rc; }
+
+void PrintTrace_VMCS_LINK_PTR_HIGH() { PrintTrace("VMCS_LINK_PTR_HIGH = %x\n", Get_VMCS_LINK_PTR_HIGH()); }
+
+
+void Set_GUEST_IA32_DEBUGCTL(uint_t val) { VMCS_WRITE(GUEST_IA32_DEBUGCTL,val); }
+uint_t Get_GUEST_IA32_DEBUGCTL() { uint_t rc; VMCS_READ(GUEST_IA32_DEBUGCTL,&rc); return rc; }
+
+void PrintTrace_GUEST_IA32_DEBUGCTL() { PrintTrace("GUEST_IA32_DEBUGCTL = %x\n", Get_GUEST_IA32_DEBUGCTL()); }
+
+
+void Set_GUEST_IA32_DEBUGCTL_HIGH(uint_t val) { VMCS_WRITE(GUEST_IA32_DEBUGCTL_HIGH,val); }
+uint_t Get_GUEST_IA32_DEBUGCTL_HIGH() { uint_t rc; VMCS_READ(GUEST_IA32_DEBUGCTL_HIGH,&rc); return rc; }
+
+void PrintTrace_GUEST_IA32_DEBUGCTL_HIGH() { PrintTrace("GUEST_IA32_DEBUGCTL_HIGH = %x\n", Get_GUEST_IA32_DEBUGCTL_HIGH()); }
+
+
+void Set_PIN_VM_EXEC_CTRLS(uint_t val) { VMCS_WRITE(PIN_VM_EXEC_CTRLS,val); }
+uint_t Get_PIN_VM_EXEC_CTRLS() { uint_t rc; VMCS_READ(PIN_VM_EXEC_CTRLS,&rc); return rc; }
+
+void PrintTrace_PIN_VM_EXEC_CTRLS() { PrintTrace("PIN_VM_EXEC_CTRLS = %x\n", Get_PIN_VM_EXEC_CTRLS()); }
+
+
+void Set_PROC_VM_EXEC_CTRLS(uint_t val) { VMCS_WRITE(PROC_VM_EXEC_CTRLS,val); }
+uint_t Get_PROC_VM_EXEC_CTRLS() { uint_t rc; VMCS_READ(PROC_VM_EXEC_CTRLS,&rc); return rc; }
+
+void PrintTrace_PROC_VM_EXEC_CTRLS() { PrintTrace("PROC_VM_EXEC_CTRLS = %x\n", Get_PROC_VM_EXEC_CTRLS()); }
+
+
+void Set_EXCEPTION_BITMAP(uint_t val) { VMCS_WRITE(EXCEPTION_BITMAP,val); }
+uint_t Get_EXCEPTION_BITMAP() { uint_t rc; VMCS_READ(EXCEPTION_BITMAP,&rc); return rc; }
+
+void PrintTrace_EXCEPTION_BITMAP() { PrintTrace("EXCEPTION_BITMAP = %x\n", Get_EXCEPTION_BITMAP()); }
+
+
+void Set_PAGE_FAULT_ERROR_MASK(uint_t val) { VMCS_WRITE(PAGE_FAULT_ERROR_MASK,val); }
+uint_t Get_PAGE_FAULT_ERROR_MASK() { uint_t rc; VMCS_READ(PAGE_FAULT_ERROR_MASK,&rc); return rc; }
+
+void PrintTrace_PAGE_FAULT_ERROR_MASK() { PrintTrace("PAGE_FAULT_ERROR_MASK = %x\n", Get_PAGE_FAULT_ERROR_MASK()); }
+
+
+void Set_PAGE_FAULT_ERROR_MATCH(uint_t val) { VMCS_WRITE(PAGE_FAULT_ERROR_MATCH,val); }
+uint_t Get_PAGE_FAULT_ERROR_MATCH() { uint_t rc; VMCS_READ(PAGE_FAULT_ERROR_MATCH,&rc); return rc; }
+
+void PrintTrace_PAGE_FAULT_ERROR_MATCH() { PrintTrace("PAGE_FAULT_ERROR_MATCH = %x\n", Get_PAGE_FAULT_ERROR_MATCH()); }
+
+
+void Set_CR3_TARGET_COUNT(uint_t val) { VMCS_WRITE(CR3_TARGET_COUNT,val); }
+uint_t Get_CR3_TARGET_COUNT() { uint_t rc; VMCS_READ(CR3_TARGET_COUNT,&rc); return rc; }
+
+void PrintTrace_CR3_TARGET_COUNT() { PrintTrace("CR3_TARGET_COUNT = %x\n", Get_CR3_TARGET_COUNT()); }
+
+
+void Set_VM_EXIT_CTRLS(uint_t val) { VMCS_WRITE(VM_EXIT_CTRLS,val); }
+uint_t Get_VM_EXIT_CTRLS() { uint_t rc; VMCS_READ(VM_EXIT_CTRLS,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_CTRLS() { PrintTrace("VM_EXIT_CTRLS = %x\n", Get_VM_EXIT_CTRLS()); }
+
+
+void Set_VM_EXIT_MSR_STORE_COUNT(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_STORE_COUNT,val); }
+uint_t Get_VM_EXIT_MSR_STORE_COUNT() { uint_t rc; VMCS_READ(VM_EXIT_MSR_STORE_COUNT,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_STORE_COUNT() { PrintTrace("VM_EXIT_MSR_STORE_COUNT = %x\n", Get_VM_EXIT_MSR_STORE_COUNT()); }
+
+
+void Set_VM_EXIT_MSR_LOAD_COUNT(uint_t val) { VMCS_WRITE(VM_EXIT_MSR_LOAD_COUNT,val); }
+uint_t Get_VM_EXIT_MSR_LOAD_COUNT() { uint_t rc; VMCS_READ(VM_EXIT_MSR_LOAD_COUNT,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_MSR_LOAD_COUNT() { PrintTrace("VM_EXIT_MSR_LOAD_COUNT = %x\n", Get_VM_EXIT_MSR_LOAD_COUNT()); }
+
+
+void Set_VM_ENTRY_CTRLS(uint_t val) { VMCS_WRITE(VM_ENTRY_CTRLS,val); }
+uint_t Get_VM_ENTRY_CTRLS() { uint_t rc; VMCS_READ(VM_ENTRY_CTRLS,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_CTRLS() { PrintTrace("VM_ENTRY_CTRLS = %x\n", Get_VM_ENTRY_CTRLS()); }
+
+
+void Set_VM_ENTRY_MSR_LOAD_COUNT(uint_t val) { VMCS_WRITE(VM_ENTRY_MSR_LOAD_COUNT,val); }
+uint_t Get_VM_ENTRY_MSR_LOAD_COUNT() { uint_t rc; VMCS_READ(VM_ENTRY_MSR_LOAD_COUNT,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_MSR_LOAD_COUNT() { PrintTrace("VM_ENTRY_MSR_LOAD_COUNT = %x\n", Get_VM_ENTRY_MSR_LOAD_COUNT()); }
+
+
+void Set_VM_ENTRY_INT_INFO_FIELD(uint_t val) { VMCS_WRITE(VM_ENTRY_INT_INFO_FIELD,val); }
+uint_t Get_VM_ENTRY_INT_INFO_FIELD() { uint_t rc; VMCS_READ(VM_ENTRY_INT_INFO_FIELD,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_INT_INFO_FIELD() { PrintTrace("VM_ENTRY_INT_INFO_FIELD = %x\n", Get_VM_ENTRY_INT_INFO_FIELD()); }
+
+
+void Set_VM_ENTRY_EXCEPTION_ERROR(uint_t val) { VMCS_WRITE(VM_ENTRY_EXCEPTION_ERROR,val); }
+uint_t Get_VM_ENTRY_EXCEPTION_ERROR() { uint_t rc; VMCS_READ(VM_ENTRY_EXCEPTION_ERROR,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_EXCEPTION_ERROR() { PrintTrace("VM_ENTRY_EXCEPTION_ERROR = %x\n", Get_VM_ENTRY_EXCEPTION_ERROR()); }
+
+
+void Set_VM_ENTRY_INSTR_LENGTH(uint_t val) { VMCS_WRITE(VM_ENTRY_INSTR_LENGTH,val); }
+uint_t Get_VM_ENTRY_INSTR_LENGTH() { uint_t rc; VMCS_READ(VM_ENTRY_INSTR_LENGTH,&rc); return rc; }
+
+void PrintTrace_VM_ENTRY_INSTR_LENGTH() { PrintTrace("VM_ENTRY_INSTR_LENGTH = %x\n", Get_VM_ENTRY_INSTR_LENGTH()); }
+
+
+void Set_TPR_THRESHOLD(uint_t val) { VMCS_WRITE(TPR_THRESHOLD,val); }
+uint_t Get_TPR_THRESHOLD() { uint_t rc; VMCS_READ(TPR_THRESHOLD,&rc); return rc; }
+
+void PrintTrace_TPR_THRESHOLD() { PrintTrace("TPR_THRESHOLD = %x\n", Get_TPR_THRESHOLD()); }
+
+
+void Set_VM_INSTR_ERROR(uint_t val) { VMCS_WRITE(VM_INSTR_ERROR,val); }
+uint_t Get_VM_INSTR_ERROR() { uint_t rc; VMCS_READ(VM_INSTR_ERROR,&rc); return rc; }
+
+void PrintTrace_VM_INSTR_ERROR() { PrintTrace("VM_INSTR_ERROR = %x\n", Get_VM_INSTR_ERROR()); }
+
+
+void Set_EXIT_REASON(uint_t val) { VMCS_WRITE(EXIT_REASON,val); }
+uint_t Get_EXIT_REASON() { uint_t rc; VMCS_READ(EXIT_REASON,&rc); return rc; }
+
+void PrintTrace_EXIT_REASON() { PrintTrace("EXIT_REASON = %x\n", Get_EXIT_REASON()); }
+
+
+void Set_VM_EXIT_INT_INFO(uint_t val) { VMCS_WRITE(VM_EXIT_INT_INFO,val); }
+uint_t Get_VM_EXIT_INT_INFO() { uint_t rc; VMCS_READ(VM_EXIT_INT_INFO,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_INT_INFO() { PrintTrace("VM_EXIT_INT_INFO = %x\n", Get_VM_EXIT_INT_INFO()); }
+
+
+void Set_VM_EXIT_INT_ERROR(uint_t val) { VMCS_WRITE(VM_EXIT_INT_ERROR,val); }
+uint_t Get_VM_EXIT_INT_ERROR() { uint_t rc; VMCS_READ(VM_EXIT_INT_ERROR,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_INT_ERROR() { PrintTrace("VM_EXIT_INT_ERROR = %x\n", Get_VM_EXIT_INT_ERROR()); }
+
+
+void Set_IDT_VECTOR_INFO(uint_t val) { VMCS_WRITE(IDT_VECTOR_INFO,val); }
+uint_t Get_IDT_VECTOR_INFO() { uint_t rc; VMCS_READ(IDT_VECTOR_INFO,&rc); return rc; }
+
+void PrintTrace_IDT_VECTOR_INFO() { PrintTrace("IDT_VECTOR_INFO = %x\n", Get_IDT_VECTOR_INFO()); }
+
+
+void Set_IDT_VECTOR_ERROR(uint_t val) { VMCS_WRITE(IDT_VECTOR_ERROR,val); }
+uint_t Get_IDT_VECTOR_ERROR() { uint_t rc; VMCS_READ(IDT_VECTOR_ERROR,&rc); return rc; }
+
+void PrintTrace_IDT_VECTOR_ERROR() { PrintTrace("IDT_VECTOR_ERROR = %x\n", Get_IDT_VECTOR_ERROR()); }
+
+
+void Set_VM_EXIT_INSTR_LENGTH(uint_t val) { VMCS_WRITE(VM_EXIT_INSTR_LENGTH,val); }
+uint_t Get_VM_EXIT_INSTR_LENGTH() { uint_t rc; VMCS_READ(VM_EXIT_INSTR_LENGTH,&rc); return rc; }
+
+void PrintTrace_VM_EXIT_INSTR_LENGTH() { PrintTrace("VM_EXIT_INSTR_LENGTH = %x\n", Get_VM_EXIT_INSTR_LENGTH()); }
+
+
+void Set_VMX_INSTR_INFO(uint_t val) { VMCS_WRITE(VMX_INSTR_INFO,val); }
+uint_t Get_VMX_INSTR_INFO() { uint_t rc; VMCS_READ(VMX_INSTR_INFO,&rc); return rc; }
+
+void PrintTrace_VMX_INSTR_INFO() { PrintTrace("VMX_INSTR_INFO = %x\n", Get_VMX_INSTR_INFO()); }
+
+
+void Set_GUEST_ES_LIMIT(uint_t val) { VMCS_WRITE(GUEST_ES_LIMIT,val); }
+uint_t Get_GUEST_ES_LIMIT() { uint_t rc; VMCS_READ(GUEST_ES_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_ES_LIMIT() { PrintTrace("GUEST_ES_LIMIT = %x\n", Get_GUEST_ES_LIMIT()); }
+
+
+void Set_GUEST_CS_LIMIT(uint_t val) { VMCS_WRITE(GUEST_CS_LIMIT,val); }
+uint_t Get_GUEST_CS_LIMIT() { uint_t rc; VMCS_READ(GUEST_CS_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_CS_LIMIT() { PrintTrace("GUEST_CS_LIMIT = %x\n", Get_GUEST_CS_LIMIT()); }
+
+
+void Set_GUEST_SS_LIMIT(uint_t val) { VMCS_WRITE(GUEST_SS_LIMIT,val); }
+uint_t Get_GUEST_SS_LIMIT() { uint_t rc; VMCS_READ(GUEST_SS_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_SS_LIMIT() { PrintTrace("GUEST_SS_LIMIT = %x\n", Get_GUEST_SS_LIMIT()); }
+
+
+void Set_GUEST_DS_LIMIT(uint_t val) { VMCS_WRITE(GUEST_DS_LIMIT,val); }
+uint_t Get_GUEST_DS_LIMIT() { uint_t rc; VMCS_READ(GUEST_DS_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_DS_LIMIT() { PrintTrace("GUEST_DS_LIMIT = %x\n", Get_GUEST_DS_LIMIT()); }
+
+
+void Set_GUEST_FS_LIMIT(uint_t val) { VMCS_WRITE(GUEST_FS_LIMIT,val); }
+uint_t Get_GUEST_FS_LIMIT() { uint_t rc; VMCS_READ(GUEST_FS_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_FS_LIMIT() { PrintTrace("GUEST_FS_LIMIT = %x\n", Get_GUEST_FS_LIMIT()); }
+
+
+void Set_GUEST_GS_LIMIT(uint_t val) { VMCS_WRITE(GUEST_GS_LIMIT,val); }
+uint_t Get_GUEST_GS_LIMIT() { uint_t rc; VMCS_READ(GUEST_GS_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_GS_LIMIT() { PrintTrace("GUEST_GS_LIMIT = %x\n", Get_GUEST_GS_LIMIT()); }
+
+
+void Set_GUEST_LDTR_LIMIT(uint_t val) { VMCS_WRITE(GUEST_LDTR_LIMIT,val); }
+uint_t Get_GUEST_LDTR_LIMIT() { uint_t rc; VMCS_READ(GUEST_LDTR_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_LDTR_LIMIT() { PrintTrace("GUEST_LDTR_LIMIT = %x\n", Get_GUEST_LDTR_LIMIT()); }
+
+
+void Set_GUEST_TR_LIMIT(uint_t val) { VMCS_WRITE(GUEST_TR_LIMIT,val); }
+uint_t Get_GUEST_TR_LIMIT() { uint_t rc; VMCS_READ(GUEST_TR_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_TR_LIMIT() { PrintTrace("GUEST_TR_LIMIT = %x\n", Get_GUEST_TR_LIMIT()); }
+
+
+void Set_GUEST_GDTR_LIMIT(uint_t val) { VMCS_WRITE(GUEST_GDTR_LIMIT,val); }
+uint_t Get_GUEST_GDTR_LIMIT() { uint_t rc; VMCS_READ(GUEST_GDTR_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_GDTR_LIMIT() { PrintTrace("GUEST_GDTR_LIMIT = %x\n", Get_GUEST_GDTR_LIMIT()); }
+
+
+void Set_GUEST_IDTR_LIMIT(uint_t val) { VMCS_WRITE(GUEST_IDTR_LIMIT,val); }
+uint_t Get_GUEST_IDTR_LIMIT() { uint_t rc; VMCS_READ(GUEST_IDTR_LIMIT,&rc); return rc; }
+
+void PrintTrace_GUEST_IDTR_LIMIT() { PrintTrace("GUEST_IDTR_LIMIT = %x\n", Get_GUEST_IDTR_LIMIT()); }
+
+
+void Set_GUEST_ES_ACCESS(uint_t val) { VMCS_WRITE(GUEST_ES_ACCESS,val); }
+uint_t Get_GUEST_ES_ACCESS() { uint_t rc; VMCS_READ(GUEST_ES_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_ES_ACCESS() { PrintTrace("GUEST_ES_ACCESS = %x\n", Get_GUEST_ES_ACCESS()); }
+
+
+void Set_GUEST_CS_ACCESS(uint_t val) { VMCS_WRITE(GUEST_CS_ACCESS,val); }
+uint_t Get_GUEST_CS_ACCESS() { uint_t rc; VMCS_READ(GUEST_CS_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_CS_ACCESS() { PrintTrace("GUEST_CS_ACCESS = %x\n", Get_GUEST_CS_ACCESS()); }
+
+
+void Set_GUEST_SS_ACCESS(uint_t val) { VMCS_WRITE(GUEST_SS_ACCESS,val); }
+uint_t Get_GUEST_SS_ACCESS() { uint_t rc; VMCS_READ(GUEST_SS_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_SS_ACCESS() { PrintTrace("GUEST_SS_ACCESS = %x\n", Get_GUEST_SS_ACCESS()); }
+
+
+void Set_GUEST_DS_ACCESS(uint_t val) { VMCS_WRITE(GUEST_DS_ACCESS,val); }
+uint_t Get_GUEST_DS_ACCESS() { uint_t rc; VMCS_READ(GUEST_DS_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_DS_ACCESS() { PrintTrace("GUEST_DS_ACCESS = %x\n", Get_GUEST_DS_ACCESS()); }
+
+
+void Set_GUEST_FS_ACCESS(uint_t val) { VMCS_WRITE(GUEST_FS_ACCESS,val); }
+uint_t Get_GUEST_FS_ACCESS() { uint_t rc; VMCS_READ(GUEST_FS_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_FS_ACCESS() { PrintTrace("GUEST_FS_ACCESS = %x\n", Get_GUEST_FS_ACCESS()); }
+
+
+void Set_GUEST_GS_ACCESS(uint_t val) { VMCS_WRITE(GUEST_GS_ACCESS,val); }
+uint_t Get_GUEST_GS_ACCESS() { uint_t rc; VMCS_READ(GUEST_GS_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_GS_ACCESS() { PrintTrace("GUEST_GS_ACCESS = %x\n", Get_GUEST_GS_ACCESS()); }
+
+
+void Set_GUEST_LDTR_ACCESS(uint_t val) { VMCS_WRITE(GUEST_LDTR_ACCESS,val); }
+uint_t Get_GUEST_LDTR_ACCESS() { uint_t rc; VMCS_READ(GUEST_LDTR_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_LDTR_ACCESS() { PrintTrace("GUEST_LDTR_ACCESS = %x\n", Get_GUEST_LDTR_ACCESS()); }
+
+
+void Set_GUEST_TR_ACCESS(uint_t val) { VMCS_WRITE(GUEST_TR_ACCESS,val); }
+uint_t Get_GUEST_TR_ACCESS() { uint_t rc; VMCS_READ(GUEST_TR_ACCESS,&rc); return rc; }
+
+void PrintTrace_GUEST_TR_ACCESS() { PrintTrace("GUEST_TR_ACCESS = %x\n", Get_GUEST_TR_ACCESS()); }
+
+
+void Set_GUEST_INT_STATE(uint_t val) { VMCS_WRITE(GUEST_INT_STATE,val); }
+uint_t Get_GUEST_INT_STATE() { uint_t rc; VMCS_READ(GUEST_INT_STATE,&rc); return rc; }
+
+void PrintTrace_GUEST_INT_STATE() { PrintTrace("GUEST_INT_STATE = %x\n", Get_GUEST_INT_STATE()); }
+
+
+void Set_GUEST_ACTIVITY_STATE(uint_t val) { VMCS_WRITE(GUEST_ACTIVITY_STATE,val); }
+uint_t Get_GUEST_ACTIVITY_STATE() { uint_t rc; VMCS_READ(GUEST_ACTIVITY_STATE,&rc); return rc; }
+
+void PrintTrace_GUEST_ACTIVITY_STATE() { PrintTrace("GUEST_ACTIVITY_STATE = %x\n", Get_GUEST_ACTIVITY_STATE()); }
+
+
+void Set_GUEST_SMBASE(uint_t val) { VMCS_WRITE(GUEST_SMBASE,val); }
+uint_t Get_GUEST_SMBASE() { uint_t rc; VMCS_READ(GUEST_SMBASE,&rc); return rc; }
+
+void PrintTrace_GUEST_SMBASE() { PrintTrace("GUEST_SMBASE = %x\n", Get_GUEST_SMBASE()); }
+
+
+void Set_GUEST_IA32_SYSENTER_CS(uint_t val) { VMCS_WRITE(GUEST_IA32_SYSENTER_CS,val); }
+uint_t Get_GUEST_IA32_SYSENTER_CS() { uint_t rc; VMCS_READ(GUEST_IA32_SYSENTER_CS,&rc); return rc; }
+
+void PrintTrace_GUEST_IA32_SYSENTER_CS() { PrintTrace("GUEST_IA32_SYSENTER_CS = %x\n", Get_GUEST_IA32_SYSENTER_CS()); }
+
+
+void Set_HOST_IA32_SYSENTER_CS(uint_t val) { VMCS_WRITE(HOST_IA32_SYSENTER_CS,val); }
+uint_t Get_HOST_IA32_SYSENTER_CS() { uint_t rc; VMCS_READ(HOST_IA32_SYSENTER_CS,&rc); return rc; }
+
+void PrintTrace_HOST_IA32_SYSENTER_CS() { PrintTrace("HOST_IA32_SYSENTER_CS = %x\n", Get_HOST_IA32_SYSENTER_CS()); }
+
+
+void Set_CR0_GUEST_HOST_MASK(uint_t val) { VMCS_WRITE(CR0_GUEST_HOST_MASK,val); }
+uint_t Get_CR0_GUEST_HOST_MASK() { uint_t rc; VMCS_READ(CR0_GUEST_HOST_MASK,&rc); return rc; }
+
+void PrintTrace_CR0_GUEST_HOST_MASK() { PrintTrace("CR0_GUEST_HOST_MASK = %x\n", Get_CR0_GUEST_HOST_MASK()); }
+
+
+void Set_CR4_GUEST_HOST_MASK(uint_t val) { VMCS_WRITE(CR4_GUEST_HOST_MASK,val); }
+uint_t Get_CR4_GUEST_HOST_MASK() { uint_t rc; VMCS_READ(CR4_GUEST_HOST_MASK,&rc); return rc; }
+
+void PrintTrace_CR4_GUEST_HOST_MASK() { PrintTrace("CR4_GUEST_HOST_MASK = %x\n", Get_CR4_GUEST_HOST_MASK()); }
+
+
+void Set_CR0_READ_SHADOW(uint_t val) { VMCS_WRITE(CR0_READ_SHADOW,val); }
+uint_t Get_CR0_READ_SHADOW() { uint_t rc; VMCS_READ(CR0_READ_SHADOW,&rc); return rc; }
+
+void PrintTrace_CR0_READ_SHADOW() { PrintTrace("CR0_READ_SHADOW = %x\n", Get_CR0_READ_SHADOW()); }
+
+
+void Set_CR4_READ_SHADOW(uint_t val) { VMCS_WRITE(CR4_READ_SHADOW,val); }
+uint_t Get_CR4_READ_SHADOW() { uint_t rc; VMCS_READ(CR4_READ_SHADOW,&rc); return rc; }
+
+void PrintTrace_CR4_READ_SHADOW() { PrintTrace("CR4_READ_SHADOW = %x\n", Get_CR4_READ_SHADOW()); }
+
+
+void Set_CR3_TARGET_VALUE_0(uint_t val) { VMCS_WRITE(CR3_TARGET_VALUE_0,val); }
+uint_t Get_CR3_TARGET_VALUE_0() { uint_t rc; VMCS_READ(CR3_TARGET_VALUE_0,&rc); return rc; }
+
+void PrintTrace_CR3_TARGET_VALUE_0() { PrintTrace("CR3_TARGET_VALUE_0 = %x\n", Get_CR3_TARGET_VALUE_0()); }
+
+
+void Set_CR3_TARGET_VALUE_1(uint_t val) { VMCS_WRITE(CR3_TARGET_VALUE_1,val); }
+uint_t Get_CR3_TARGET_VALUE_1() { uint_t rc; VMCS_READ(CR3_TARGET_VALUE_1,&rc); return rc; }
+
+void PrintTrace_CR3_TARGET_VALUE_1() { PrintTrace("CR3_TARGET_VALUE_1 = %x\n", Get_CR3_TARGET_VALUE_1()); }
+
+
+void Set_CR3_TARGET_VALUE_2(uint_t val) { VMCS_WRITE(CR3_TARGET_VALUE_2,val); }
+uint_t Get_CR3_TARGET_VALUE_2() { uint_t rc; VMCS_READ(CR3_TARGET_VALUE_2,&rc); return rc; }
+
+void PrintTrace_CR3_TARGET_VALUE_2() { PrintTrace("CR3_TARGET_VALUE_2 = %x\n", Get_CR3_TARGET_VALUE_2()); }
+
+
+void Set_CR3_TARGET_VALUE_3(uint_t val) { VMCS_WRITE(CR3_TARGET_VALUE_3,val); }
+uint_t Get_CR3_TARGET_VALUE_3() { uint_t rc; VMCS_READ(CR3_TARGET_VALUE_3,&rc); return rc; }
+
+void PrintTrace_CR3_TARGET_VALUE_3() { PrintTrace("CR3_TARGET_VALUE_3 = %x\n", Get_CR3_TARGET_VALUE_3()); }
+
+
+void Set_EXIT_QUALIFICATION(uint_t val) { VMCS_WRITE(EXIT_QUALIFICATION,val); }
+uint_t Get_EXIT_QUALIFICATION() { uint_t rc; VMCS_READ(EXIT_QUALIFICATION,&rc); return rc; }
+
+void PrintTrace_EXIT_QUALIFICATION() { PrintTrace("EXIT_QUALIFICATION = %x\n", Get_EXIT_QUALIFICATION()); }
+
+
+void Set_IO_RCX(uint_t val) { VMCS_WRITE(IO_RCX,val); }
+uint_t Get_IO_RCX() { uint_t rc; VMCS_READ(IO_RCX,&rc); return rc; }
+
+void PrintTrace_IO_RCX() { PrintTrace("IO_RCX = %x\n", Get_IO_RCX()); }
+
+
+void Set_IO_RSI(uint_t val) { VMCS_WRITE(IO_RSI,val); }
+uint_t Get_IO_RSI() { uint_t rc; VMCS_READ(IO_RSI,&rc); return rc; }
+
+void PrintTrace_IO_RSI() { PrintTrace("IO_RSI = %x\n", Get_IO_RSI()); }
+
+
+void Set_IO_RDI(uint_t val) { VMCS_WRITE(IO_RDI,val); }
+uint_t Get_IO_RDI() { uint_t rc; VMCS_READ(IO_RDI,&rc); return rc; }
+
+void PrintTrace_IO_RDI() { PrintTrace("IO_RDI = %x\n", Get_IO_RDI()); }
+
+
+void Set_IO_RIP(uint_t val) { VMCS_WRITE(IO_RIP,val); }
+uint_t Get_IO_RIP() { uint_t rc; VMCS_READ(IO_RIP,&rc); return rc; }
+
+void PrintTrace_IO_RIP() { PrintTrace("IO_RIP = %x\n", Get_IO_RIP()); }
+
+
+void Set_GUEST_LINEAR_ADDR(uint_t val) { VMCS_WRITE(GUEST_LINEAR_ADDR,val); }
+uint_t Get_GUEST_LINEAR_ADDR() { uint_t rc; VMCS_READ(GUEST_LINEAR_ADDR,&rc); return rc; }
+
+void PrintTrace_GUEST_LINEAR_ADDR() { PrintTrace("GUEST_LINEAR_ADDR = %x\n", Get_GUEST_LINEAR_ADDR()); }
+
+
+void Set_GUEST_CR0(uint_t val) { VMCS_WRITE(GUEST_CR0,val); }
+uint_t Get_GUEST_CR0() { uint_t rc; VMCS_READ(GUEST_CR0,&rc); return rc; }
+
+void PrintTrace_GUEST_CR0() { PrintTrace("GUEST_CR0 = %x\n", Get_GUEST_CR0()); }
+
+
+void Set_GUEST_CR3(uint_t val) { VMCS_WRITE(GUEST_CR3,val); }
+uint_t Get_GUEST_CR3() { uint_t rc; VMCS_READ(GUEST_CR3,&rc); return rc; }
+
+void PrintTrace_GUEST_CR3() { PrintTrace("GUEST_CR3 = %x\n", Get_GUEST_CR3()); }
+
+
+void Set_GUEST_CR4(uint_t val) { VMCS_WRITE(GUEST_CR4,val); }
+uint_t Get_GUEST_CR4() { uint_t rc; VMCS_READ(GUEST_CR4,&rc); return rc; }
+
+void PrintTrace_GUEST_CR4() { PrintTrace("GUEST_CR4 = %x\n", Get_GUEST_CR4()); }
+
+
+void Set_GUEST_ES_BASE(uint_t val) { VMCS_WRITE(GUEST_ES_BASE,val); }
+uint_t Get_GUEST_ES_BASE() { uint_t rc; VMCS_READ(GUEST_ES_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_ES_BASE() { PrintTrace("GUEST_ES_BASE = %x\n", Get_GUEST_ES_BASE()); }
+
+
+void Set_GUEST_CS_BASE(uint_t val) { VMCS_WRITE(GUEST_CS_BASE,val); }
+uint_t Get_GUEST_CS_BASE() { uint_t rc; VMCS_READ(GUEST_CS_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_CS_BASE() { PrintTrace("GUEST_CS_BASE = %x\n", Get_GUEST_CS_BASE()); }
+
+
+void Set_GUEST_SS_BASE(uint_t val) { VMCS_WRITE(GUEST_SS_BASE,val); }
+uint_t Get_GUEST_SS_BASE() { uint_t rc; VMCS_READ(GUEST_SS_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_SS_BASE() { PrintTrace("GUEST_SS_BASE = %x\n", Get_GUEST_SS_BASE()); }
+
+
+void Set_GUEST_DS_BASE(uint_t val) { VMCS_WRITE(GUEST_DS_BASE,val); }
+uint_t Get_GUEST_DS_BASE() { uint_t rc; VMCS_READ(GUEST_DS_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_DS_BASE() { PrintTrace("GUEST_DS_BASE = %x\n", Get_GUEST_DS_BASE()); }
+
+
+void Set_GUEST_FS_BASE(uint_t val) { VMCS_WRITE(GUEST_FS_BASE,val); }
+uint_t Get_GUEST_FS_BASE() { uint_t rc; VMCS_READ(GUEST_FS_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_FS_BASE() { PrintTrace("GUEST_FS_BASE = %x\n", Get_GUEST_FS_BASE()); }
+
+
+void Set_GUEST_GS_BASE(uint_t val) { VMCS_WRITE(GUEST_GS_BASE,val); }
+uint_t Get_GUEST_GS_BASE() { uint_t rc; VMCS_READ(GUEST_GS_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_GS_BASE() { PrintTrace("GUEST_GS_BASE = %x\n", Get_GUEST_GS_BASE()); }
+
+
+void Set_GUEST_LDTR_BASE(uint_t val) { VMCS_WRITE(GUEST_LDTR_BASE,val); }
+uint_t Get_GUEST_LDTR_BASE() { uint_t rc; VMCS_READ(GUEST_LDTR_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_LDTR_BASE() { PrintTrace("GUEST_LDTR_BASE = %x\n", Get_GUEST_LDTR_BASE()); }
+
+
+void Set_GUEST_TR_BASE(uint_t val) { VMCS_WRITE(GUEST_TR_BASE,val); }
+uint_t Get_GUEST_TR_BASE() { uint_t rc; VMCS_READ(GUEST_TR_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_TR_BASE() { PrintTrace("GUEST_TR_BASE = %x\n", Get_GUEST_TR_BASE()); }
+
+
+void Set_GUEST_GDTR_BASE(uint_t val) { VMCS_WRITE(GUEST_GDTR_BASE,val); }
+uint_t Get_GUEST_GDTR_BASE() { uint_t rc; VMCS_READ(GUEST_GDTR_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_GDTR_BASE() { PrintTrace("GUEST_GDTR_BASE = %x\n", Get_GUEST_GDTR_BASE()); }
+
+
+void Set_GUEST_IDTR_BASE(uint_t val) { VMCS_WRITE(GUEST_IDTR_BASE,val); }
+uint_t Get_GUEST_IDTR_BASE() { uint_t rc; VMCS_READ(GUEST_IDTR_BASE,&rc); return rc; }
+
+void PrintTrace_GUEST_IDTR_BASE() { PrintTrace("GUEST_IDTR_BASE = %x\n", Get_GUEST_IDTR_BASE()); }
+
+
+void Set_GUEST_DR7(uint_t val) { VMCS_WRITE(GUEST_DR7,val); }
+uint_t Get_GUEST_DR7() { uint_t rc; VMCS_READ(GUEST_DR7,&rc); return rc; }
+
+void PrintTrace_GUEST_DR7() { PrintTrace("GUEST_DR7 = %x\n", Get_GUEST_DR7()); }
+
+
+void Set_GUEST_RSP(uint_t val) { VMCS_WRITE(GUEST_RSP,val); }
+uint_t Get_GUEST_RSP() { uint_t rc; VMCS_READ(GUEST_RSP,&rc); return rc; }
+
+void PrintTrace_GUEST_RSP() { PrintTrace("GUEST_RSP = %x\n", Get_GUEST_RSP()); }
+
+
+void Set_GUEST_RIP(uint_t val) { VMCS_WRITE(GUEST_RIP,val); }
+uint_t Get_GUEST_RIP() { uint_t rc; VMCS_READ(GUEST_RIP,&rc); return rc; }
+
+void PrintTrace_GUEST_RIP() { PrintTrace("GUEST_RIP = %x\n", Get_GUEST_RIP()); }
+
+
+void Set_GUEST_RFLAGS(uint_t val) { VMCS_WRITE(GUEST_RFLAGS,val); }
+uint_t Get_GUEST_RFLAGS() { uint_t rc; VMCS_READ(GUEST_RFLAGS,&rc); return rc; }
+
+void PrintTrace_GUEST_RFLAGS() { PrintTrace("GUEST_RFLAGS = %x\n", Get_GUEST_RFLAGS()); }
+
+
+void Set_GUEST_PENDING_DEBUG_EXCS(uint_t val) { VMCS_WRITE(GUEST_PENDING_DEBUG_EXCS,val); }
+uint_t Get_GUEST_PENDING_DEBUG_EXCS() { uint_t rc; VMCS_READ(GUEST_PENDING_DEBUG_EXCS,&rc); return rc; }
+
+void PrintTrace_GUEST_PENDING_DEBUG_EXCS() { PrintTrace("GUEST_PENDING_DEBUG_EXCS = %x\n", Get_GUEST_PENDING_DEBUG_EXCS()); }
+
+
+void Set_GUEST_IA32_SYSENTER_ESP(uint_t val) { VMCS_WRITE(GUEST_IA32_SYSENTER_ESP,val); }
+uint_t Get_GUEST_IA32_SYSENTER_ESP() { uint_t rc; VMCS_READ(GUEST_IA32_SYSENTER_ESP,&rc); return rc; }
+
+void PrintTrace_GUEST_IA32_SYSENTER_ESP() { PrintTrace("GUEST_IA32_SYSENTER_ESP = %x\n", Get_GUEST_IA32_SYSENTER_ESP()); }
+
+
+void Set_GUEST_IA32_SYSENTER_EIP(uint_t val) { VMCS_WRITE(GUEST_IA32_SYSENTER_EIP,val); }
+uint_t Get_GUEST_IA32_SYSENTER_EIP() { uint_t rc; VMCS_READ(GUEST_IA32_SYSENTER_EIP,&rc); return rc; }
+
+void PrintTrace_GUEST_IA32_SYSENTER_EIP() { PrintTrace("GUEST_IA32_SYSENTER_EIP = %x\n", Get_GUEST_IA32_SYSENTER_EIP()); }
+
+
+void Set_HOST_CR0(uint_t val) { VMCS_WRITE(HOST_CR0,val); }
+uint_t Get_HOST_CR0() { uint_t rc; VMCS_READ(HOST_CR0,&rc); return rc; }
+
+void PrintTrace_HOST_CR0() { PrintTrace("HOST_CR0 = %x\n", Get_HOST_CR0()); }
+
+
+void Set_HOST_CR3(uint_t val) { VMCS_WRITE(HOST_CR3,val); }
+uint_t Get_HOST_CR3() { uint_t rc; VMCS_READ(HOST_CR3,&rc); return rc; }
+
+void PrintTrace_HOST_CR3() { PrintTrace("HOST_CR3 = %x\n", Get_HOST_CR3()); }
+
+
+void Set_HOST_CR4(uint_t val) { VMCS_WRITE(HOST_CR4,val); }
+uint_t Get_HOST_CR4() { uint_t rc; VMCS_READ(HOST_CR4,&rc); return rc; }
+
+void PrintTrace_HOST_CR4() { PrintTrace("HOST_CR4 = %x\n", Get_HOST_CR4()); }
+
+
+void Set_HOST_FS_BASE(uint_t val) { VMCS_WRITE(HOST_FS_BASE,val); }
+uint_t Get_HOST_FS_BASE() { uint_t rc; VMCS_READ(HOST_FS_BASE,&rc); return rc; }
+
+void PrintTrace_HOST_FS_BASE() { PrintTrace("HOST_FS_BASE = %x\n", Get_HOST_FS_BASE()); }
+
+
+void Set_HOST_GS_BASE(uint_t val) { VMCS_WRITE(HOST_GS_BASE,val); }
+uint_t Get_HOST_GS_BASE() { uint_t rc; VMCS_READ(HOST_GS_BASE,&rc); return rc; }
+
+void PrintTrace_HOST_GS_BASE() { PrintTrace("HOST_GS_BASE = %x\n", Get_HOST_GS_BASE()); }
+
+
+void Set_HOST_TR_BASE(uint_t val) { VMCS_WRITE(HOST_TR_BASE,val); }
+uint_t Get_HOST_TR_BASE() { uint_t rc; VMCS_READ(HOST_TR_BASE,&rc); return rc; }
+
+void PrintTrace_HOST_TR_BASE() { PrintTrace("HOST_TR_BASE = %x\n", Get_HOST_TR_BASE()); }
+
+
+void Set_HOST_GDTR_BASE(uint_t val) { VMCS_WRITE(HOST_GDTR_BASE,val); }
+uint_t Get_HOST_GDTR_BASE() { uint_t rc; VMCS_READ(HOST_GDTR_BASE,&rc); return rc; }
+
+void PrintTrace_HOST_GDTR_BASE() { PrintTrace("HOST_GDTR_BASE = %x\n", Get_HOST_GDTR_BASE()); }
+
+
+void Set_HOST_IDTR_BASE(uint_t val) { VMCS_WRITE(HOST_IDTR_BASE,val); }
+uint_t Get_HOST_IDTR_BASE() { uint_t rc; VMCS_READ(HOST_IDTR_BASE,&rc); return rc; }
+
+void PrintTrace_HOST_IDTR_BASE() { PrintTrace("HOST_IDTR_BASE = %x\n", Get_HOST_IDTR_BASE()); }
+
+
+void Set_HOST_IA32_SYSENTER_ESP(uint_t val) { VMCS_WRITE(HOST_IA32_SYSENTER_ESP,val); }
+uint_t Get_HOST_IA32_SYSENTER_ESP() { uint_t rc; VMCS_READ(HOST_IA32_SYSENTER_ESP,&rc); return rc; }
+
+void PrintTrace_HOST_IA32_SYSENTER_ESP() { PrintTrace("HOST_IA32_SYSENTER_ESP = %x\n", Get_HOST_IA32_SYSENTER_ESP()); }
+
+
+void Set_HOST_IA32_SYSENTER_EIP(uint_t val) { VMCS_WRITE(HOST_IA32_SYSENTER_EIP,val); }
+uint_t Get_HOST_IA32_SYSENTER_EIP() { uint_t rc; VMCS_READ(HOST_IA32_SYSENTER_EIP,&rc); return rc; }
+
+void PrintTrace_HOST_IA32_SYSENTER_EIP() { PrintTrace("HOST_IA32_SYSENTER_EIP = %x\n", Get_HOST_IA32_SYSENTER_EIP()); }
+
+
+void Set_HOST_RSP(uint_t val) { VMCS_WRITE(HOST_RSP,val); }
+uint_t Get_HOST_RSP() { uint_t rc; VMCS_READ(HOST_RSP,&rc); return rc; }
+
+void PrintTrace_HOST_RSP() { PrintTrace("HOST_RSP = %x\n", Get_HOST_RSP()); }
+
+
+void Set_HOST_RIP(uint_t val) { VMCS_WRITE(HOST_RIP,val); }
+uint_t Get_HOST_RIP() { uint_t rc; VMCS_READ(HOST_RIP,&rc); return rc; }
+
+void PrintTrace_HOST_RIP() { PrintTrace("HOST_RIP = %x\n", Get_HOST_RIP()); }
+
+void PrintTrace_VMCS_ALL() {
+
+ PrintTrace("==>Guest State Area\n");
+ PrintTrace("==>==> Guest Register State\n");
+ PrintTrace_GUEST_CR0();
+ PrintTrace_GUEST_CR3();
+ PrintTrace_GUEST_CR4();
+ PrintTrace_GUEST_DR7();
+ PrintTrace_GUEST_RSP();
+ PrintTrace_GUEST_RIP();
+ PrintTrace_GUEST_RFLAGS();
+ PrintTrace_VMCS_GUEST_CS_SELECTOR();
+ PrintTrace_VMCS_GUEST_SS_SELECTOR();
+ PrintTrace_VMCS_GUEST_DS_SELECTOR();
+ PrintTrace_VMCS_GUEST_ES_SELECTOR();
+ PrintTrace_VMCS_GUEST_FS_SELECTOR();
+ PrintTrace_VMCS_GUEST_GS_SELECTOR();
+ PrintTrace_VMCS_GUEST_LDTR_SELECTOR();
+ PrintTrace_VMCS_GUEST_TR_SELECTOR();
+ PrintTrace_GUEST_CS_BASE();
+ PrintTrace_GUEST_SS_BASE();
+ PrintTrace_GUEST_DS_BASE();
+ PrintTrace_GUEST_ES_BASE();
+ PrintTrace_GUEST_FS_BASE();
+ PrintTrace_GUEST_GS_BASE();
+ PrintTrace_GUEST_LDTR_BASE();
+ PrintTrace_GUEST_TR_BASE();
+ PrintTrace_GUEST_CS_LIMIT();
+ PrintTrace_GUEST_SS_LIMIT();
+ PrintTrace_GUEST_DS_LIMIT();
+ PrintTrace_GUEST_ES_LIMIT();
+ PrintTrace_GUEST_FS_LIMIT();
+ PrintTrace_GUEST_GS_LIMIT();
+ PrintTrace_GUEST_LDTR_LIMIT();
+ PrintTrace_GUEST_TR_LIMIT();
+ PrintTrace_GUEST_ES_ACCESS();
+ PrintTrace_GUEST_CS_ACCESS();
+ PrintTrace_GUEST_SS_ACCESS();
+ PrintTrace_GUEST_DS_ACCESS();
+ PrintTrace_GUEST_FS_ACCESS();
+ PrintTrace_GUEST_GS_ACCESS();
+ PrintTrace_GUEST_LDTR_ACCESS();
+ PrintTrace_GUEST_TR_ACCESS();
+ PrintTrace_GUEST_GDTR_BASE();
+ PrintTrace_GUEST_IDTR_BASE();
+ PrintTrace_GUEST_GDTR_LIMIT();
+ PrintTrace_GUEST_IDTR_LIMIT();
+ PrintTrace_GUEST_IA32_DEBUGCTL();
+ PrintTrace_GUEST_IA32_DEBUGCTL_HIGH();
+ PrintTrace_GUEST_IA32_SYSENTER_CS();
+ PrintTrace_GUEST_IA32_SYSENTER_ESP();
+ PrintTrace_GUEST_IA32_SYSENTER_EIP();
+ PrintTrace_GUEST_SMBASE();
+
+ PrintTrace("==>==> Guest Non-Register State\n");
+ PrintTrace_GUEST_ACTIVITY_STATE();
+ PrintTrace_GUEST_INT_STATE();
+ PrintTrace_GUEST_PENDING_DEBUG_EXCS();
+ PrintTrace_VMCS_LINK_PTR();
+ PrintTrace_VMCS_LINK_PTR_HIGH();
+
+ PrintTrace("\n==> Host State Area\n");
+ PrintTrace_HOST_CR0();
+ PrintTrace_HOST_CR3();
+ PrintTrace_HOST_CR4();
+ PrintTrace_HOST_RSP();
+ PrintTrace_HOST_RIP();
+ PrintTrace_VMCS_HOST_CS_SELECTOR();
+ PrintTrace_VMCS_HOST_SS_SELECTOR();
+ PrintTrace_VMCS_HOST_DS_SELECTOR();
+ PrintTrace_VMCS_HOST_ES_SELECTOR();
+ PrintTrace_VMCS_HOST_FS_SELECTOR();
+ PrintTrace_VMCS_HOST_GS_SELECTOR();
+ PrintTrace_VMCS_HOST_TR_SELECTOR();
+ PrintTrace_HOST_FS_BASE();
+ PrintTrace_HOST_GS_BASE();
+ PrintTrace_HOST_TR_BASE();
+ PrintTrace_HOST_GDTR_BASE();
+ PrintTrace_HOST_IDTR_BASE();
+ PrintTrace_HOST_IA32_SYSENTER_CS();
+ PrintTrace_HOST_IA32_SYSENTER_ESP();
+ PrintTrace_HOST_IA32_SYSENTER_EIP();
+
+
+ PrintTrace("\n==> VM-Execution Controls:\n");
+ PrintTrace_PIN_VM_EXEC_CTRLS();
+ PrintTrace_PROC_VM_EXEC_CTRLS();
+ PrintTrace_EXCEPTION_BITMAP();
+ PrintTrace_PAGE_FAULT_ERROR_MASK();
+ PrintTrace_PAGE_FAULT_ERROR_MATCH();
+ PrintTrace_IO_BITMAP_A_ADDR();
+ PrintTrace_IO_BITMAP_A_ADDR_HIGH();
+ PrintTrace_IO_BITMAP_B_ADDR();
+ PrintTrace_IO_BITMAP_B_ADDR_HIGH();
+ PrintTrace_TSC_OFFSET();
+ PrintTrace_TSC_OFFSET_HIGH();
+ PrintTrace_CR0_GUEST_HOST_MASK();
+ PrintTrace_CR0_READ_SHADOW();
+ PrintTrace_CR4_GUEST_HOST_MASK();
+ PrintTrace_CR4_READ_SHADOW();
+ PrintTrace_CR3_TARGET_COUNT();
+ PrintTrace_CR3_TARGET_VALUE_0();
+ PrintTrace_CR3_TARGET_VALUE_1();
+ PrintTrace_CR3_TARGET_VALUE_2();
+ PrintTrace_CR3_TARGET_VALUE_3();
+ PrintTrace_VIRT_APIC_PAGE_ADDR();
+ PrintTrace_VIRT_APIC_PAGE_ADDR_HIGH();
+ PrintTrace_TPR_THRESHOLD();
+ PrintTrace_MSR_BITMAPS();
+ PrintTrace_MSR_BITMAPS_HIGH();
+ PrintTrace_VMCS_EXEC_PTR();
+ PrintTrace_VMCS_EXEC_PTR_HIGH();
+
+ PrintTrace("\n==> VM Exit Controls\n");
+ PrintTrace_VM_EXIT_CTRLS();
+ PrintTrace_VM_EXIT_MSR_STORE_COUNT();
+ PrintTrace_VM_EXIT_MSR_STORE_ADDR();
+ PrintTrace_VM_EXIT_MSR_STORE_ADDR_HIGH();
+ PrintTrace_VM_EXIT_MSR_LOAD_COUNT();
+ PrintTrace_VM_EXIT_MSR_LOAD_ADDR();
+ PrintTrace_VM_EXIT_MSR_LOAD_ADDR_HIGH();
+
+ PrintTrace("\n==> VM Entry Controls\n");
+ PrintTrace_VM_ENTRY_CTRLS();
+ PrintTrace_VM_ENTRY_MSR_LOAD_COUNT();
+ PrintTrace_VM_ENTRY_MSR_LOAD_ADDR();
+ PrintTrace_VM_ENTRY_MSR_LOAD_ADDR_HIGH();
+ PrintTrace_VM_ENTRY_INT_INFO_FIELD();
+ PrintTrace_VM_ENTRY_EXCEPTION_ERROR();
+ PrintTrace_VM_ENTRY_INSTR_LENGTH();
+
+ PrintTrace("\n==> VM Exit Info\n");
+ PrintTrace_EXIT_REASON();
+ PrintTrace_EXIT_QUALIFICATION();
+ PrintTrace_VM_EXIT_INT_INFO();
+ PrintTrace_VM_EXIT_INT_ERROR();
+ PrintTrace_IDT_VECTOR_INFO();
+ PrintTrace_IDT_VECTOR_ERROR();
+ PrintTrace_VM_EXIT_INSTR_LENGTH();
+ PrintTrace_GUEST_LINEAR_ADDR();
+ PrintTrace_VMX_INSTR_INFO();
+ PrintTrace_IO_RCX();
+ PrintTrace_IO_RSI();
+ PrintTrace_IO_RDI();
+ PrintTrace_IO_RIP();
+ PrintTrace_VM_INSTR_ERROR();
+ PrintTrace("\n");
+}
--- /dev/null
+#include <palacios/vmm.h>
+#include <palacios/svm.h>
+#include <palacios/vmx.h>
+
+
+uint_t vmm_cpu_type;
+
+
+
+
+struct vmm_os_hooks * os_hooks = NULL;
+
+
+
+void Init_VMM(struct vmm_os_hooks * hooks, struct vmm_ctrl_ops * vmm_ops) {
+ vmm_cpu_type = VMM_INVALID_CPU;
+
+ os_hooks = hooks;
+
+
+
+ if (is_svm_capable()) {
+ vmm_cpu_type = VMM_SVM_CPU;
+ PrintDebug("Machine is SVM Capable\n");
+
+ Init_SVM(vmm_ops);
+
+ /*
+ } else if (is_vmx_capable()) {
+ vmm_cpu_type = VMM_VMX_CPU;
+ PrintDebug("Machine is VMX Capable\n");
+ //Init_VMX();*/
+ } else {
+ PrintDebug("CPU has no virtualization Extensions\n");
+ }
+}
--- /dev/null
+#include <palacios/vmm_debug.h>
+#include <palacios/vmm.h>
+
+
+void PrintDebugHex(unsigned char x)
+{
+ unsigned char z;
+
+ z = (x>>4) & 0xf ;
+ PrintDebug("%x", z);
+ z = x & 0xf;
+ PrintDebug("%x", z);
+}
+
+void PrintDebugMemDump(unsigned char *start, int n)
+{
+ int i, j;
+
+ for (i=0;i<n;i+=16) {
+ PrintDebug("%8x", (unsigned)(start+i));
+ for (j=i; j<i+16 && j<n; j+=2) {
+ PrintDebug(" ");
+ PrintDebugHex(*((unsigned char *)(start+j)));
+ if ((j+1)<n) {
+ PrintDebugHex(*((unsigned char *)(start+j+1)));
+ }
+ }
+ PrintDebug(" ");
+ for (j=i; j<i+16 && j<n;j++) {
+ PrintDebug("%c", ((start[j]>=32) && (start[j]<=126)) ? start[j] : '.');
+ }
+ PrintDebug("\n");
+ }
+}
--- /dev/null
+#include <palacios/vmm_io.h>
+#include <palacios/vmm_string.h>
+#include <palacios/vmm.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+void init_vmm_io_map(vmm_io_map_t * io_map) {
+ io_map->num_ports = 0;
+ io_map->head = NULL;
+}
+
+
+
+void add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
+ vmm_io_hook_t * tmp_hook = io_map->head;
+
+ if (!tmp_hook) {
+ io_map->head = io_hook;
+ io_map->num_ports = 1;
+ return;
+ } else {
+ while ((tmp_hook->next) &&
+ (tmp_hook->next->port <= io_hook->port)) {
+ tmp_hook = tmp_hook->next;
+ }
+
+ if (tmp_hook->port == io_hook->port) {
+ tmp_hook->read = io_hook->read;
+ tmp_hook->write = io_hook->write;
+
+ VMMFree(io_hook);
+ return;
+ } else if (!tmp_hook->next) {
+ tmp_hook->next = io_hook;
+ io_hook->prev = tmp_hook;
+ io_map->num_ports++;
+
+ return;
+ } else {
+ io_hook->next = tmp_hook->next;
+ io_hook->prev = tmp_hook;
+
+ tmp_hook->next = io_hook;
+ if (io_hook->next) {
+ io_hook->next->prev = io_hook;
+ }
+
+ io_map->num_ports++;
+ return;
+ }
+ }
+}
+
+void hook_io_port(vmm_io_map_t * io_map, uint_t port,
+ int (*read)(ushort_t port, void * dst, uint_t length),
+ int (*write)(ushort_t port, void * src, uint_t length)) {
+ vmm_io_hook_t * io_hook = os_hooks->malloc(sizeof(vmm_io_hook_t));
+
+ io_hook->port = port;
+ io_hook->read = read;
+ io_hook->write = write;
+ io_hook->next = NULL;
+ io_hook->prev = NULL;
+
+ add_io_hook(io_map, io_hook);
+
+ return;
+}
+
+
+vmm_io_hook_t * get_io_hook(vmm_io_map_t * io_map, uint_t port) {
+ vmm_io_hook_t * tmp_hook;
+ FOREACH_IO_HOOK(*io_map, tmp_hook) {
+ if (tmp_hook->port == port) {
+ return tmp_hook;
+ }
+ }
+ return NULL;
+}
+
+
+
+void PrintDebugIOMap(vmm_io_map_t * io_map) {
+ vmm_io_hook_t * iter = io_map->head;
+
+ PrintDebug("VMM IO Map (Entries=%d)\n", io_map->num_ports);
+
+ while (iter) {
+ PrintDebug("IO Port: %hu (Read=%x) (Write=%x)\n", iter->port, iter->read, iter->write);
+ }
+}
--- /dev/null
+#include <palacios/vmm_mem.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_util.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+void init_shadow_region(shadow_region_t * entry,
+ addr_t guest_addr_start,
+ addr_t guest_addr_end,
+ guest_region_type_t guest_region_type,
+ host_region_type_t host_region_type)
+{
+ entry->guest_type = guest_region_type;
+ entry->guest_start = guest_addr_start;
+ entry->guest_end = guest_addr_end;
+ entry->host_type = host_region_type;
+ entry->next=entry->prev = NULL;
+}
+
+void init_shadow_region_physical(shadow_region_t * entry,
+ addr_t guest_addr_start,
+ addr_t guest_addr_end,
+ guest_region_type_t guest_region_type,
+ addr_t host_addr_start,
+ host_region_type_t host_region_type)
+{
+ init_shadow_region(entry, guest_addr_start, guest_addr_end, guest_region_type, host_region_type);
+ entry->host_addr.phys_addr.host_start = host_addr_start;
+
+}
+
+
+void init_shadow_map(shadow_map_t * map) {
+ map->num_regions = 0;
+
+ map->head = NULL;
+}
+
+
+void free_shadow_map(shadow_map_t * map) {
+ shadow_region_t * cursor = map->head;
+ shadow_region_t * tmp = NULL;
+
+ while(cursor) {
+ tmp = cursor;
+ cursor = cursor->next;
+ VMMFree(tmp);
+ }
+
+ VMMFree(map);
+}
+
+
+
+/* This is slightly different semantically from the mem list, in that
+ * we don't allow overlaps we could probably allow overlappig regions
+ * of the same type... but I'll let someone else deal with that
+ */
+int add_shadow_region(shadow_map_t * map,
+ shadow_region_t * region)
+{
+ shadow_region_t * cursor = map->head;
+
+ if ((!cursor) || (cursor->guest_start >= region->guest_end)) {
+ region->prev = NULL;
+ region->next = cursor;
+ map->num_regions++;
+ map->head = region;
+ return 0;
+ }
+
+ while (cursor) {
+ // Check if it overlaps with the current cursor
+ if ((cursor->guest_end > region->guest_start) && (cursor->guest_start < region->guest_start)) {
+ // overlaps not allowed
+ return -1;
+ }
+
+ if (!(cursor->next)) {
+ // add to the end of the list
+ cursor->next = region;
+ region->prev = cursor;
+ region->next = NULL;
+ map->num_regions++;
+ return 0;
+ } else if (cursor->next->guest_start >= region->guest_end) {
+ // add here
+ region->next = cursor->next;
+ region->prev = cursor;
+
+ cursor->next->prev = region;
+ cursor->next = region;
+
+ map->num_regions++;
+
+ return 0;
+ } else if (cursor->next->guest_end < region->guest_start) {
+ cursor = cursor->next;
+ } else {
+ // This cannot happen!
+ // we should panic here
+ return -1;
+ }
+ }
+
+ // This cannot happen
+ // We should panic here
+ return -1;
+}
+
+
+int delete_shadow_region(shadow_map_t * map,
+ addr_t guest_start,
+ addr_t guest_end) {
+ return -1;
+}
+
+
+
+shadow_region_t *get_shadow_region_by_index(shadow_map_t * map,
+ uint_t index) {
+ shadow_region_t * reg = map->head;
+ uint_t i = 0;
+
+ while (reg) {
+ if (i == index) {
+ return reg;
+ }
+ reg = reg->next;
+ i++;
+ }
+ return NULL;
+}
+
+
+shadow_region_t * get_shadow_region_by_addr(shadow_map_t * map,
+ addr_t addr) {
+ shadow_region_t * reg = map->head;
+
+ while (reg) {
+ if ((reg->guest_start <= addr) && (reg->guest_end > addr)) {
+ return reg;
+ } else if (reg->guest_start > addr) {
+ return NULL;
+ } else {
+ reg = reg->next;
+ }
+ }
+ return NULL;
+}
+
+
+
+host_region_type_t lookup_shadow_map_addr(shadow_map_t * map, addr_t guest_addr, addr_t * host_addr) {
+ shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
+
+ if (!reg) {
+ // No mapping exists
+ return HOST_REGION_INVALID;
+ } else {
+ switch (reg->host_type) {
+ case HOST_REGION_PHYSICAL_MEMORY:
+ *host_addr = (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
+ return reg->host_type;
+ case HOST_REGION_MEMORY_MAPPED_DEVICE:
+ case HOST_REGION_UNALLOCATED:
+ // ...
+ default:
+ *host_addr = 0;
+ return reg->host_type;
+ }
+ }
+}
+
+
+void print_shadow_map(shadow_map_t * map) {
+ shadow_region_t * cur = map->head;
+ int i = 0;
+
+ PrintDebug("Memory Layout (regions: %d) \n", map->num_regions);
+
+ while (cur) {
+ PrintDebug("%d: 0x%x - 0x%x (%s) -> ", i, cur->guest_start, cur->guest_end - 1,
+ cur->guest_type == GUEST_REGION_PHYSICAL_MEMORY ? "GUEST_REGION_PHYSICAL_MEMORY" :
+ cur->guest_type == GUEST_REGION_NOTHING ? "GUEST_REGION_NOTHING" :
+ cur->guest_type == GUEST_REGION_MEMORY_MAPPED_DEVICE ? "GUEST_REGION_MEMORY_MAPPED_DEVICE" :
+ "UNKNOWN");
+ if (cur->host_type == HOST_REGION_PHYSICAL_MEMORY ||
+ cur->host_type == HOST_REGION_UNALLOCATED ||
+ cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) {
+ PrintDebug("0x%x", cur->host_addr.phys_addr.host_start);
+ }
+ PrintDebug("(%s)\n",
+ cur->host_type == HOST_REGION_PHYSICAL_MEMORY ? "HOST_REGION_PHYSICAL_MEMORY" :
+ cur->host_type == HOST_REGION_UNALLOCATED ? "HOST_REGION_UNALLOACTED" :
+ cur->host_type == HOST_REGION_NOTHING ? "HOST_REGION_NOTHING" :
+ cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE ? "HOST_REGION_MEMORY_MAPPED_DEVICE" :
+ cur->host_type == HOST_REGION_REMOTE ? "HOST_REGION_REMOTE" :
+ cur->host_type == HOST_REGION_SWAPPED ? "HOST_REGION_SWAPPED" :
+ "UNKNOWN");
+ cur = cur->next;
+ i++;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+#ifdef VMM_MEM_TEST
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+
+
+
+
+struct vmm_os_hooks * os_hooks;
+
+void * TestMalloc(uint_t size) {
+ return malloc(size);
+}
+
+void * TestAllocatePages(int size) {
+ return malloc(4096 * size);
+}
+
+
+void TestPrint(const char * fmt, ...) {
+ va_list args;
+
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+int mem_list_add_test_1( vmm_mem_list_t * list) {
+
+ uint_t offset = 0;
+
+ PrintDebug("\n\nTesting Memory List\n");
+
+ init_mem_list(list);
+
+ offset = PAGE_SIZE * 6;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
+ add_mem_list_pages(list, offset, 10);
+ print_mem_list(list);
+
+
+ offset = 0;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
+ add_mem_list_pages(list, offset, 4);
+ print_mem_list(list);
+
+ offset = PAGE_SIZE * 20;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
+ add_mem_list_pages(list, offset, 1);
+ print_mem_list(list);
+
+ offset = PAGE_SIZE * 21;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3));
+ add_mem_list_pages(list, offset, 3);
+ print_mem_list(list);
+
+
+ offset = PAGE_SIZE * 10;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
+ add_mem_list_pages(list, offset, 30);
+ print_mem_list(list);
+
+
+ offset = PAGE_SIZE * 5;
+ PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
+ add_mem_list_pages(list, offset, 1);
+ print_mem_list(list);
+
+
+
+ return 0;
+}
+
+
+int mem_layout_add_test_1(vmm_mem_layout_t * layout) {
+
+
+ uint_t start = 0;
+ uint_t end = 0;
+
+ PrintDebug("\n\nTesting Memory Layout\n");
+
+ init_mem_layout(layout);
+
+ start = 0x6000;
+ end = 0x10000;;
+ PrintDebug("Adding 0x%x - 0x%x\n", start, end);
+ add_guest_mem_range(layout, start, end);
+ print_mem_layout(layout);
+
+
+ start = 0x1000;
+ end = 0x3000;
+ PrintDebug("Adding 0x%x - 0x%x\n", start, end);
+ add_guest_mem_range(layout, start, end);
+ print_mem_layout(layout);
+
+ start = 0x2000;
+ end = 0x6000;
+ PrintDebug("Adding 0x%x - 0x%x\n", start, end);
+ add_guest_mem_range(layout, start, end);
+ print_mem_layout(layout);
+
+ start = 0x4000;
+ end = 0x5000;
+ PrintDebug("Adding 0x%x - 0x%x\n", start, end);
+ add_guest_mem_range(layout, start, end);
+ print_mem_layout(layout);
+
+
+ start = 0x5000;
+ end = 0x7000;
+ PrintDebug("Adding 0x%x - 0x%x\n", start, end);
+ add_guest_mem_range(layout, start, end);
+ print_mem_layout(layout);
+
+
+
+
+ return 0;
+}
+
+
+
+int main(int argc, char ** argv) {
+ struct vmm_os_hooks dummy_hooks;
+ os_hooks = &dummy_hooks;
+
+ vmm_mem_layout_t layout;
+ vmm_mem_list_t list;
+
+ os_hooks->malloc = &TestMalloc;
+ os_hooks->free = &free;
+ os_hooks->print_debug = &TestPrint;
+ os_hooks->allocate_pages = &TestAllocatePages;
+
+
+
+ printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list));
+ printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout));
+
+ return 0;
+}
+#endif
+
+
+
+
+
+
--- /dev/null
+#include <palacios/vmm_paging.h>
+
+#include <palacios/vmm.h>
+
+#include <palacios/vm_guest_mem.h>
+
+
+extern struct vmm_os_hooks * os_hooks;
+
+void delete_page_tables_pde32(pde32_t * pde) {
+ int i, j;
+
+ if (pde == NULL) {
+ return;
+ }
+
+ for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
+ if (pde[i].present) {
+ pte32_t * pte = (pte32_t *)(pde[i].pt_base_addr << PAGE_POWER);
+
+ for (j = 0; (j < MAX_PTE32_ENTRIES); j++) {
+ if ((pte[j].present)) {
+ os_hooks->free_page((void *)(pte[j].page_base_addr << PAGE_POWER));
+ }
+ }
+
+ os_hooks->free_page(pte);
+ }
+ }
+
+ os_hooks->free_page(pde);
+}
+
+
+
+
+
+
+
+/* We can't do a full lookup because we don't know what context the page tables are in...
+ * The entry addresses could be pointing to either guest physical memory or host physical memory
+ * Instead we just return the entry address, and a flag to show if it points to a pte or a large page...
+ */
+pde32_entry_type_t pde32_lookup(pde32_t * pde, addr_t addr, addr_t * entry) {
+ pde32_t * pde_entry = &(pde[PDE32_INDEX(addr)]);
+
+ if (!pde_entry->present) {
+ *entry = 0;
+ return NOT_PRESENT;
+ } else {
+ *entry = PAGE_ADDR(pde_entry->pt_base_addr);
+
+ if (pde_entry->large_pages) {
+ *entry += PAGE_OFFSET(addr);
+ return LARGE_PAGE;
+ } else {
+ return PTE32;
+ }
+ }
+ return NOT_PRESENT;
+}
+
+
+int pte32_lookup(pte32_t * pte, addr_t addr, addr_t * entry) {
+ pte32_t * pte_entry = &(pte[PTE32_INDEX(addr)]);
+
+ if (!pte_entry->present) {
+ *entry = 0;
+ return -1;
+ } else {
+ *entry = PAGE_ADDR(pte_entry->page_base_addr);
+ *entry += PAGE_OFFSET(addr);
+ return 0;
+ }
+
+ return -1;
+}
+
+
+
+
+
+
+
+
+/* We generate a page table to correspond to a given memory layout
+ * pulling pages from the mem_list when necessary
+ * If there are any gaps in the layout, we add them as unmapped pages
+ */
+pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info) {
+ ullong_t current_page_addr = 0;
+ int i, j;
+ shadow_map_t * map = &(guest_info->mem_map);
+
+
+ pde32_t * pde = os_hooks->allocate_pages(1);
+
+ for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+ int pte_present = 0;
+ pte32_t * pte = os_hooks->allocate_pages(1);
+
+
+ for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
+ shadow_region_t * region = get_shadow_region_by_addr(map, current_page_addr);
+
+ if (!region ||
+ (region->host_type == HOST_REGION_NOTHING) ||
+ (region->host_type == HOST_REGION_UNALLOCATED) ||
+ (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) ||
+ (region->host_type == HOST_REGION_REMOTE) ||
+ (region->host_type == HOST_REGION_SWAPPED)) {
+ pte[j].present = 0;
+ pte[j].flags = 0;
+ pte[j].accessed = 0;
+ pte[j].dirty = 0;
+ pte[j].pte_attr = 0;
+ pte[j].global_page = 0;
+ pte[j].vmm_info = 0;
+ pte[j].page_base_addr = 0;
+ } else {
+ addr_t host_addr;
+ pte[j].present = 1;
+ pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+
+ pte[j].accessed = 0;
+ pte[j].dirty = 0;
+ pte[j].pte_attr = 0;
+ pte[j].global_page = 0;
+ pte[j].vmm_info = 0;
+
+ if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
+ // BIG ERROR
+ // PANIC
+ return NULL;
+ }
+
+ pte[j].page_base_addr = host_addr >> 12;
+
+ pte_present = 1;
+ }
+
+ current_page_addr += PAGE_SIZE;
+ }
+
+ if (pte_present == 0) {
+ os_hooks->free_page(pte);
+
+ pde[i].present = 0;
+ pde[i].flags = 0;
+ pde[i].accessed = 0;
+ pde[i].reserved = 0;
+ pde[i].large_pages = 0;
+ pde[i].global_page = 0;
+ pde[i].vmm_info = 0;
+ pde[i].pt_base_addr = 0;
+ } else {
+ pde[i].present = 1;
+ pde[i].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+ pde[i].accessed = 0;
+ pde[i].reserved = 0;
+ pde[i].large_pages = 0;
+ pde[i].global_page = 0;
+ pde[i].vmm_info = 0;
+ pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(pte);
+ }
+
+ }
+
+ return pde;
+}
+
+
+
+
+
+
+void PrintPDE32(void * virtual_address, pde32_t * pde)
+{
+ PrintDebug("PDE %p -> %p : present=%x, flags=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
+ virtual_address,
+ (void *) (pde->pt_base_addr << PAGE_POWER),
+ pde->present,
+ pde->flags,
+ pde->accessed,
+ pde->reserved,
+ pde->large_pages,
+ pde->global_page,
+ pde->vmm_info);
+}
+
+void PrintPTE32(void * virtual_address, pte32_t * pte)
+{
+ PrintDebug("PTE %p -> %p : present=%x, flags=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
+ virtual_address,
+ (void*)(pte->page_base_addr << PAGE_POWER),
+ pte->present,
+ pte->flags,
+ pte->accessed,
+ pte->dirty,
+ pte->pte_attr,
+ pte->global_page,
+ pte->vmm_info);
+}
+
+
+
+void PrintPD32(pde32_t * pde)
+{
+ int i;
+
+ PrintDebug("Page Directory at %p:\n", pde);
+ for (i = 0; (i < MAX_PDE32_ENTRIES) && pde[i].present; i++) {
+ PrintPDE32((void*)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+ }
+}
+
+void PrintPT32(void * starting_address, pte32_t * pte)
+{
+ int i;
+
+ PrintDebug("Page Table at %p:\n", pte);
+ for (i = 0; (i < MAX_PTE32_ENTRIES) && pte[i].present; i++) {
+ PrintPTE32(starting_address + (PAGE_SIZE * i), &(pte[i]));
+ }
+}
+
+
+
+
+
+void PrintDebugPageTables(pde32_t * pde)
+{
+ int i;
+
+ PrintDebug("Dumping the pages starting with the pde page at %p\n", pde);
+
+ for (i = 0; (i < MAX_PDE32_ENTRIES) && pde[i].present; i++) {
+ PrintPDE32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+ PrintPT32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER));
+ }
+}
+
--- /dev/null
+#include <palacios/vmm_shadow_paging.h>
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest_mem.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+int init_shadow_page_state(struct shadow_page_state * state) {
+ state->guest_mode = PDE32;
+ state->shadow_mode = PDE32;
+
+ state->guest_cr3.r_reg = 0;
+ state->shadow_cr3.r_reg = 0;
+
+ return 0;
+}
+
+
+int wholesale_update_shadow_page_state(struct guest_info * guest_info) {
+ unsigned i, j;
+ pde32_t * guest_pde;
+ pde32_t * shadow_pde;
+
+ struct shadow_page_state * state = &(guest_info->shdw_pg_state);
+
+
+ // For now, we'll only work with PDE32
+ if (state->guest_mode != PDE32) {
+ return -1;
+ }
+
+ shadow_pde = (pde32_t *)(CR3_TO_PDE32(state->shadow_cr3.e_reg.low));
+
+ if (host_pa_to_host_va(CR3_TO_PDE32(state->guest_cr3.e_reg.low), (addr_t*)&guest_pde) != 0) {
+ return -1;
+ }
+
+ // Delete the current page table
+ delete_page_tables_pde32(shadow_pde);
+
+ shadow_pde = os_hooks->allocate_pages(1);
+
+ state->shadow_cr3.e_reg.low = (addr_t)shadow_pde;
+
+ state->shadow_mode = PDE32;
+
+ for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+ shadow_pde[i] = guest_pde[i];
+
+ // The shadow can be identical to the guest if it's not present
+ if (!shadow_pde[i].present) {
+ continue;
+ }
+
+ if (shadow_pde[i].large_pages) {
+ // large page - just map it through shadow map to generate its physical location
+ addr_t guest_addr = PAGE_ADDR(shadow_pde[i].pt_base_addr);
+ addr_t host_addr;
+ shadow_region_t * ent;
+
+ ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
+
+ if (!ent) {
+ // FIXME Panic here - guest is trying to map to physical memory
+ // it does not own in any way!
+ return -1;
+ }
+
+ // FIXME Bounds check here to see if it's trying to trick us
+
+ switch (ent->host_type) {
+ case HOST_REGION_PHYSICAL_MEMORY:
+ // points into currently allocated physical memory, so we just
+ // set up the shadow to point to the mapped location
+ if (guest_pa_to_host_pa(guest_info, guest_addr, &host_addr)) {
+ // Panic here
+ return -1;
+ }
+
+ shadow_pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(host_addr);
+ // FIXME set vmm_info bits here
+ break;
+ case HOST_REGION_UNALLOCATED:
+ // points to physical memory that is *allowed* but that we
+ // have not yet allocated. We mark as not present and set a
+ // bit to remind us to allocate it later
+ shadow_pde[i].present = 0;
+ // FIXME Set vminfo bits here so that we know that we will be
+ // allocating it later
+ break;
+ case HOST_REGION_NOTHING:
+ // points to physical memory that is NOT ALLOWED.
+ // We will mark it as not present and set a bit to remind
+ // us that it's bad later and insert a GPF then
+ shadow_pde[i].present = 0;
+ break;
+ case HOST_REGION_MEMORY_MAPPED_DEVICE:
+ case HOST_REGION_REMOTE:
+ case HOST_REGION_SWAPPED:
+ default:
+ // Panic. Currently unhandled
+ return -1;
+ break;
+ }
+ } else {
+ pte32_t * guest_pte;
+ pte32_t * shadow_pte;
+ addr_t guest_addr;
+ addr_t guest_pte_host_addr;
+ shadow_region_t * ent;
+
+ // small page - set PDE and follow down to the child table
+ shadow_pde[i] = guest_pde[i];
+
+ guest_addr = PAGE_ADDR(guest_pde[i].pt_base_addr);
+
+ // Allocate a new second level page table for the shadow
+ shadow_pte = os_hooks->allocate_pages(1);
+
+ // make our first level page table in the shadow point to it
+ shadow_pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(shadow_pte);
+
+ ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
+
+
+ /* JRL: This is bad.... */
+ // For now the guest Page Table must always be mapped to host physical memory
+ /* If we swap out a page table or if it isn't present for some reason, this turns real ugly */
+
+ if ((!ent) || (ent->host_type != HOST_REGION_PHYSICAL_MEMORY)) {
+ // FIXME Panic here - guest is trying to map to physical memory
+ // it does not own in any way!
+ return -1;
+ }
+
+ // Address of the relevant second level page table in the guest
+ if (guest_pa_to_host_pa(guest_info, guest_addr, &guest_pte_host_addr)) {
+ // Panic here
+ return -1;
+ }
+
+
+ // host_addr now contains the host physical address for the guest's 2nd level page table
+ // Now we transform it to relevant virtual address
+ guest_pte = os_hooks->paddr_to_vaddr((void *)guest_pte_host_addr);
+
+ // Now we walk through the second level guest page table
+ // and clone it into the shadow
+ for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
+ shadow_pte[j] = guest_pte[j];
+
+ addr_t guest_addr = PAGE_ADDR(shadow_pte[j].page_base_addr);
+
+ shadow_region_t * ent;
+
+ ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
+
+ if (!ent) {
+ // FIXME Panic here - guest is trying to map to physical memory
+ // it does not own in any way!
+ return -1;
+ }
+
+ switch (ent->host_type) {
+ case HOST_REGION_PHYSICAL_MEMORY:
+ {
+ addr_t host_addr;
+
+ // points into currently allocated physical memory, so we just
+ // set up the shadow to point to the mapped location
+ if (guest_pa_to_host_pa(guest_info, guest_addr, &host_addr)) {
+ // Panic here
+ return -1;
+ }
+
+ shadow_pte[j].page_base_addr = PAGE_ALIGNED_ADDR(host_addr);
+ // FIXME set vmm_info bits here
+ break;
+ }
+ case HOST_REGION_UNALLOCATED:
+ // points to physical memory that is *allowed* but that we
+ // have not yet allocated. We mark as not present and set a
+ // bit to remind us to allocate it later
+ shadow_pte[j].present = 0;
+ // FIXME Set vminfo bits here so that we know that we will be
+ // allocating it later
+ break;
+ case HOST_REGION_NOTHING:
+ // points to physical memory that is NOT ALLOWED.
+ // We will mark it as not present and set a bit to remind
+ // us that it's bad later and insert a GPF then
+ shadow_pte[j].present = 0;
+ break;
+ case HOST_REGION_MEMORY_MAPPED_DEVICE:
+ case HOST_REGION_REMOTE:
+ case HOST_REGION_SWAPPED:
+ default:
+ // Panic. Currently unhandled
+ return -1;
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * String library
+ * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+ * $Revision: 1.1 $
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "COPYING".
+ */
+
+/*
+ * NOTE:
+ * These are slow and simple implementations of a subset of
+ * the standard C library string functions.
+ * We also have an implementation of snprintf().
+ */
+
+
+#include <palacios/vmm_string.h>
+
+extern void *Malloc(size_t size);
+
+void* memset(void* s, int c, size_t n)
+{
+ unsigned char* p = (unsigned char*) s;
+
+ while (n > 0) {
+ *p++ = (unsigned char) c;
+ --n;
+ }
+
+ return s;
+}
+
+void* memcpy(void *dst, const void* src, size_t n)
+{
+ unsigned char* d = (unsigned char*) dst;
+ const unsigned char* s = (const unsigned char*) src;
+
+ while (n > 0) {
+ *d++ = *s++;
+ --n;
+ }
+
+ return dst;
+}
+
+int memcmp(const void *s1_, const void *s2_, size_t n)
+{
+ const signed char *s1 = s1_, *s2 = s2_;
+
+ while (n > 0) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0)
+ return cmp;
+ ++s1;
+ ++s2;
+ }
+
+ return 0;
+}
+
+size_t strlen(const char* s)
+{
+ size_t len = 0;
+ while (*s++ != '\0')
+ ++len;
+ return len;
+}
+
+/*
+ * This it a GNU extension.
+ * It is like strlen(), but it will check at most maxlen
+ * characters for the terminating nul character,
+ * returning maxlen if it doesn't find a nul.
+ * This is very useful for checking the length of untrusted
+ * strings (e.g., from user space).
+ */
+size_t strnlen(const char *s, size_t maxlen)
+{
+ size_t len = 0;
+ while (len < maxlen && *s++ != '\0')
+ ++len;
+ return len;
+}
+
+int strcmp(const char* s1, const char* s2)
+{
+ while (1) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
+ return cmp;
+ ++s1;
+ ++s2;
+ }
+}
+
+int strncmp(const char* s1, const char* s2, size_t limit)
+{
+ size_t i = 0;
+ while (i < limit) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
+ return cmp;
+ ++s1;
+ ++s2;
+ ++i;
+ }
+
+ /* limit reached and equal */
+ return 0;
+}
+
+char *strcat(char *s1, const char *s2)
+{
+ char *t1;
+
+ t1 = s1;
+ while (*s1) s1++;
+ while(*s2) *s1++ = *s2++;
+ *s1 = '\0';
+
+ return t1;
+}
+
+char *strcpy(char *dest, const char *src)
+{
+ char *ret = dest;
+
+ while (*src) {
+ *dest++ = *src++;
+ }
+ *dest = '\0';
+
+ return ret;
+}
+
+char *strncpy(char *dest, const char *src, size_t limit)
+{
+ char *ret = dest;
+
+ while (*src != '\0' && limit > 0) {
+ *dest++ = *src++;
+ --limit;
+ }
+ if (limit > 0)
+ *dest = '\0';
+
+ return ret;
+}
+
+char *strdup(const char *s1)
+{
+ char *ret;
+
+ ret = Malloc(strlen(s1) + 1);
+ strcpy(ret, s1);
+
+ return ret;
+}
+
+int atoi(const char *buf)
+{
+ int ret = 0;
+
+ while (*buf >= '0' && *buf <= '9') {
+ ret *= 10;
+ ret += *buf - '0';
+ buf++;
+ }
+
+ return ret;
+}
+
+char *strchr(const char *s, int c)
+{
+ while (*s != '\0') {
+ if (*s == c)
+ return (char *) s;
+ ++s;
+ }
+ return 0;
+}
+
+char *strrchr(const char *s, int c)
+{
+ size_t len = strlen(s);
+ const char *p = s + len;
+
+ while (p > s) {
+ --p;
+ if (*p == c)
+ return (char*) p;
+ }
+ return 0;
+}
+
+char *strpbrk(const char *s, const char *accept)
+{
+ size_t setLen = strlen(accept);
+
+ while (*s != '\0') {
+ size_t i;
+ for (i = 0; i < setLen; ++i) {
+ if (*s == accept[i])
+ return (char *) s;
+ }
+ ++s;
+ }
+
+ return 0;
+}
+
--- /dev/null
+; Symbol mangling macros
+; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
+; $Revision: 1.1 $
+
+; This file defines macros for dealing with externally-visible
+; symbols that must be mangled for some object file formats.
+; For example, PECOFF requires a leading underscore, while
+; ELF does not.
+
+; EXPORT defines a symbol as global
+; IMPORT references a symbol defined in another module
+
+; Thanks to Christopher Giese for providing the NASM macros
+; (thus saving me hours of frustration).
+
+%ifndef __VMM_SYMBOL_ASM
+%define __VMM_SYMBOL_ASM
+
+%ifdef NEED_UNDERSCORE
+
+%macro EXPORT 1
+[GLOBAL _%1]
+%define %1 _%1
+%endmacro
+
+%macro IMPORT 1
+[EXTERN _%1]
+%define %1 _%1
+%endmacro
+
+%else
+
+%macro EXPORT 1
+[GLOBAL %1]
+%endmacro
+
+%macro IMPORT 1
+[EXTERN %1]
+%endmacro
+
+%endif
+
+%endif
--- /dev/null
+#include <palacios/vmm_util.h>
+
+#include <palacios/vmm.h>
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+void PrintTraceHex(unsigned char x) {
+ unsigned char z;
+
+ z = (x >> 4) & 0xf ;
+ PrintTrace("%x", z);
+ z = x & 0xf;
+ PrintTrace("%x", z);
+}
+
+
+void PrintTraceMemDump(unsigned char *start, int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i += 16) {
+ PrintTrace("%8x", (unsigned)(start + i));
+ for (j = i; (j < (i + 16)) && (j < n); j += 2) {
+ PrintTrace(" ");
+ PrintTraceHex(*((unsigned char *)(start + j)));
+ if ((j + 1) < n) {
+ PrintTraceHex(*((unsigned char *)(start + j + 1)));
+ }
+ }
+ PrintTrace(" ");
+ for (j = i; (j < (i + 16)) && (j < n); j++) {
+ PrintTrace("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.');
+ }
+ PrintTrace("\n");
+ }
+}
+
+
+
--- /dev/null
+/* Eventually we want to get rid of these */
+
+#include <geekos/cpu.h>
+#include <geekos/io_devs.h>
+#include <geekos/io.h>
+/* ** */
+
+#include <palacios/vmx.h>
+#include <palacios/vmcs.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_util.h>
+#include <palacios/vmm_string.h>
+
+
+extern void Get_MSR(unsigned int msr, uint_t * high, uint_t * low);
+extern void Set_MSR(unsigned int msr, uint_t high, uint_t low);
+extern int Enable_VMX(ullong_t regionPtr);
+extern int cpuid_ecx(unsigned int op);
+extern int Launch_VM(ullong_t vmcsPtr, uint_t eip);
+
+#define NUMPORTS 65536
+
+
+#define VMXASSIST_INFO_PORT 0x0e9
+#define ROMBIOS_PANIC_PORT 0x400
+#define ROMBIOS_PANIC_PORT2 0x401
+#define ROMBIOS_INFO_PORT 0x402
+#define ROMBIOS_DEBUG_PORT 0x403
+
+
+extern struct vmm_os_hooks * os_hooks;
+
+
+static struct VM theVM;
+
+static uint_t GetLinearIP(struct VM *vm)
+{
+ if (vm->state==VM_VMXASSIST_V8086_BIOS || vm->state==VM_VMXASSIST_V8086) {
+ return vm->vmcs.guestStateArea.cs.baseAddr + vm->vmcs.guestStateArea.rip;
+ } else {
+ return vm->vmcs.guestStateArea.rip;
+ }
+}
+
+
+static void VMXPanic()
+{
+ while (1) {}
+}
+
+
+#define MAX_CODE 512
+#define INSTR_OFFSET_START 17
+#define NOP_SEQ_LEN 10
+#define INSTR_OFFSET_END (INSTR_OFFSET_START+NOP_SEQ_LEN-1)
+#define TEMPLATE_CODE_LEN 35
+
+uint_t oldesp=0;
+uint_t myregs=0;
+
+// simply execute the instruction that is faulting and return
+static int ExecFaultingInstructionInVMM(struct VM *vm)
+{
+ uint_t address = GetLinearIP(vm);
+ myregs = (uint_t)&(vm->registers);
+
+
+ PrintTrace("About the execute faulting instruction!\n");
+ PrintTrace("Instruction is:\n");
+ PrintTraceMemDump((void*)(address),vm->vmcs.exitInfoFields.instrLength);
+
+
+ PrintTrace("The template code is:\n");
+ PrintTraceMemDump(&&template_code,TEMPLATE_CODE_LEN);
+
+ // clone the template code
+ //memcpy(&&template_code,code,MAX_CODE);
+
+ // clean up the nop field
+ memset(&&template_code+INSTR_OFFSET_START,*((uchar_t *)(&&template_code+0)),NOP_SEQ_LEN);
+ // overwrite the nops with the faulting instruction
+ memcpy(&&template_code+INSTR_OFFSET_START, (void*)(address),vm->vmcs.exitInfoFields.instrLength);
+
+ PrintTrace("Finished modifying the template code, which now is:\n");
+ PrintTraceMemDump(&&template_code,TEMPLATE_CODE_LEN);
+
+ PrintTrace("Now entering modified template code\n");
+
+
+ template_code:
+ // Template code stores current registers,
+ // restores registers, has a landing pad of noops
+ // that will be modified, restores current regs, and then returns
+ //
+ // Note that this currently ignores cr0, cr3, cr4, dr7, rsp, rip, and rflags
+ // it also blythly assumes it can exec the instruction in protected mode
+ //
+ __asm__ __volatile__ ("nop\n" // for cloning purposes (1 byte)
+ "pusha\n" // push our current regs onto the current stack (1 byte)
+ "movl %0, %%eax\n" // Get oldesp location (5 bytes)
+ "movl %%esp, (%%eax)\n" // store the current stack pointer in oldesp (2 bytes)
+ "movl %1, %%eax\n" // Get regs location (5 bytes)
+ "movl (%%eax), %%esp\n" // point esp at regs (2 bytes)
+ "popa\n" // now we have the VM registers restored (1 byte)
+ "nop\n" // now we execute the actual instruction (1 byte x 10)
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ "nop\n" // now we execute the actual instruction
+ // need to copy back to the VM registers!
+ "movl %0, %%eax\n" // recapture oldesp location (5 bytes)
+ "movl (%%eax), %%esp\n" // now we'll get our esp back from oldesp (2 bytes)
+ "popa\n" // and restore our GP regs and we're done (1 byte)
+ : "=m"(oldesp)
+ : "m"(myregs)
+ );
+
+ PrintTrace("Survived executing the faulting instruction and returning.\n");
+
+ vm->vmcs.guestStateArea.rip += vm->vmcs.exitInfoFields.instrLength;
+
+ return 0;
+
+}
+
+
+int is_vmx_capable() {
+ uint_t ret;
+ union VMX_MSR featureMSR;
+
+ ret = cpuid_ecx(1);
+ if (ret & CPUID_1_ECX_VTXFLAG) {
+ Get_MSR(IA32_FEATURE_CONTROL_MSR, &featureMSR.regs.high, &featureMSR.regs.low);
+
+ PrintTrace("MSRREGlow: 0x%.8x\n", featureMSR.regs.low);
+
+ if ((featureMSR.regs.low & FEATURE_CONTROL_VALID) != FEATURE_CONTROL_VALID) {
+ PrintDebug("VMX is locked -- enable in the BIOS\n");
+ return 0;
+ }
+ } else {
+ PrintDebug("VMX not supported on this cpu\n");
+ return 0;
+ }
+
+ return 1;
+
+}
+
+
+VmxOnRegion * Init_VMX() {
+ uint_t ret;
+ VmxOnRegion * region = NULL;
+
+
+ region = CreateVmxOnRegion();
+
+
+ ret = Enable_VMX((ullong_t)((uint_t)region));
+ if (ret == 0) {
+ PrintDebug("VMX Enabled\n");
+ } else {
+ PrintDebug("VMX failure (ret = %d)\n", ret);
+ }
+
+ theVM.vmxonregion = region;
+
+ return region;
+}
+
+extern uint_t VMCS_CLEAR();
+extern uint_t VMCS_LOAD();
+extern uint_t VMCS_STORE();
+extern uint_t VMCS_LAUNCH();
+extern uint_t VMCS_RESUME();
+extern uint_t Init_VMCS_HostState();
+extern uint_t Init_VMCS_GuestState();
+
+void SetCtrlBitsCorrectly(int msrno, int vmcsno)
+{
+ uint_t reserved =0;
+ union VMX_MSR msr;
+
+ PrintTrace("SetCtrlBitsCorrectly(%x,%x)\n", msrno, vmcsno);
+ Get_MSR(msrno, &msr.regs.high, &msr.regs.low);
+ PrintTrace("MSR %x = %x : %x \n", msrno, msr.regs.high, msr.regs.low);
+ reserved = msr.regs.low;
+ reserved &= msr.regs.high;
+ VMCS_WRITE(vmcsno, &reserved);
+}
+
+
+void SetCRBitsCorrectly(int msr0no, int msr1no, int vmcsno)
+{
+ uint_t reserved =0;
+ union VMX_MSR msr0, msr1;
+
+ PrintTrace("SetCRBitsCorrectly(%x,%x,%x)\n",msr0no,msr1no,vmcsno);
+ Get_MSR(msr0no, &msr0.regs.high, &msr0.regs.low);
+ Get_MSR(msr1no, &msr1.regs.high, &msr1.regs.low);
+ PrintTrace("MSR %x = %x, %x = %x \n", msr0no, msr0.regs.low, msr1no, msr1.regs.low);
+ reserved = msr0.regs.low;
+ reserved &= msr1.regs.low;
+ VMCS_WRITE(vmcsno, &reserved);
+}
+
+
+extern int Get_CR2();
+extern int vmRunning;
+
+
+static int PanicUnhandledVMExit(struct VM *vm)
+{
+ PrintInfo("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
+ PrintTrace("Panicking due to VMExit with reason %u\n", vm->vmcs.exitInfoFields.reason);
+ PrintTrace_VMCS_ALL();
+ PrintTrace_VMX_Regs(&(vm->registers));
+ VMXPanic();
+ return 0;
+}
+
+
+static int HandleVMPrintsAndPanics(struct VM *vm, uint_t port, uint_t data)
+{
+ if (port==VMXASSIST_INFO_PORT &&
+ (vm->state == VM_VMXASSIST_STARTUP ||
+ vm->state == VM_VMXASSIST_V8086_BIOS ||
+ vm->state == VM_VMXASSIST_V8086)) {
+ // Communication channel from VMXAssist
+ PrintTrace("VMXASSIST Output Port\n");
+ PrintDebug("%c",data&0xff);
+ return 1;
+ }
+
+ if ((port==ROMBIOS_PANIC_PORT ||
+ port==ROMBIOS_PANIC_PORT2 ||
+ port==ROMBIOS_DEBUG_PORT ||
+ port==ROMBIOS_INFO_PORT) &&
+ (vm->state==VM_VMXASSIST_V8086_BIOS)) {
+ // rombios is communicating
+ PrintTrace("ROMBIOS Output Port\n");
+ // PrintDebug("%c",data&0xff);
+ return 1;
+ }
+
+ if (port==BOOT_STATE_CARD_PORT && vm->state==VM_VMXASSIST_V8086_BIOS) {
+ // rombios is sending something to the display card
+ PrintTrace("Hex Display: 0x%x\n",data&0xff);
+ return 1;
+ }
+ return 0;
+}
+
+static int HandleInOutExit(struct VM *vm)
+{
+ uint_t address;
+
+ struct VMCSExitInfoFields *exitinfo = &(vm->vmcs.exitInfoFields);
+ struct VMExitIOQual * qual = (struct VMExitIOQual *)&(vm->vmcs.exitInfoFields.qualification);
+ struct VMXRegs *regs = &(vm->registers);
+
+ address=GetLinearIP(vm);
+
+ PrintTrace("Handling Input/Output Instruction Exit\n");
+
+ PrintTrace_VMX_Regs(regs);
+
+ PrintTrace("Qualifications=0x%x\n", exitinfo->qualification);
+ PrintTrace("Reason=0x%x\n", exitinfo->reason);
+ PrintTrace("IO Port: 0x%x (%d)\n", qual->port, qual->port);
+ PrintTrace("Instruction Info=%x\n", exitinfo->instrInfo);
+ PrintTrace("%x : %s %s %s instruction of length %d for %d bytes from/to port 0x%x\n",
+ address,
+ qual->dir == 0 ? "output" : "input",
+ qual->string ==0 ? "nonstring" : "STRING",
+ qual->REP == 0 ? "with no rep" : "WITH REP",
+ exitinfo->instrLength,
+ qual->accessSize==0 ? 1 : qual->accessSize==1 ? 2 : 4,
+ qual->port);
+
+ if ((qual->port == PIC_MASTER_CMD_ISR_PORT) ||
+ (qual->port == PIC_MASTER_IMR_PORT) ||
+ (qual->port == PIC_SLAVE_CMD_ISR_PORT) ||
+ (qual->port == PIC_SLAVE_IMR_PORT)) {
+ PrintTrace( "PIC Access\n");
+ }
+
+
+ if ((qual->dir == 1) && (qual->REP == 0) && (qual->string == 0)) {
+ char byte = In_Byte(qual->port);
+
+ vm->vmcs.guestStateArea.rip += exitinfo->instrLength;
+ regs->eax = (regs->eax & 0xffffff00) | byte;
+ PrintTrace("Returning 0x%x in eax\n", (regs->eax));
+ }
+
+ if (qual->dir==0 && qual->REP==0 && qual->string==0) {
+ // See if we need to handle the outb as a signal or
+ // print from the VM
+ if (HandleVMPrintsAndPanics(vm,qual->port,regs->eax)) {
+ } else {
+ // If not, just go ahead and do the outb
+ Out_Byte(qual->port,regs->eax);
+ PrintTrace("Wrote 0x%x to port\n",(regs->eax));
+ }
+ vm->vmcs.guestStateArea.rip += exitinfo->instrLength;
+ }
+
+ return 0;
+}
+
+
+static int HandleExternalIRQExit(struct VM *vm)
+{
+ struct VMCSExitInfoFields * exitinfo = &(vm->vmcs.exitInfoFields);
+ struct VMExitIntInfo * intInfo = (struct VMExitIntInfo *)&(vm->vmcs.exitInfoFields.intInfo);
+
+ PrintTrace("External Interrupt captured\n");
+ PrintTrace("IntInfo: %x\n", exitinfo->intInfo);
+
+
+ if (!intInfo->valid) {
+ // interrupts are off, but this interrupt is not acknoledged (still pending)
+ // so we turn on interrupts to deliver appropriately in the
+ // host
+ PrintTrace("External Interrupt is invald. Turning Interrupts back on\n");
+ asm("sti");
+ return 0;
+ }
+
+ // At this point, interrupts are off and the interrupt has been
+ // acknowledged. We will now handle the interrupt ourselves
+ // and turn interrupts back on in the host
+
+ PrintTrace("type: %d\n", intInfo->type);
+ PrintTrace("number: %d\n", intInfo->nr);
+
+ PrintTrace("Interrupt %d occuring now and handled by HandleExternalIRQExit\n",intInfo->nr);
+
+ switch (intInfo->type) {
+ case 0: { // ext. IRQ
+ // In the following, we construct an "int x" instruction
+ // where x is the specific interrupt number that is raised
+ // then we execute that instruciton
+ // because we are in host context, that means it is delivered as normal
+ // through the host IDT
+
+ ((char*)(&&ext_int_seq_start))[1] = intInfo->nr;
+
+ PrintTrace("Interrupt instruction setup done %x\n", *((ushort_t *)(&&ext_int_seq_start)));
+
+ext_int_seq_start:
+ asm("int $0");
+ }
+
+ break;
+ case 2: // NMI
+ PrintTrace("Type: NMI\n");
+ break;
+ case 3: // hw exception
+ PrintTrace("Type: HW Exception\n");
+ break;
+ case 4: // sw exception
+ PrintTrace("Type: SW Exception\n");
+ break;
+ default:
+ PrintTrace("Invalid Interrupt Type\n");
+ return -1;
+ }
+
+ if (intInfo->valid && intInfo->errorCode) {
+ PrintTrace("IntError: %x\n", exitinfo->intErrorCode);
+ }
+
+
+ return 0;
+
+}
+
+
+
+void DecodeCurrentInstruction(struct VM *vm, struct Instruction *inst)
+{
+ // this is a gruesome hack
+ uint_t address = GetLinearIP(vm);
+ uint_t length = vm->vmcs.exitInfoFields.instrLength;
+ unsigned char *t = (unsigned char *) address;
+
+
+
+ PrintTrace("DecodeCurrentInstruction: instruction is\n");
+ PrintTraceMemDump(t,length);
+
+ if (length==3 && t[0]==0x0f && t[1]==0x22 && t[2]==0xc0) {
+ // mov from eax to cr0
+ // usually used to signal
+ inst->type=VM_MOV_TO_CR0;
+ inst->address=address;
+ inst->size=length;
+ inst->input1=vm->registers.eax;
+ inst->input2=vm->vmcs.guestStateArea.cr0;
+ inst->output=vm->registers.eax;
+ PrintTrace("MOV FROM EAX TO CR0\n");
+ } else {
+ inst->type=VM_UNKNOWN_INST;
+ }
+}
+
+
+static void V8086ModeSegmentRegisterFixup(struct VM *vm)
+{
+ vm->vmcs.guestStateArea.cs.baseAddr=vm->vmcs.guestStateArea.cs.selector<<4;
+ vm->vmcs.guestStateArea.es.baseAddr=vm->vmcs.guestStateArea.es.selector<<4;
+ vm->vmcs.guestStateArea.ss.baseAddr=vm->vmcs.guestStateArea.ss.selector<<4;
+ vm->vmcs.guestStateArea.ds.baseAddr=vm->vmcs.guestStateArea.ds.selector<<4;
+ vm->vmcs.guestStateArea.fs.baseAddr=vm->vmcs.guestStateArea.fs.selector<<4;
+ vm->vmcs.guestStateArea.gs.baseAddr=vm->vmcs.guestStateArea.gs.selector<<4;
+}
+
+static void SetupV8086ModeForBoot(struct VM *vm)
+{
+ vm->state = VM_VMXASSIST_V8086_BIOS;
+
+ // Put guest into V8086 mode on return
+ vm->vmcs.guestStateArea.rflags |= EFLAGS_VM | EFLAGS_IOPL_HI | EFLAGS_IOPL_LO ;
+
+ // We will start at f000:fff0 on return
+ //
+ // We want this to look as much as possible as a processor
+ // reset
+ vm->vmcs.guestStateArea.rip = 0xfff0; // note, 16 bit rip
+ vm->vmcs.guestStateArea.cs.selector = 0xf000;
+ vm->vmcs.guestStateArea.cs.limit=0xffff;
+ vm->vmcs.guestStateArea.cs.access.as_dword = 0xf3;
+
+ vm->vmcs.guestStateArea.ss.selector = 0x0000;
+ vm->vmcs.guestStateArea.ss.limit=0xffff;
+ vm->vmcs.guestStateArea.ss.access.as_dword = 0xf3;
+
+ vm->vmcs.guestStateArea.ds.selector = 0x0000;
+ vm->vmcs.guestStateArea.ds.limit=0xffff;
+ vm->vmcs.guestStateArea.ds.access.as_dword = 0xf3;
+
+ vm->vmcs.guestStateArea.es.selector = 0x0000;
+ vm->vmcs.guestStateArea.es.limit=0xffff;
+ vm->vmcs.guestStateArea.es.access.as_dword = 0xf3;
+
+ vm->vmcs.guestStateArea.fs.selector = 0x0000;
+ vm->vmcs.guestStateArea.fs.limit=0xffff;
+ vm->vmcs.guestStateArea.fs.access.as_dword = 0xf3;
+
+ vm->vmcs.guestStateArea.gs.selector = 0x0000;
+ vm->vmcs.guestStateArea.gs.limit=0xffff;
+ vm->vmcs.guestStateArea.gs.access.as_dword = 0xf3;
+
+ V8086ModeSegmentRegisterFixup(vm);
+
+ PrintTrace_VMCSData(&(vm->vmcs));
+
+}
+
+
+
+static int HandleExceptionOrNMI(struct VM *vm)
+{
+ struct Instruction inst;
+ uint_t num;
+ uint_t type;
+ uint_t errorvalid;
+ uint_t error;
+ uint_t ext=0;
+ uint_t idt=0;
+ uint_t ti=0;
+ uint_t selectorindex=0;
+
+ PrintTrace("Exception or NMI occurred\n");
+
+ num=vm->vmcs.exitInfoFields.intInfo & 0xff;
+ type=(vm->vmcs.exitInfoFields.intInfo & 0x700)>>8;
+ errorvalid=(vm->vmcs.exitInfoFields.intInfo & 0x800)>>11;
+ if (errorvalid) {
+ error=vm->vmcs.exitInfoFields.intErrorCode;
+ ext=error&0x1;
+ idt=(error&0x2)>>1;
+ ti=(error&0x4)>>2;
+ selectorindex=(error>>3)&0xffff;
+ }
+
+ PrintTrace("Exception %d now - handled by HandleExceptionOrNMI\n",num);
+
+ PrintTrace("Exception Number %u : %s\n", num, exception_names[num]);
+ PrintTrace("Exception Type %u : %s\n", type, exception_type_names[type]);
+ if (errorvalid) {
+ if (ext) {
+ PrintTrace("External\n");
+ } else {
+ PrintTrace("%s - Selector Index is %u\n", idt ? "IDT" : ti ? "LDT" : "GDT", selectorindex);
+ }
+ }
+
+ DecodeCurrentInstruction(vm,&inst);
+
+ if (inst.type==VM_MOV_TO_CR0) {
+ PrintTrace("MOV TO CR0, oldvalue=0x%x, newvalue=0x%x\n",inst.input2, inst.input1);
+ if ((inst.input2 & CR0_PE) && !(inst.input1 & CR0_PE) && vm->state==VM_VMXASSIST_STARTUP) {
+ // This is VMXAssist signalling for us to turn on V8086 mode and
+ // jump into the bios
+ PrintTrace("VMXAssist is signaling us for switch to V8086 mode and jump to 0xf000:fff0\n");
+ SetupV8086ModeForBoot(vm);
+ goto leave;
+ } else {
+ PrintTrace("Instruction is a write to CR0, but we don't understand it so we'll just exec it\n");
+ }
+ }
+
+
+ PrintTrace("Trying to execute the faulting instruction in VMM context now\n");
+ ExecFaultingInstructionInVMM(vm);
+
+ leave:
+ //
+ //PanicUnhandledVMExit(vmcs,regs);
+ //VMXPanic();
+ return 0;
+}
+
+
+static struct VM *FindVM()
+{
+ return &theVM;
+}
+
+
+int Do_VMM(struct VMXRegs regs)
+{
+
+ ullong_t vmcs_ptr = 0;
+ uint_t vmcs_ptr_low = 0;
+ int ret = 0;
+ uint_t vmx_abort = 0;
+
+
+
+ PrintTrace("Vm Exit\n");
+ ret = VMCS_STORE(&vmcs_ptr);
+ vmcs_ptr &= 0xffffffff;
+ vmcs_ptr_low += vmcs_ptr;
+
+
+
+
+ PrintTrace("ret=%d\n", ret);
+ PrintTrace("Revision: %x\n", *(uint_t *)(vmcs_ptr_low));
+ vmx_abort = *(uint_t*)(((char *)vmcs_ptr_low)+4);
+
+ struct VM *vm = FindVM();
+
+ if (vmx_abort != 0) {
+ PrintTrace("VM ABORTED w/ code: %x\n", vmx_abort);
+ return -1;
+ }
+
+ vm->registers = regs;
+
+ if (CopyOutVMCSData(&(vm->vmcs)) != 0) {
+ PrintTrace("Could not copy out VMCS\n");
+ return -1;
+ }
+
+
+ PrintTrace("Guest esp: 0x%x (%u)\n", vm->vmcs.guestStateArea.rsp, vm->vmcs.guestStateArea.rsp);
+
+ PrintTrace("VM Exit for reason: %d (%x)\n",
+ vm->vmcs.exitInfoFields.reason & 0x00000fff,
+ vm->vmcs.exitInfoFields.reason);
+
+ if (vm->vmcs.exitInfoFields.reason & (0x1<<29) ) {
+ PrintTrace("VM Exit is from VMX root operation. Panicking\n");
+ VMXPanic();
+ }
+
+ if (vm->vmcs.exitInfoFields.reason & (0x1<<31) ) {
+ PrintTrace("VM Exit is due to a VM entry failure. Shouldn't happen here. Panicking\n");
+ PrintTrace_VMCSData(&(vm->vmcs));
+ VMXPanic();
+ }
+
+ switch (vm->vmcs.exitInfoFields.reason) {
+ case VM_EXIT_REASON_INFO_EXCEPTION_OR_NMI:
+ ret = HandleExceptionOrNMI(vm);
+ break;
+ case VM_EXIT_REASON_EXTERNAL_INTR:
+ ret = HandleExternalIRQExit(vm);
+ break;
+ case VM_EXIT_REASON_TRIPLE_FAULT:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_INIT_SIGNAL:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_STARTUP_IPI:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_IO_SMI:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_OTHER_SMI:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_INTR_WINDOW:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_NMI_WINDOW:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_TASK_SWITCH:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_CPUID:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_INVD:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_INVLPG:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_RDPMC:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_RDTSC:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_RSM:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMCALL:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMCLEAR:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMLAUNCH:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMPTRLD:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMPTRST:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMREAD:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMRESUME:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMWRITE:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMXOFF:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_VMXON:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_CR_REG_ACCESSES:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_MOV_DR:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_IO_INSTR:
+ ret = HandleInOutExit(vm);
+ break;
+ case VM_EXIT_REASON_RDMSR:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_WRMSR:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_ENTRY_FAIL_INVALID_GUEST_STATE:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_ENTRY_FAIL_MSR_LOAD:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_MWAIT:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_MONITOR:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_PAUSE:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_ENTRY_FAILURE_MACHINE_CHECK:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ case VM_EXIT_REASON_TPR_BELOW_THRESHOLD:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ default:
+ ret = PanicUnhandledVMExit(vm);
+ break;
+ }
+
+
+ regs = vm->registers;
+ CopyInVMCSData(&(vm->vmcs));
+
+ /*
+ {
+ VMCS_CLEAR(vmcs_ptr);
+ }
+ */
+
+ PrintTrace("Returning from Do_VMM: %d\n", ret);
+
+ return ret;
+}
+
+
+static void ConfigureExits(struct VM *vm)
+{
+ CopyOutVMCSExecCtrlFields(&(vm->vmcs.execCtrlFields));
+
+ vm->vmcs.execCtrlFields.pinCtrls |= 0
+ // EXTERNAL_INTERRUPT_EXITING
+ | NMI_EXITING;
+ vm->vmcs.execCtrlFields.procCtrls |= 0
+ // INTERRUPT_WINDOWS_EXIT
+ | USE_TSC_OFFSETTING
+ | HLT_EXITING
+ |INVLPG_EXITING
+ |MWAIT_EXITING
+ |RDPMC_EXITING
+ |RDTSC_EXITING
+ |MOVDR_EXITING
+ |UNCONDITION_IO_EXITING
+ |MONITOR_EXITING
+ |PAUSE_EXITING ;
+
+ CopyInVMCSExecCtrlFields(&(vm->vmcs.execCtrlFields));
+
+ CopyOutVMCSExitCtrlFields(&(vm->vmcs.exitCtrlFields));
+
+ vm->vmcs.exitCtrlFields.exitCtrls |= ACK_IRQ_ON_EXIT;
+
+ CopyInVMCSExitCtrlFields(&(vm->vmcs.exitCtrlFields));
+
+
+/* VMCS_READ(VM_EXIT_CTRLS, &flags); */
+/* flags |= ACK_IRQ_ON_EXIT; */
+/* VMCS_WRITE(VM_EXIT_CTRLS, &flags); */
+}
+
+
+extern int RunVMM();
+extern int SAFE_VM_LAUNCH();
+
+int MyLaunch(struct VM *vm)
+{
+ ullong_t vmcs = (ullong_t)((uint_t) (vm->vmcsregion));
+ uint_t entry_eip = vm->descriptor.entry_ip;
+ uint_t exit_eip = vm->descriptor.exit_eip;
+ uint_t guest_esp = vm->descriptor.guest_esp;
+ uint_t f = 0xffffffff;
+ uint_t tmpReg = 0;
+ int ret;
+ int vmm_ret = 0;
+
+ PrintTrace("Guest ESP: 0x%x (%u)\n", guest_esp, guest_esp);
+
+ exit_eip=(uint_t)RunVMM;
+
+ PrintTrace("Clear\n");
+ VMCS_CLEAR(vmcs);
+ PrintTrace("Load\n");
+ VMCS_LOAD(vmcs);
+
+
+ PrintTrace("VMCS_LINK_PTR\n");
+ VMCS_WRITE(VMCS_LINK_PTR, &f);
+ PrintTrace("VMCS_LINK_PTR_HIGH\n");
+ VMCS_WRITE(VMCS_LINK_PTR_HIGH, &f);
+
+
+ SetCtrlBitsCorrectly(IA32_VMX_PINBASED_CTLS_MSR, PIN_VM_EXEC_CTRLS);
+ SetCtrlBitsCorrectly(IA32_VMX_PROCBASED_CTLS_MSR, PROC_VM_EXEC_CTRLS);
+ SetCtrlBitsCorrectly(IA32_VMX_EXIT_CTLS_MSR, VM_EXIT_CTRLS);
+ SetCtrlBitsCorrectly(IA32_VMX_ENTRY_CTLS_MSR, VM_ENTRY_CTRLS);
+
+ //
+ //
+ //SetCtrlBitsCorrectly(IA32_something,GUEST_IA32_DEBUGCTL);
+ //SetCtrlBitsCorrectly(IA32_something,GUEST_IA32_DEBUGCTL_HIGH);
+
+
+ /* Host state */
+ PrintTrace("Setting up host state\n");
+ SetCRBitsCorrectly(IA32_VMX_CR0_FIXED0_MSR, IA32_VMX_CR0_FIXED1_MSR, HOST_CR0);
+ SetCRBitsCorrectly(IA32_VMX_CR4_FIXED0_MSR, IA32_VMX_CR4_FIXED1_MSR, HOST_CR4);
+ ret = Init_VMCS_HostState();
+
+ if (ret != VMX_SUCCESS) {
+ if (ret == VMX_FAIL_VALID) {
+ PrintTrace("Init Host state: VMCS FAILED WITH ERROR\n");
+ } else {
+ PrintTrace("Init Host state: Invalid VMCS\n");
+ }
+ return ret;
+ }
+
+ // PrintTrace("HOST_RIP: %x (%u)\n", exit_eip, exit_eip);
+ VMCS_WRITE(HOST_RIP, &exit_eip);
+
+ /* Guest state */
+ PrintTrace("Setting up guest state\n");
+ PrintTrace("GUEST_RIP: %x (%u)\n", entry_eip, entry_eip);
+ VMCS_WRITE(GUEST_RIP,&entry_eip);
+
+ SetCRBitsCorrectly(IA32_VMX_CR0_FIXED0_MSR, IA32_VMX_CR0_FIXED1_MSR, GUEST_CR0);
+ SetCRBitsCorrectly(IA32_VMX_CR4_FIXED0_MSR, IA32_VMX_CR4_FIXED1_MSR, GUEST_CR4);
+ ret = Init_VMCS_GuestState();
+
+ PrintTrace("InitGuestState returned\n");
+ if (ret != VMX_SUCCESS) {
+ if (ret == VMX_FAIL_VALID) {
+ PrintTrace("Init Guest state: VMCS FAILED WITH ERROR\n");
+ } else {
+ PrintTrace("Init Guest state: Invalid VMCS\n");
+ }
+ return ret;
+ }
+ PrintTrace("GUEST_RSP: %x (%u)\n", guest_esp, (uint_t)guest_esp);
+ VMCS_WRITE(GUEST_RSP,&guest_esp);
+
+ // tmpReg = 0x4100;
+ tmpReg = 0xffffffff;
+ if (VMCS_WRITE(EXCEPTION_BITMAP,&tmpReg ) != VMX_SUCCESS) {
+ PrintInfo("Bitmap error\n");
+ }
+
+ ConfigureExits(vm);
+
+ PrintTrace("VMCS_LAUNCH\n");
+
+ vm->state=VM_VMXASSIST_STARTUP;
+
+ vmm_ret = SAFE_VM_LAUNCH();
+
+ PrintTrace("VMM error %d\n", vmm_ret);
+
+ return vmm_ret;
+}
+
+
+
+
+int VMLaunch(struct VMDescriptor *vm)
+{
+ VMCS * vmcs = CreateVMCS();
+ int rc;
+
+ ullong_t vmcs_ptr = (ullong_t)((uint_t)vmcs);
+ uint_t top = (vmcs_ptr>>32)&0xffffffff;
+ uint_t bottom = (vmcs_ptr)&0xffffffff;
+
+ theVM.vmcsregion = vmcs;
+ theVM.descriptor = *vm;
+
+ PrintTrace("vmcs_ptr_top=%x vmcs_ptr_bottom=%x, eip=%x\n", top, bottom, vm->entry_ip);
+ rc=MyLaunch(&theVM); // vmcs_ptr, vm->entry_ip, vm->exit_eip, vm->guest_esp);
+ PrintTrace("Returned from MyLaunch();\n");
+ return rc;
+}
+
+
+VmxOnRegion * CreateVmxOnRegion() {
+ union VMX_MSR basicMSR;
+ VmxOnRegion * region = (VmxOnRegion *)(os_hooks)->allocate_pages(1);
+
+ Get_MSR(IA32_VMX_BASIC_MSR, &basicMSR.regs.high, &basicMSR.regs.low);
+ // memcpy(region, &basicMSR.vmxBasic.revision, sizeof(uint_t));
+
+ *(ulong_t*)region = basicMSR.vmxBasic.revision;
+
+ PrintInfo("VMX revision: 0x%lu\n", *(ulong_t *)region);
+
+ return region;
+}
+
+VMCS * CreateVMCS() {
+ union VMX_MSR basicMSR;
+ VMCS * vmcs = (VMCS *)(os_hooks)->allocate_pages(1);
+
+ Get_MSR(IA32_VMX_BASIC_MSR, &basicMSR.regs.high, &basicMSR.regs.low);
+ *(ulong_t *)vmcs = basicMSR.vmxBasic.revision;
+ *(ulong_t *)((char*)vmcs + 4) = 0;
+
+ PrintTrace("VMCS Region size: %u\n", basicMSR.vmxBasic.regionSize);
+ PrintTrace("VMCS Abort: %x\n",*(uint_t *)(((char*)vmcs)+4));
+
+ return vmcs;
+}
--- /dev/null
+; -*- fundamental -*-
+
+%ifndef VMX_ASM
+%define VMX_ASM
+
+
+%include "defs.asm"
+%include "symbol.asm"
+
+
+%include "vmcs_fields.asm"
+
+VMX_SUCCESS equ 0x00000000
+VMX_FAIL_INVALID equ 0x00000001
+VMX_FAIL_VALID equ 0x00000002
+VMM_ERROR equ 0x00000003
+
+[BITS 32]
+
+IMPORT Do_VMM
+
+
+; VMX Functions
+EXPORT VMCS_READ
+EXPORT VMCS_WRITE
+EXPORT VMCS_CLEAR
+EXPORT VMCS_LOAD
+EXPORT VMCS_STORE
+EXPORT Enable_VMX
+EXPORT Disable_VMX
+EXPORT Launch_VM
+EXPORT VMCS_LAUNCH
+EXPORT VMCS_RESUME
+EXPORT RunVMM
+EXPORT SAFE_VM_LAUNCH
+EXPORT Init_VMCS_HostState
+EXPORT Init_VMCS_GuestState
+
+;
+; Enable_VMX - Turn on VMX
+;
+align 8
+Enable_VMX:
+ push ebp
+ mov ebp, esp
+ push ebx
+ mov ebx, cr4
+ or ebx, dword 0x00002000
+ mov cr4, ebx
+ mov ebx, cr0
+ or ebx, dword 0x80000021
+ mov cr0, ebx
+ vmxon [ebp+8]
+ pop ebx
+ pop ebp
+ mov eax, VMX_SUCCESS
+ jnc .return
+ mov eax, VMX_FAIL_INVALID
+.return
+ ret
+
+
+;
+; VMREAD - read a value from a VMCS
+;
+align 8
+VMCS_READ:
+ push ebp
+ mov ebp, esp
+ push ecx
+ push ebx
+
+ mov ecx, [ebp + 8]
+ mov ebx,[ebp + 12]
+; lea ebx, ebp
+ vmread [ebx], ecx
+
+ pop ebx
+ pop ecx
+ pop ebp
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+;
+; VMWRITE - write a value to a VMCS
+align 8
+VMCS_WRITE:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov eax, [ebp + 8]
+ mov ebx, [ebp + 12]
+ vmwrite eax, [ebx]
+
+ pop ebx
+ pop ebp
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+;
+; VMCLEAR - Initializes a VMCS
+;
+align 8
+VMCS_CLEAR:
+ vmclear [esp+4]
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+
+
+;
+; VMCS_LOAD - load a VMCS
+;
+align 8
+VMCS_LOAD:
+ vmptrld [esp+4]
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+
+
+;
+; VMCS_STORE - Store a VMCS
+;
+align 8
+VMCS_STORE:
+ mov eax, [esp+4]
+ vmptrst [eax]
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+
+;
+; VMCS_LAUNCH
+;
+align 8
+VMCS_LAUNCH:
+ vmlaunch
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+
+
+;
+; VMCS_RESUME
+;
+align 8
+VMCS_RESUME:
+ vmresume
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ ret
+
+align 8
+SAFE_VM_LAUNCH:
+ pushf
+ pusha
+ mov eax, HOST_RSP
+ vmwrite eax, esp
+ jz .esp_err
+ jc .esp_err
+ jmp .vm_cont
+
+.esp_err
+ popa
+ jz .error_code
+ jc .error
+.vm_cont
+ vmlaunch
+ popa
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ popf
+ ret
+
+
+;
+; RunVMM
+;
+align 8
+RunVMM:
+ pusha
+ call Do_VMM
+ and eax, eax
+ jnz .vmm_error
+ jmp .vm_cont
+
+.vmm_error
+ popa
+ popa
+ mov eax, VMM_ERROR
+ jmp .return
+
+.vm_cont
+ popa
+ vmresume
+ popa ; we only get here if there is an error in the vmresume
+ ; we restore the host state and return an error code
+
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ popf
+ ret
+
+
+
+
+;
+; Setup_VMCS_GuestState
+; Copy all of the Guest registers into the guest state of a vmcs
+;
+
+align 8
+InitGuestSelectors:
+ push ebp
+ mov ebp, esp
+ push ebx
+ push ebx
+
+ mov ebx, VMCS_GUEST_ES_SELECTOR
+ mov eax, es
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_GUEST_CS_SELECTOR
+ mov eax, cs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_GUEST_SS_SELECTOR
+ mov eax, ss
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_GUEST_DS_SELECTOR
+ mov eax, ds
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_GUEST_FS_SELECTOR
+ mov eax, fs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_GUEST_GS_SELECTOR
+ mov eax, gs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ str [esp]
+ mov eax, [esp]
+ mov ebx, VMCS_GUEST_TR_SELECTOR
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebx
+ pop ebp
+ ret
+ret
+
+align 8
+InitGuestDescRegs:
+ push ebp
+ mov ebp, esp
+ push ebx
+ sub esp, 6
+
+
+ sgdt [esp]
+ mov eax, [esp]
+ and eax, 0xffff
+ mov ebx, GUEST_GDTR_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, [esp+2]
+ mov ebx, GUEST_GDTR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ sidt [esp]
+ mov eax, [esp]
+ and eax, 0xffff
+ mov ebx, GUEST_IDTR_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, [esp+2]
+ mov ebx, GUEST_IDTR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ sldt [esp]
+ mov eax, [esp]
+ mov ebx, GUEST_LDTR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov eax, 0x00000000
+ mov ebx, GUEST_LDTR_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+
+ add esp, 6
+ pop ebx
+ pop ebp
+ ret
+
+
+
+
+
+align 8
+InitGuestSegBases:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+
+ mov eax, dword 0
+ mov ebx, GUEST_ES_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, GUEST_CS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, GUEST_SS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, GUEST_DS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, GUEST_FS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, GUEST_GS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, dword 0
+ mov eax, 0x000220a0
+ mov ebx, GUEST_TR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+
+ pop ebx
+ pop ebp
+ ret
+
+align 8
+InitGuestSegsAccess:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov eax, 1100000010010011b
+ mov ebx, GUEST_ES_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+
+ mov eax, 1100000010011001b
+; mov eax, 0x0000c099
+ mov ebx, GUEST_CS_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 1100000010010111b
+ mov eax, 1100000010010011b
+ mov ebx, GUEST_SS_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, 1100000010010011b
+ mov ebx, GUEST_DS_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov eax, 1100000010010011b
+ mov ebx, GUEST_FS_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov eax, 1100000010010011b
+ mov ebx, GUEST_GS_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, 0x10000
+ mov ebx, GUEST_LDTR_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, 01000000010001011b
+ mov ebx, GUEST_TR_ACCESS
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+;
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebp
+ ret
+
+;; Do seg limit
+align 8
+InitGuestSegsLimits:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_ES_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_CS_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_SS_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_DS_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_FS_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0xffffffff
+ mov ebx, GUEST_GS_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; mov eax, 0xffffffff
+ mov eax, 0x68fff
+ mov ebx, GUEST_TR_LIMIT
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebp
+ ret
+
+
+align 8
+Init_VMCS_GuestState:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov ebx, GUEST_CR3
+ mov eax, cr3
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ call InitGuestSelectors
+ and eax, 0xffffffff
+ jz .selDone
+ jmp .return
+.selDone
+
+ call InitGuestDescRegs
+ and eax, 0xffffffff
+ jz .descRegsDone
+ jmp .return
+.descRegsDone
+
+ call InitGuestSegBases
+ and eax, 0xffffffff
+ jz .descSegBasesDone
+ jmp .return
+.descSegBasesDone
+
+
+ call InitGuestSegsLimits
+ and eax, 0xffffffff
+ jz .segsLimitsDone
+ jmp .return
+.segsLimitsDone
+
+ call InitGuestSegsAccess
+ and eax, 0xffffffff
+ jz .segsAccessDone
+ jmp .return
+.segsAccessDone
+
+ mov ebx, GUEST_RSP
+ mov eax, esp
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, GUEST_RFLAGS
+ mov eax, dword 0x00000002
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, GUEST_DR7
+ mov eax, dword 0x00000400
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebp
+ ret
+
+;
+; Setup_VMCS_HostState
+; Copy all of the host registers into the host state of a vmcs
+;
+
+align 8
+InitHostSelectors:
+ push ebp
+ mov ebp, esp
+ push ebx
+ push ebx
+
+ mov ebx, VMCS_HOST_ES_SELECTOR
+ mov eax, es
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_HOST_CS_SELECTOR
+ mov eax, cs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_HOST_SS_SELECTOR
+ mov eax, ss
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_HOST_DS_SELECTOR
+ mov eax, ds
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_HOST_FS_SELECTOR
+ mov eax, fs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov ebx, VMCS_HOST_GS_SELECTOR
+ mov eax, gs
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ str [esp]
+ mov eax, [esp]
+ mov ebx, VMCS_HOST_TR_SELECTOR
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebx
+ pop ebp
+ ret
+ret
+
+
+
+
+
+align 8
+InitHostBaseRegs:
+ push ebp
+ mov ebp, esp
+ push ebx
+ sub esp, 6
+
+ sgdt [esp]
+ mov eax, [esp+2]
+ mov ebx, HOST_GDTR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ sidt [esp]
+ mov eax, [esp+2]
+ mov ebx, HOST_IDTR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov eax, dword 0
+ mov ebx, HOST_FS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, HOST_GS_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, dword 0
+ mov ebx, HOST_TR_BASE
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+
+ add esp, 6
+ pop ebx
+ pop ebp
+ ret
+
+
+align 8
+Init_VMCS_HostState:
+ push ebp
+ mov ebp, esp
+ push ebx
+
+ mov ebx, HOST_CR3
+ mov eax, cr3
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+
+ mov ebx, HOST_RSP
+ mov eax, esp
+ vmwrite ebx, eax
+ jz .error_code
+ jc .error
+
+; push esp
+ call InitHostSelectors
+ and eax, 0xffffffff
+ jz .selDone
+ jmp .return
+.selDone
+; push esp
+ call InitHostBaseRegs
+ and eax, 0xffffffff
+ jz .baseRegsDone
+ jmp .return
+.baseRegsDone
+
+
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ mov eax, VMX_FAIL_INVALID
+ jmp .return
+.error_code
+ mov eax, VMX_FAIL_VALID
+.return
+ pop ebx
+ pop ebp
+ ret
+
+;
+; Launch_VM - inits a vmcs with an ip and launches it
+; [eip = ebp + 8], [vmcs = ebp + 12]
+; int Launch_VM(ullont_t VMCS, uint_t eip);
+;
+align 8
+Launch_VM:
+ push ebp
+ mov ebp, esp
+ push ebx
+ mov ebx, dword 0
+ vmclear [ebp+8]
+ jz .error_code
+ jc .error
+ add ebx, dword 1
+ vmptrld [ebp+8]
+ jz .error_code
+ jc .error
+ mov eax, dword 0x0000681E
+ add ebx, dword 1
+ vmwrite eax, [ebp+16]
+ jz .error_code
+ jc .error
+ add ebx, dword 1
+ vmlaunch
+ jz .error_code
+ jc .error
+ mov eax, VMX_SUCCESS
+ jmp .return
+.error
+ shl ebx, 4
+ mov eax, VMX_FAIL_INVALID
+ or eax, ebx
+ jmp .return
+.error_code
+ shl ebx, 4
+ mov eax, VMX_FAIL_VALID
+ or eax, ebx
+ mov ebx, dword 0x00004400
+ vmread eax, ebx
+.return
+ pop ebx
+ pop ebp
+
+ ret
+
+
+%endif