From: Jack Lange Date: Wed, 14 May 2008 19:54:08 +0000 (+0000) Subject: architecture independence work X-Git-Tag: CUTPOINT_BEFORE_FULL_EMULATION~4 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=eb87f60800c8634e37d1f8e71cd8f88605f2a46e architecture independence work --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index 0b13303..861ca0b 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -1,6 +1,6 @@ # Makefile for GeekOS kernel, userspace, and tools # Copyright (c) 2004,2005 David H. Hovemeyer -# $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". @@ -122,7 +122,7 @@ 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 \ + 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 \ diff --git a/palacios/build/depend.mak b/palacios/build/depend.mak index a13f5be..7f12c48 100644 --- a/palacios/build/depend.mak +++ b/palacios/build/depend.mak @@ -275,13 +275,13 @@ geekos/vm.o: ../src/geekos/vm.c ../include/geekos/vmm_stubs.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/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 \ @@ -334,118 +334,108 @@ palacios/svm.o: ../src/palacios/svm.c ../include/palacios/svm.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 \ @@ -463,25 +453,25 @@ palacios/svm_io.o: ../src/palacios/svm_io.c ../include/palacios/svm_io.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 \ @@ -500,7 +490,7 @@ palacios/vm_dev.o: ../src/palacios/vm_dev.c ../include/palacios/vm_dev.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 \ @@ -522,7 +512,7 @@ devices/nvram.o: ../src/devices/nvram.c ../include/devices/nvram.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 \ @@ -534,7 +524,7 @@ devices/timer.o: ../src/devices/timer.c ../include/devices/timer.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 \ @@ -546,8 +536,8 @@ devices/simple_pic.o: ../src/devices/simple_pic.c ../include/devices/simple_pic. ../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 \ @@ -557,7 +547,7 @@ 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 diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 56245ef..13be2f0 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -13,32 +13,60 @@ #include -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; @@ -79,7 +107,9 @@ struct guest_info { 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; diff --git a/palacios/include/palacios/vmcb.h b/palacios/include/palacios/vmcb.h index cfbeb8b..fda2847 100644 --- a/palacios/include/palacios/vmcb.h +++ b/palacios/include/palacios/vmcb.h @@ -2,7 +2,7 @@ #define __VMCB_H #include - +#include #define VMCB_CTRL_AREA_OFFSET 0x0 #define VMCB_STATE_SAVE_AREA_OFFSET 0x400 @@ -357,4 +357,7 @@ typedef struct VMCB_State_Save_Area { 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 diff --git a/palacios/include/palacios/vmm_ctrl_regs.h b/palacios/include/palacios/vmm_ctrl_regs.h index 0bebdbc..1849092 100644 --- a/palacios/include/palacios/vmm_ctrl_regs.h +++ b/palacios/include/palacios/vmm_ctrl_regs.h @@ -2,6 +2,8 @@ #define __VMM_CTRL_REGS_H +#include + struct cr0_real { uint_t pe : 1; uint_t mp : 1; @@ -144,4 +146,28 @@ struct rflags { }; + + + +// 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 diff --git a/palacios/include/palacios/vmm_emulate.h b/palacios/include/palacios/vmm_emulate.h index ea24d25..fb1436b 100644 --- a/palacios/include/palacios/vmm_emulate.h +++ b/palacios/include/palacios/vmm_emulate.h @@ -122,14 +122,14 @@ static inline int is_prefix_byte(char byte) { -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; @@ -141,9 +141,9 @@ typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t 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) { @@ -197,7 +197,7 @@ static inline addr_t decode_register(struct guest_gprs * gprs, char reg_code, re -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 @@ -286,7 +286,7 @@ static inline operand_type_t decode_operands16(struct guest_gprs * gprs, // inpu -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 diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index a95efa4..9983b08 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -19,7 +19,7 @@ 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 void safe_svm_launch(vmcb_t * vmcb_addr, struct v3_gprs * gprs); extern void STGI(); extern void CLGI(); @@ -163,11 +163,9 @@ int start_svm_guest(struct guest_info *info) { 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); diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 6f58b7c..fed3d25 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -2,10 +2,11 @@ #include #include #include -#include +#include #include #include + extern struct vmm_os_hooks * os_hooks; @@ -25,6 +26,16 @@ int handle_svm_exit(struct guest_info * info) { 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); @@ -120,11 +131,9 @@ int handle_svm_exit(struct guest_info * info) { 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); @@ -204,11 +213,21 @@ int handle_svm_exit(struct guest_info * info) { } + 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); } diff --git a/palacios/src/palacios/svm_io.c b/palacios/src/palacios/svm_io.c index 4706817..a4208f4 100644 --- a/palacios/src/palacios/svm_io.c +++ b/palacios/src/palacios/svm_io.c @@ -57,7 +57,7 @@ int handle_svm_io_ins(struct guest_info * info) { 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; @@ -110,7 +110,7 @@ int handle_svm_io_ins(struct guest_info * info) { 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... @@ -185,7 +185,7 @@ int handle_svm_io_outs(struct guest_info * info) { 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; @@ -237,7 +237,7 @@ int handle_svm_io_outs(struct guest_info * info) { 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... diff --git a/palacios/src/palacios/vmcb.c b/palacios/src/palacios/vmcb.c index f317088..d1754ae 100644 --- a/palacios/src/palacios/vmcb.c +++ b/palacios/src/palacios/vmcb.c @@ -3,6 +3,69 @@ #include + +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; diff --git a/palacios/src/palacios/vmm_ctrl_regs.c b/palacios/src/palacios/vmm_ctrl_regs.c new file mode 100644 index 0000000..d134043 --- /dev/null +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@ -0,0 +1,536 @@ +#include +#include +#include +#include +#include +#include + + +/* 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; +} diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index 3454039..70a2c77 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -160,7 +160,6 @@ int handle_shadow_pte32_fault(struct guest_info* info, return -1; } - shadow_pte_access = can_access_pte32(shadow_pte, fault_addr, error_code); if (shadow_pte_access == PT_ENTRY_NOT_PRESENT) { @@ -185,7 +184,7 @@ int handle_shadow_pte32_fault(struct guest_info* info, 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; @@ -216,7 +215,7 @@ int handle_shadow_pte32_fault(struct guest_info* info, // // Page Table Entry marked non-user // - + PrintDebug("Shadow Paging User access error\n"); return -1; } else if (shadow_pte_access == PT_ACCESS_OK) { @@ -228,7 +227,6 @@ int handle_shadow_pte32_fault(struct guest_info* info, return -1; } - return 0; }