# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.31 $
+# $Revision: 1.32 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
VMM_C_SRCS := vm_guest.c \
- svm.c svm_handler.c vmm.c vmm_util.c svm_ctrl_regs.c \
+ svm.c svm_handler.c vmm.c vmm_util.c vmm_ctrl_regs.c \
vmcb.c vmm_mem.c vmm_paging.c vmm_io.c vmm_debug.c svm_io.c \
vmm_intr.c vmm_irq.c\
vmm_shadow_paging.c vm_guest_mem.c \
/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/palacios/vmm.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_mem.h ../include/palacios/vmm_types.h \
- ../include/palacios/vm_guest.h ../include/palacios/vmm_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/vmm_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.h ../include/geekos/debug.h \
../include/geekos/serial.h ../include/geekos/irq.h \
../include/geekos/int.h ../include/geekos/string.h \
../include/palacios/vmm_util.h ../include/palacios/vmm_types.h \
../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.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_mem.h ../include/palacios/vm_guest.h \
- ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_shadow_paging.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.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/geekos/ktypes.h \
+ ../include/palacios/vm_guest_mem.h ../include/palacios/vmm_emulate.h
+palacios/vmm.o: ../src/palacios/vmm.c ../include/palacios/vmm.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.h \
+ ../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.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_mem.h ../include/palacios/vm_guest.h \
- ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.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_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
- ../include/palacios/vmm_irq.h ../include/palacios/vmcb.h \
- ../include/palacios/vm_guest_mem.h ../include/palacios/vmm_emulate.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_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/vmm_types.h \
- ../include/geekos/ktypes.h \
- /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.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_intr.h \
- ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
../include/palacios/vmm_irq.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/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.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_mem.h ../include/palacios/vm_guest.h \
- ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm_shadow_paging.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.h
-palacios/svm_ctrl_regs.o: ../src/palacios/svm_ctrl_regs.c \
- ../include/palacios/svm_ctrl_regs.h ../include/palacios/vm_guest.h \
+palacios/vmm_ctrl_regs.o: ../src/palacios/vmm_ctrl_regs.c \
../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
+ ../include/palacios/vmm.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_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.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
+ ../include/palacios/vmm_irq.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/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.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_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.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_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
- ../include/palacios/vmm_irq.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_irq.h ../include/palacios/vmm.h
palacios/vmm_mem.o: ../src/palacios/vmm_mem.c ../include/palacios/vmm_mem.h \
../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_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.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_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.h
palacios/vmm_paging.o: ../src/palacios/vmm_paging.c \
../include/palacios/vmm_paging.h ../include/palacios/vmm_types.h \
../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
../include/palacios/vmm_mem.h ../include/palacios/vmm_util.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_string.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm_intr.h ../include/palacios/vmm_dev_mgr.h \
+ ../include/palacios/vmm_list.h ../include/palacios/vmm_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/vmm_intr.h \
- ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
../include/palacios/vmm_irq.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/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.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/palacios/vmm_mem.h \
- ../include/palacios/vm_guest.h ../include/palacios/vmm_shadow_paging.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.h ../include/palacios/vmm_shadow_paging.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
../include/palacios/vmm_irq.h
palacios/vmm_debug.o: ../src/palacios/vmm_debug.c ../include/palacios/vmm_debug.h \
- ../include/palacios/vmm.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/palacios/vm_guest.h \
../include/palacios/vmm_mem.h ../include/palacios/vmm_types.h \
../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.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_io.h ../include/palacios/vmm_util.h \
+ ../include/palacios/vmm_shadow_paging.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_intr.h \
../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.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_irq.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 \
palacios/vmm_intr.o: ../src/palacios/vmm_intr.c ../include/palacios/vmm_intr.h \
../include/palacios/vmm_types.h ../include/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
- ../include/palacios/vmm.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_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.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.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_dev_mgr.h \
- ../include/palacios/vmm_list.h ../include/palacios/vmm_irq.h
+ ../include/palacios/vmm_list.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_irq.h
palacios/vmm_irq.o: ../src/palacios/vmm_irq.c
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/geekos/ktypes.h \
/home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \
../include/palacios/vmm_paging.h ../include/palacios/vmm_mem.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_string.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_io.h ../include/palacios/vmm_intr.h \
+ ../include/palacios/vmm_dev_mgr.h ../include/palacios/vmm_list.h \
+ ../include/palacios/vmm_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_intr.h ../include/palacios/vmm_dev_mgr.h \
- ../include/palacios/vmm_list.h ../include/palacios/vmm_irq.h \
- ../include/palacios/vm_guest_mem.h
+ ../include/palacios/vmm_irq.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_list.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_dev_mgr.h ../include/palacios/vmm.h \
- ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.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_intr.h \
../include/palacios/vmm_list.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_dev_mgr.h ../include/palacios/vmm.h \
- ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.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_intr.h \
../include/palacios/vmm_list.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_dev_mgr.h ../include/palacios/vmm.h \
- ../include/palacios/vmm_mem.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vm_guest.h ../include/palacios/vmm_mem.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_intr.h \
../include/palacios/vmm_list.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_dev_mgr.h ../include/palacios/vmm_intr.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_mem.h \
- ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.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_irq.h
devices/8259a.o: ../src/devices/8259a.c ../include/devices/8259a.h \
../include/palacios/vmm_list.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_dev_mgr.h ../include/palacios/vmm_intr.h \
- ../include/palacios/vmm.h ../include/palacios/vmm_mem.h \
- ../include/palacios/vm_guest.h ../include/palacios/vmm_io.h \
+ ../include/palacios/vmm.h ../include/palacios/vm_guest.h \
+ ../include/palacios/vmm_mem.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_irq.h
#include <palacios/vmm_irq.h>
-typedef ullong_t gpr_t;
-
-/*
- struct guest_gprs {
- addr_t rax;
- addr_t rbx;
- addr_t rcx;
- addr_t rdx;
- addr_t rsi;
- addr_t rdi;
- addr_t rbp;
- };
-*/
-
-struct guest_gprs {
- gpr_t rdi;
- gpr_t rsi;
- gpr_t rbp;
- gpr_t rsp;
- gpr_t rbx;
- gpr_t rdx;
- gpr_t rcx;
- gpr_t rax;
+typedef ullong_t v3_reg_t;
+
+
+
+struct v3_gprs {
+ v3_reg_t rdi;
+ v3_reg_t rsi;
+ v3_reg_t rbp;
+ v3_reg_t rsp;
+ v3_reg_t rbx;
+ v3_reg_t rdx;
+ v3_reg_t rcx;
+ v3_reg_t rax;
+};
+
+
+struct v3_ctrl_regs {
+ v3_reg_t cr0;
+ v3_reg_t cr2;
+ v3_reg_t cr3;
+ v3_reg_t cr4;
+ v3_reg_t cr8;
+ v3_reg_t rflags;
};
+struct v3_segment {
+ ushort_t selector;
+ uint_t limit;
+ ullong_t base;
+ uint_t type : 4;
+ uint_t system : 1;
+ uint_t dpl : 2;
+ uint_t present : 1;
+ uint_t avail : 1;
+ uint_t long_mode : 1;
+ uint_t db : 1;
+ uint_t granularity : 1;
+};
+
+
+struct v3_segments {
+ struct v3_segment cs;
+ struct v3_segment ds;
+ struct v3_segment es;
+ struct v3_segment fs;
+ struct v3_segment gs;
+ struct v3_segment ss;
+ struct v3_segment ldtr;
+ struct v3_segment gdtr;
+ struct v3_segment idtr;
+ struct v3_segment tr;
+};
+
struct shadow_page_state;
struct shadow_map;
vm_cpu_mode_t cpu_mode;
- struct guest_gprs vm_regs;
+ struct v3_gprs vm_regs;
+ struct v3_ctrl_regs ctrl_regs;
+ struct v3_segments segments;
struct vm_ctrl_ops vm_ops;
#define __VMCB_H
#include <palacios/vmm_types.h>
-
+#include <palacios/vm_guest.h>
#define VMCB_CTRL_AREA_OFFSET 0x0
#define VMCB_STATE_SAVE_AREA_OFFSET 0x400
void PrintDebugVMCB(vmcb_t * vmcb);
+void set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
+void get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
+
#endif
#define __VMM_CTRL_REGS_H
+#include <palacios/vm_guest.h>
+
struct cr0_real {
uint_t pe : 1;
uint_t mp : 1;
};
+
+
+
+// First opcode byte
+static const uchar_t cr_access_byte = 0x0f;
+
+// Second opcode byte
+static const uchar_t lmsw_byte = 0x01;
+static const uchar_t lmsw_reg_byte = 0x6;
+static const uchar_t smsw_byte = 0x01;
+static const uchar_t smsw_reg_byte = 0x4;
+static const uchar_t clts_byte = 0x06;
+static const uchar_t mov_to_cr_byte = 0x22;
+static const uchar_t mov_from_cr_byte = 0x20;
+
+
+
+int handle_cr0_write(struct guest_info * info);
+int handle_cr0_read(struct guest_info * info);
+
+int handle_cr3_write(struct guest_info * info);
+int handle_cr3_read(struct guest_info * info);
+
+
#endif
-static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, addr_t seg_base) {
+static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, struct v3_segment * seg) {
switch (info->cpu_mode) {
case REAL:
- return addr + (seg_base << 4);
+ return addr + (seg->selector << 4);
break;
case PROTECTED:
case PROTECTED_PG:
- return addr + seg_base;
+ return addr + seg->base;
break;
default:
return 0;
typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND} operand_type_t;
-struct guest_gprs;
+struct v3_gprs;
-static inline addr_t decode_register(struct guest_gprs * gprs, char reg_code, reg_size_t reg_size) {
+static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
addr_t reg_addr;
switch (reg_code) {
-static inline operand_type_t decode_operands16(struct guest_gprs * gprs, // input/output
+static inline operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
char * modrm_instr, // input
int * offset, // output
addr_t * first_operand, // output
-static inline operand_type_t decode_operands32(struct guest_gprs * gprs, // input/output
+static inline operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
char * modrm_instr, // input
int * offset, // output
addr_t * first_operand, // output
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 void safe_svm_launch(vmcb_t * vmcb_addr, struct v3_gprs * gprs);
extern void STGI();
extern void CLGI();
PrintDebug("RIP: %x\n", guest_state->rip);
- if (info->cpu_mode == REAL) {
- linear_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
- } else {
- linear_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.base);
- }
+
+ linear_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
+
PrintDebug("RIP Linear: %x\n", linear_addr);
#include <palacios/vmm.h>
#include <palacios/vm_guest_mem.h>
#include <palacios/vmm_emulate.h>
-#include <palacios/svm_ctrl_regs.h>
+#include <palacios/vmm_ctrl_regs.h>
#include <palacios/svm_io.h>
#include <palacios/vmm_intr.h>
+
extern struct vmm_os_hooks * os_hooks;
info->vm_regs.rsp = guest_state->rsp;
+ info->ctrl_regs.cr0 = guest_state->cr0;
+ info->ctrl_regs.cr2 = guest_state->cr2;
+ info->ctrl_regs.cr3 = guest_state->cr3;
+ info->ctrl_regs.cr4 = guest_state->cr4;
+ info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
+ info->ctrl_regs.rflags = guest_state->rflags;
+
+ get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
+
+
exit_code = guest_ctrl->exit_code;
PrintDebug("SVM Returned: Exit Code: %x\n",exit_code);
char buf[15];
addr_t host_addr;
- if (info->cpu_mode == REAL) {
- rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
- } else {
- rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.base);
- }
+
+ rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
+
PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data);
}
+ guest_state->cr0 = info->ctrl_regs.cr0;
+ guest_state->cr2 = info->ctrl_regs.cr2;
+ guest_state->cr3 = info->ctrl_regs.cr3;
+ guest_state->cr4 = info->ctrl_regs.cr4;
+ guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
+ guest_state->rflags = info->ctrl_regs.rflags;
+
guest_state->rax = info->vm_regs.rax;
guest_state->rip = info->rip;
guest_state->rsp = info->vm_regs.rsp;
+
+ set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
+
if (exit_code == VMEXIT_INTR) {
PrintDebug("INTR ret IP = %x\n", guest_state->rip);
}
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;
while (rep_num > 0) {
addr_t host_addr;
- dst_addr = get_addr_linear(info, info->vm_regs.rdi & mask, base_addr);
+ dst_addr = get_addr_linear(info, info->vm_regs.rdi & mask, &(info->segments.es));
if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
// either page fault or gpf...
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;
while (rep_num > 0) {
addr_t host_addr;
- dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), base_addr);
+ dst_addr = get_addr_linear(info, (info->vm_regs.rsi & mask), &(info->segments.ds));
if (guest_va_to_host_va(info, dst_addr, &host_addr) == -1) {
// either page fault or gpf...
#include <palacios/vmm_util.h>
+
+void set_vmcb_segment(struct vmcb_selector * vmcb_seg, struct v3_segment * seg) {
+ vmcb_seg->selector = seg->selector;
+ vmcb_seg->limit = seg->limit;
+ vmcb_seg->base = seg->base;
+ vmcb_seg->attrib.fields.type = seg->type;
+ vmcb_seg->attrib.fields.S = seg->system;
+ vmcb_seg->attrib.fields.dpl = seg->dpl;
+ vmcb_seg->attrib.fields.P = seg->present;
+ vmcb_seg->attrib.fields.avl = seg->avail;
+ vmcb_seg->attrib.fields.L = seg->long_mode;
+ vmcb_seg->attrib.fields.db = seg->db;
+ vmcb_seg->attrib.fields.G = seg->granularity;
+}
+
+
+void get_vmcb_segment(struct vmcb_selector * vmcb_seg, struct v3_segment * seg) {
+ seg->selector = vmcb_seg->selector;
+ seg->limit = vmcb_seg->limit;
+ seg->base = vmcb_seg->base;
+ seg->type = vmcb_seg->attrib.fields.type;
+ seg->system = vmcb_seg->attrib.fields.S;
+ seg->dpl = vmcb_seg->attrib.fields.dpl;
+ seg->present = vmcb_seg->attrib.fields.P;
+ seg->avail = vmcb_seg->attrib.fields.avl;
+ seg->long_mode = vmcb_seg->attrib.fields.L;
+ seg->db = vmcb_seg->attrib.fields.db;
+ seg->granularity = vmcb_seg->attrib.fields.G;
+}
+
+
+void set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs) {
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+
+ set_vmcb_segment(&(guest_area->cs), &(segs->cs));
+ set_vmcb_segment(&(guest_area->ds), &(segs->ds));
+ set_vmcb_segment(&(guest_area->es), &(segs->es));
+ set_vmcb_segment(&(guest_area->fs), &(segs->fs));
+ set_vmcb_segment(&(guest_area->gs), &(segs->gs));
+ set_vmcb_segment(&(guest_area->ss), &(segs->ss));
+ set_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
+ set_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
+ set_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
+ set_vmcb_segment(&(guest_area->tr), &(segs->tr));
+}
+
+
+void get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs) {
+ vmcb_saved_state_t * guest_area = GET_VMCB_SAVE_STATE_AREA(vmcb);
+
+ get_vmcb_segment(&(guest_area->cs), &(segs->cs));
+ get_vmcb_segment(&(guest_area->ds), &(segs->ds));
+ get_vmcb_segment(&(guest_area->es), &(segs->es));
+ get_vmcb_segment(&(guest_area->fs), &(segs->fs));
+ get_vmcb_segment(&(guest_area->gs), &(segs->gs));
+ get_vmcb_segment(&(guest_area->ss), &(segs->ss));
+ get_vmcb_segment(&(guest_area->ldtr), &(segs->ldtr));
+ get_vmcb_segment(&(guest_area->gdtr), &(segs->gdtr));
+ get_vmcb_segment(&(guest_area->idtr), &(segs->idtr));
+ get_vmcb_segment(&(guest_area->tr), &(segs->tr));
+}
+
+
void PrintDebugVMCB(vmcb_t * vmcb) {
reg_ex_t tmp_reg;
--- /dev/null
+#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) {
+ 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, info->rip, &(info->segments.cs)), 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 *real_cr0;
+ struct cr0_real *new_cr0;
+ operand_type_t addr_type;
+ char new_cr0_val = 0;
+ // LMSW
+ // decode mod/RM
+ index += 2;
+
+ real_cr0 = (struct cr0_real*)&(info->ctrl_regs.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 + (info->segments.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) && (real_cr0->pe == 0)) {
+ info->cpu_mode = PROTECTED;
+ } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
+ info->cpu_mode = REAL;
+ }
+
+ new_cr0_val = *(char*)(new_cr0) & 0x0f;
+
+
+ if (info->page_mode == SHADOW_PAGING) {
+ struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
+
+ PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
+ /* struct cr0_real is only 4 bits wide,
+ * so we can overwrite the real_cr0 without worrying about the shadow fields
+ */
+ *(char*)real_cr0 &= 0xf0;
+ *(char*)real_cr0 |= new_cr0_val;
+
+ *(char*)shadow_cr0 &= 0xf0;
+ *(char*)shadow_cr0 |= new_cr0_val;
+
+ PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
+ } else {
+ PrintDebug("Old CR0=%x\n", *real_cr0);
+ // for now we just pass through....
+ *(char*)real_cr0 &= 0xf0;
+ *(char*)real_cr0 |= new_cr0_val;
+
+ PrintDebug("New CR0=%x\n", *real_cr0);
+ }
+
+
+ info->rip += index;
+
+ } else if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] == clts_byte)) {
+ // CLTS
+
+
+ } else if ((instr[index] == cr_access_byte) &&
+ (instr[index + 1] = mov_to_cr_byte)) {
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr0_32 *real_cr0;
+ struct cr0_32 *new_cr0;
+ operand_type_t addr_type;
+
+
+ index += 2;
+
+ real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
+
+ addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ if (addr_type != REG_OPERAND) {
+ /* Mov to CR0 Can only be a 32 bit register */
+ // FIX ME
+ return -1;
+ }
+
+ new_cr0 = (struct cr0_32 *)first_operand;
+
+ if (new_cr0->pe == 1) {
+ PrintDebug("Entering Protected Mode\n");
+ info->cpu_mode = PROTECTED;
+ }
+
+ if (new_cr0->pg == 1) {
+ // GPF the guest??
+ return -1;
+ }
+
+ if (info->page_mode == SHADOW_PAGING) {
+ struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+
+ PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
+ *real_cr0 = *new_cr0;
+ real_cr0->pg = 1;
+
+ *shadow_cr0 = *new_cr0;
+
+ PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
+ } else {
+ PrintDebug("Old CR0=%x\n", *real_cr0);
+ *real_cr0 = *new_cr0;
+ PrintDebug("New CR0=%x\n", *real_cr0);
+ }
+
+ info->rip += index;
+
+ } else {
+ PrintDebug("Unsupported Instruction\n");
+ // 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, info->rip, &(info->segments.cs)), 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] == mov_to_cr_byte)) {
+
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr0_32 *real_cr0;
+ struct cr0_32 *new_cr0;
+ operand_type_t addr_type;
+
+ index += 2;
+
+ real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
+
+ addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ if (addr_type != REG_OPERAND) {
+ return -1;
+ }
+
+ new_cr0 = (struct cr0_32 *)first_operand;
+
+
+ if (info->page_mode == SHADOW_PAGING) {
+ struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+
+ if (new_cr0->pg == 1){
+ struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
+
+ info->cpu_mode = PROTECTED_PG;
+
+ *shadow_cr0 = *new_cr0;
+ *real_cr0 = *new_cr0;
+
+ //
+ // Activate Shadow Paging
+ //
+ PrintDebug("Turning on paging in the guest\n");
+
+ info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
+
+
+ } else if (new_cr0->pe == 0) {
+ info->cpu_mode = REAL;
+
+ *shadow_cr0 = *new_cr0;
+ *real_cr0 = *new_cr0;
+ real_cr0->pg = 1;
+ }
+
+
+ } else {
+ *real_cr0 = *new_cr0;
+ }
+
+ info->rip += index;
+ }
+
+ } else {
+ PrintDebug("Unknown Mode write to CR0\n");
+ return -1;
+ }
+ return 0;
+}
+
+
+int handle_cr0_read(struct guest_info * info) {
+ 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, info->rip, &(info->segments.cs)), 15, instr);
+ if (ret != 15) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read Real Mode 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*)&(info->ctrl_regs.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 + (info->segments.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;
+
+ 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] == mov_from_cr_byte)) {
+ /* Mov from CR0
+ * This can only take a 32 bit register argument in anything less than 64 bit mode.
+ */
+ addr_t first_operand;
+ addr_t second_operand;
+ operand_type_t addr_type;
+
+ struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+
+ index += 2;
+
+ addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
+
+ if (addr_type != REG_OPERAND) {
+ // invalid opcode to guest
+ PrintDebug("Invalid operand type in mov from CR0\n");
+ return -1;
+ }
+
+ if (info->page_mode == SHADOW_PAGING) {
+ *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ } else {
+ *virt_cr0 = *real_cr0;
+ }
+
+ info->rip += index;
+
+ } else {
+ PrintDebug("Unknown read instr from CR0\n");
+ return -1;
+ }
+
+ } 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, info->rip, &(info->segments.cs)), 15, instr);
+ if (ret != 15) {
+ // I think we should inject a GPF into the guest
+ PrintDebug("Could not read Proteced mode instruction (ret=%d)\n", ret);
+ return -1;
+ }
+
+ while (is_prefix_byte(instr[index])) {
+ index++;
+ }
+
+
+ if ((instr[index] == cr_access_byte) &&
+ (instr[index+1] == mov_from_cr_byte)) {
+ addr_t first_operand;
+ addr_t second_operand;
+ operand_type_t addr_type;
+ struct cr0_32 * virt_cr0;
+ struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+
+ index += 2;
+
+ addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ if (addr_type != REG_OPERAND) {
+ PrintDebug("Invalid operand type in mov from CR0\n");
+ return -1;
+ }
+
+ virt_cr0 = (struct cr0_32 *)first_operand;
+
+ if (info->page_mode == SHADOW_PAGING) {
+ *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ } else {
+ *virt_cr0 = *real_cr0;
+ }
+
+ info->rip += index;
+
+ } else {
+ PrintDebug("Unknown read instruction from CR0\n");
+ return -1;
+ }
+
+ } else {
+ PrintDebug("Unknown mode read from CR0\n");
+ return -1;
+ }
+
+
+ return 0;
+}
+
+
+
+
+int handle_cr3_write(struct guest_info * info) {
+ if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+ int index = 0;
+ int ret;
+ char instr[15];
+
+ ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ if (ret != 15) {
+ 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] == mov_to_cr_byte)) {
+
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr3_32 * new_cr3;
+ // struct cr3_32 * real_cr3;
+ operand_type_t addr_type;
+
+ index += 2;
+
+ addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ if (addr_type != REG_OPERAND) {
+ /* Mov to CR3 can only be a 32 bit register */
+ return -1;
+ }
+
+ new_cr3 = (struct cr3_32 *)first_operand;
+
+ if (info->page_mode == SHADOW_PAGING) {
+ addr_t shadow_pt;
+ struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
+ struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
+
+
+ *guest_cr3 = *new_cr3;
+
+ // Something like this
+ shadow_pt = create_new_shadow_pt32(info);
+ //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
+
+ /* Copy Various flags */
+ *shadow_cr3 = *new_cr3;
+
+ shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
+
+ if (info->cpu_mode == PROTECTED_PG) {
+ // If we aren't in paged mode then we have to preserve the identity mapped CR3
+ info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
+ }
+ }
+
+ info->rip += index;
+
+ } else {
+ PrintDebug("Unknown Instruction\n");
+ return -1;
+ }
+ } else {
+ PrintDebug("Invalid operating Mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
+int handle_cr3_read(struct guest_info * info) {
+ if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+ int index = 0;
+ int ret;
+ char instr[15];
+
+ ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ if (ret != 15) {
+ 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] == mov_from_cr_byte)) {
+ addr_t first_operand;
+ addr_t second_operand;
+ struct cr3_32 * virt_cr3;
+ struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
+ operand_type_t addr_type;
+
+ index += 2;
+
+ addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
+
+ if (addr_type != REG_OPERAND) {
+ /* Mov to CR3 can only be a 32 bit register */
+ return -1;
+ }
+
+ virt_cr3 = (struct cr3_32 *)first_operand;
+
+ if (info->page_mode == SHADOW_PAGING) {
+ *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
+ } else {
+ *virt_cr3 = *real_cr3;
+ }
+
+ info->rip += index;
+ } else {
+ PrintDebug("Unknown Instruction\n");
+ return -1;
+ }
+ } else {
+ PrintDebug("Invalid operating Mode\n");
+ return -1;
+ }
+
+ return 0;
+}
return -1;
}
-
shadow_pte_access = can_access_pte32(shadow_pte, fault_addr, error_code);
if (shadow_pte_access == PT_ENTRY_NOT_PRESENT) {
shadow_pte_entry->present = guest_pte_entry->present;
shadow_pte_entry->user_page = guest_pte_entry->user_page;
-
+
//set according to VMM policy
shadow_pte_entry->write_through = 0;
shadow_pte_entry->cache_disable = 0;
//
// Page Table Entry marked non-user
//
-
+
PrintDebug("Shadow Paging User access error\n");
return -1;
} else if (shadow_pte_access == PT_ACCESS_OK) {
return -1;
}
-
return 0;
}