Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel' into ide
Jack Lange [Tue, 31 Mar 2009 20:42:42 +0000 (15:42 -0500)]
Conflicts:
misc/test_vm/build/Makefile
palacios/build/Makefile

30 files changed:
build/Makefile
misc/test_vm/build/Makefile
palacios/build/Makefile
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_direct_paging.h
palacios/include/palacios/vmm_excp.h [new file with mode: 0644]
palacios/include/palacios/vmm_intr.h
palacios/src/devices/apic.c
palacios/src/devices/cdrom.c
palacios/src/devices/generic.c
palacios/src/devices/ramdisk.c
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vm_guest_mem.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_ctrl_regs.c
palacios/src/palacios/vmm_direct_paging.c
palacios/src/palacios/vmm_direct_paging_32.h
palacios/src/palacios/vmm_direct_paging_32pae.h
palacios/src/palacios/vmm_direct_paging_64.h
palacios/src/palacios/vmm_emulator.c
palacios/src/palacios/vmm_excp.c [new file with mode: 0644]
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_profiler.c
palacios/src/palacios/vmm_xed.c
palacios/src/vmboot/rombios/BIOS-bochs-latest [new file with mode: 0644]
palacios/src/vmboot/vgabios/VGABIOS-lgpl-latest.bin [new file with mode: 0644]

index aecdd92..fb57c3e 100644 (file)
@@ -51,6 +51,14 @@ DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_SHADOW_PAGING=0
 endif
 endif
 
+ifeq ($(DEBUG_NESTED_PAGING),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_NESTED_PAGING=1
+else 
+ifeq ($(DEBUG_NESTED_PAGING),0) 
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_NESTED_PAGING=0
+endif
+endif
+
 ifeq ($(DEBUG_CTRL_REGS),1)
 DEBUG_SECTIONS := $(DEBUG_SECTIONS) DEBUG_CTRL_REGS=1
 else 
index 47bd48e..c38b9f4 100644 (file)
@@ -38,14 +38,15 @@ KERNEL_ENTRY = $(SYM_PFX)Main
 PROJECT_ROOT := ..
 VPATH := $(PROJECT_ROOT)/src
 
-#when -DNDEBUG is set the kassert functions are disabled
-#JRLDEBUG=-DNDEBUG
+
+
 ifeq ($(SERIAL_DEBUG), 1)
 JRLDEBUG= -DDEBUG_SERIAL
 else 
 JRLDEBUG= 
 endif
 
+
 # Figure out if we're compiling with cygwin, http://cygwin.com
 SYSTEM_NAME := $(shell uname -s)
 ifeq ($(findstring CYGWIN,$(SYSTEM_NAME)),CYGWIN)
@@ -178,6 +179,7 @@ NUMSECS := $(PERL) $(PROJECT_ROOT)/scripts/numsecs
 # ----------------------------------------------------------------------
 
 # Flags used for all C source files
+
 GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(JRLDEBUG)
 CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror 
 
index 6d62c0b..f243949 100644 (file)
@@ -62,7 +62,7 @@ endif
 
 
 ifeq ($(DEBUG_ALL),1)
-  DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR  -DDEBUG_XED -DDEBUG_HALT -DDEBUG_DEV_MGR
+  DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_NESTED_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR  -DDEBUG_XED -DDEBUG_HALT -DDEBUG_DEV_MGR
 # -DDEBUG_IO -DDEBUG_GENERIC -DDEBUG_IDE
 endif
 
@@ -73,6 +73,14 @@ else
 ifeq ($(DEBUG_SHADOW_PAGING),0) 
 DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_SHADOW_PAGING
 endif
+
+endif
+ifeq ($(DEBUG_NESTED_PAGING),1)
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -DDEBUG_NESTED_PAGING
+else 
+ifeq ($(DEBUG_NESTED_PAGING),0) 
+DEBUG_SECTIONS := $(DEBUG_SECTIONS) -UDEBUG_NESTED_PAGING
+endif
 endif
 
 ifeq ($(DEBUG_CTRL_REGS),1)
@@ -263,6 +271,7 @@ VMM_OBJS := \
        palacios/vmm_debug.o \
        palacios/svm_io.o \
        palacios/vmm_intr.o \
+       palacios/vmm_excp.o \
        palacios/vmm_time.o \
        palacios/vmm_shadow_paging.o \
        palacios/vm_guest_mem.o \
@@ -522,13 +531,7 @@ vgabios_link:
        ln -s -f ../src/vmboot/vgabios/VGABIOS-lgpl-latest.bin vgabios
 
 
-force_rombios: rombios_link
-       (cd ../src/vmboot/rombios; make clean; make)
-
-force_vgabios: vgabios_link
-       (cd ../src/vmboot/vgabios; make clean; make)
-
-force_payload: force_rombios force_vgabios
+force_payload: rombios_link vgabios_link
        ../scripts/make_payload.pl payload_layout.txt vm_kernel
 
 inter1: force_payload
index 23329eb..005d32b 100644 (file)
@@ -27,6 +27,7 @@
 #include <palacios/vmm_io.h>
 #include <palacios/vmm_shadow_paging.h>
 #include <palacios/vmm_intr.h>
+#include <palacios/vmm_excp.h>
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_time.h>
 #include <palacios/vmm_host_events.h>
@@ -135,6 +136,9 @@ struct guest_info {
     // This structure is how we get interrupts for the guest
     struct v3_intr_state intr_state;
 
+    // This structure is how we get exceptions for the guest
+    struct v3_excp_state excp_state;
+
     v3_io_map_t io_map;
 
     struct v3_msr_map msr_map;
index 9e9f812..4a4ed79 100644 (file)
@@ -273,6 +273,7 @@ struct v3_vm_config {
 
 
     int enable_profiling;
+    int enable_nested_paging;
 
     int use_ramdisk;
     void * ramdisk;
index 3bae7e3..22843fd 100644 (file)
@@ -29,6 +29,7 @@
 addr_t v3_create_direct_passthrough_pts(struct guest_info * guest_info);
 
 int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
+int v3_handle_nested_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
 
 #endif // ! __V3VEE__
 
diff --git a/palacios/include/palacios/vmm_excp.h b/palacios/include/palacios/vmm_excp.h
new file mode 100644 (file)
index 0000000..9e15e32
--- /dev/null
@@ -0,0 +1,74 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VMM_EXCP_H__
+#define __VMM_EXCP_H__
+
+#ifdef __V3VEE__
+
+
+#include <palacios/vmm_types.h>
+
+#define DE_EXCEPTION          0x00  
+#define DB_EXCEPTION          0x01
+#define NMI_EXCEPTION         0x02
+#define BP_EXCEPTION          0x03
+#define OF_EXCEPTION          0x04
+#define BR_EXCEPTION          0x05
+#define UD_EXCEPTION          0x06
+#define NM_EXCEPTION          0x07
+#define DF_EXCEPTION          0x08
+#define TS_EXCEPTION          0x0a
+#define NP_EXCEPTION          0x0b
+#define SS_EXCEPTION          0x0c
+#define GPF_EXCEPTION         0x0d
+#define PF_EXCEPTION          0x0e
+#define MF_EXCEPTION          0x10
+#define AC_EXCEPTION          0x11
+#define MC_EXCEPTION          0x12
+#define XF_EXCEPTION          0x13
+#define SX_EXCEPTION          0x1e
+
+
+struct guest_info;
+
+struct v3_excp_state {
+
+    /* We need to rework the exception state, to handle stacking */
+    uint_t excp_pending;
+    uint_t excp_num;
+    uint_t excp_error_code_valid : 1;
+    uint_t excp_error_code;
+    
+};
+
+
+void v3_init_exception_state(struct guest_info * info);
+
+
+int v3_raise_exception(struct guest_info * info, uint_t excp);
+int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code);
+
+int v3_excp_pending(struct guest_info * info);
+int v3_get_excp_number(struct guest_info * info);
+int v3_injecting_excp(struct guest_info * info, uint_t excp);
+
+#endif 
+
+#endif
index be407c1..82de275 100644 (file)
 #include <palacios/vmm_types.h>
 #include <palacios/vmm_list.h>
 
-#define DE_EXCEPTION          0x00  
-#define DB_EXCEPTION          0x01
-#define NMI_EXCEPTION         0x02
-#define BP_EXCEPTION          0x03
-#define OF_EXCEPTION          0x04
-#define BR_EXCEPTION          0x05
-#define UD_EXCEPTION          0x06
-#define NM_EXCEPTION          0x07
-#define DF_EXCEPTION          0x08
-#define TS_EXCEPTION          0x0a
-#define NP_EXCEPTION          0x0b
-#define SS_EXCEPTION          0x0c
-#define GPF_EXCEPTION         0x0d
-#define PF_EXCEPTION          0x0e
-#define MF_EXCEPTION          0x10
-#define AC_EXCEPTION          0x11
-#define MC_EXCEPTION          0x12
-#define XF_EXCEPTION          0x13
-#define SX_EXCEPTION          0x1e
-
-
-typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t;
+
+
+typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t;
 
 struct guest_info;
 struct v3_interrupt;
@@ -65,15 +46,8 @@ struct v3_irq_hook {
 
 struct v3_intr_state {
 
-    /* We need to rework the exception state, to handle stacking */
-    uint_t excp_pending;
-    uint_t excp_num;
-    uint_t excp_error_code_valid : 1;
-    uint_t excp_error_code;
-  
     struct list_head controller_list;
 
-
     uint_t irq_pending;
     uint_t irq_vector;
 
@@ -102,12 +76,8 @@ struct intr_ctrl_ops {
 
 
 
-
 void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
 
-int v3_raise_exception(struct guest_info * info, uint_t excp);
-int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code);
-
 int v3_intr_pending(struct guest_info * info);
 uint_t v3_get_intr_number(struct guest_info * info);
 intr_type_t v3_get_intr_type(struct guest_info * info);
index 13ead3c..92e6683 100644 (file)
@@ -168,6 +168,7 @@ struct apic_state {
     uint32_t tmr_init_cnt;
 
 
+    struct local_vec_tbl_reg ext_intr_vec_tbl[4];
 
     uint32_t rem_rd_data;
 
@@ -223,6 +224,7 @@ static void init_apic_state(struct apic_state * apic) {
     apic->lint1_vec_tbl.val = 0x00010000;
     apic->err_vec_tbl.val = 0x00010000;
     apic->tmr_div_cfg.val = 0x00000000;
+    //apic->ext_apic_feature.val = 0x00000007;
     apic->ext_apic_feature.val = 0x00040007;
     apic->ext_apic_ctrl.val = 0x00000000;
     apic->spec_eoi.val = 0x00000000;
@@ -337,12 +339,12 @@ static int apic_do_eoi(struct apic_state * apic) {
 
 #ifdef CRAY_XT
        
-       if ((((i * 8) + j) == 238) || 
-           (((i * 8) + j) == 239)) {
-           PrintError("Acking IRQ %d\n", ((i * 8) + j));
+       if ((isr_irq == 238) || 
+           (isr_irq == 239)) {
+           PrintError("Acking IRQ %d\n", isr_irq);
        }
        
-       if (((i * 8) + j) == 238) {
+       if (isr_irq == 238) {
            V3_ACK_IRQ(238);
        }
 #endif
@@ -618,9 +620,19 @@ static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_d
 
            // Unhandled Registers
        case EXT_INT_LOC_VEC_TBL_OFFSET0:
+           val = apic->ext_intr_vec_tbl[0].val;
+           break;
        case EXT_INT_LOC_VEC_TBL_OFFSET1:
+           val = apic->ext_intr_vec_tbl[1].val;
+           break;
        case EXT_INT_LOC_VEC_TBL_OFFSET2:
+           val = apic->ext_intr_vec_tbl[2].val;
+           break;
        case EXT_INT_LOC_VEC_TBL_OFFSET3:
+           val = apic->ext_intr_vec_tbl[3].val;
+           break;
+    
+
        case EXT_APIC_FEATURE_OFFSET:
        case EXT_APIC_CMD_OFFSET:
        case SEOI_OFFSET:
@@ -791,7 +803,20 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
        case IER_OFFSET7:
            *(uint32_t *)(apic->int_en_reg + 28) = op_val;
            break;
-   
+
+       case EXT_INT_LOC_VEC_TBL_OFFSET0:
+           apic->ext_intr_vec_tbl[0].val = op_val;
+           break;
+       case EXT_INT_LOC_VEC_TBL_OFFSET1:
+           apic->ext_intr_vec_tbl[1].val = op_val;
+           break;
+       case EXT_INT_LOC_VEC_TBL_OFFSET2:
+           apic->ext_intr_vec_tbl[2].val = op_val;
+           break;
+       case EXT_INT_LOC_VEC_TBL_OFFSET3:
+           apic->ext_intr_vec_tbl[3].val = op_val;
+           break;
+
 
            // Action Registers
        case EOI_OFFSET:
@@ -802,10 +827,7 @@ static int apic_write(addr_t guest_addr, void * src, uint_t length, void * priv_
        case INT_CMD_LO_OFFSET:
        case INT_CMD_HI_OFFSET:
            // Unhandled Registers
-       case EXT_INT_LOC_VEC_TBL_OFFSET0:
-       case EXT_INT_LOC_VEC_TBL_OFFSET1:
-       case EXT_INT_LOC_VEC_TBL_OFFSET2:
-       case EXT_INT_LOC_VEC_TBL_OFFSET3:
+
        case EXT_APIC_CMD_OFFSET:
        case SEOI_OFFSET:
        default:
index b46a361..43dafd8 100644 (file)
@@ -77,14 +77,14 @@ static rd_bool cdrom_read_toc(void * private_data, uint8_t* buf, int* length, rd
 static uint32_t cdrom_capacity(void * private_data) {
     struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
 
-    PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes);
+    PrintDebug("[cdrom_capacity] s_ramdiskSize = %lu\n", cdrom->capacity_in_bytes);
 
     if (cdrom->lba) {
        if (cdrom->capacity_in_bytes % 2048) {
-           PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1);
+           PrintDebug("\t\t capacity in LBA is %lu\n", (cdrom->capacity_in_bytes / 2048) + 1);
            return (cdrom->capacity_in_bytes / 2048) + 1;
        } else {
-           PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048);
+           PrintDebug("\t\t capacity in LBA is %lu\n", cdrom->capacity_in_bytes / 2048);
            return cdrom->capacity_in_bytes / 2048;
        }
     } else {
@@ -102,7 +102,7 @@ static void cdrom_read_block(void * private_data, uint8_t * buf, int lba)/* __at
 
     V3_ASSERT(lba != 0);
   
-    PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr);
+    PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%p)\n", lba, (void*)cdrom->image_addr);
     memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048);
     //PrintDebug("Returning from read block\n");
     return;
@@ -139,7 +139,7 @@ static struct cdrom_ops cd_ops = {
 static int cdrom_device_init(struct vm_device * dev) {
     struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data;
     PrintDebug("[cdrom_init]\n");
-    PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr);
+    PrintDebug("CDIMAGE located at: %p\n", (void *)cdrom->image_addr);
 
     //FIXME:lba
     cdrom->lba = 1; 
index cc26934..cc9cc69 100644 (file)
@@ -220,7 +220,7 @@ static int generic_init_device(struct vm_device * dev) {
        list_for_each_entry(tmp, &(state->port_list), range_link) {
            uint_t i = 0;
       
-           PrintDebug("generic: hooking ports 0x%x to 0x%x as %x\n", 
+           PrintDebug("generic: hooking ports 0x%x to 0x%x as %s\n", 
                       tmp->start, tmp->end, 
                       (tmp->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
       
@@ -251,12 +251,12 @@ static int generic_init_device(struct vm_device * dev) {
 
        list_for_each_entry(tmp, &(state->mem_list), range_link) {
 
-           PrintDebug("generic: hooking addresses 0x%x to 0x%x\n", 
+           PrintDebug("generic: hooking addresses 0x%p to 0x%p\n", 
                       tmp->start, tmp->end); 
       
       
            if (v3_dev_hook_mem(dev, tmp->start, tmp->end)) {
-               PrintDebug("generic: Can't hook addresses 0x%x to 0x%x (already hooked?)\n",
+               PrintDebug("generic: Can't hook addresses 0x%p to 0x%p (already hooked?)\n",
                           tmp->start, tmp->end); 
            }
        }
@@ -331,11 +331,11 @@ static int generic_deinit_device(struct vm_device * dev) {
     
        list_for_each_entry_safe(cur, tmp, &(state->mem_list), range_link) {
 
-           PrintDebug("generic: unhooking addresses 0x%x to 0x%x\n",
+           PrintDebug("generic: unhooking addresses 0x%p to 0x%p\n",
                       cur->start, cur->end); 
 
            if (v3_dev_unhook_mem(dev, cur->start, cur->end)) {
-               PrintDebug("generic: Can't unhook addresses 0x%x to 0x%x (already unhooked?)\n",
+               PrintDebug("generic: Can't unhook addresses 0x%p to 0x%p (already unhooked?)\n",
                           cur->start, cur->end); 
            }
 
@@ -404,7 +404,7 @@ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end,
        range->type = type;
     
       
-       PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %x\n", 
+       PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %s\n", 
                   range->start, range->end, 
                   (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
     
index c7668de..04602f7 100644 (file)
@@ -2438,29 +2438,8 @@ static void rd_print_state(struct ramdisk_t * ramdisk) {
       memset((char *)(channels + channel), 0, sizeof(struct channel_t));
       }
     */
-    PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels));
-    PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
-    PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
-    PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
-    PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
 
 
-    PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", 
-              sizeof((channels->drives[0].controller.status)));
-    PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", 
-              sizeof((channels->drives[0].controller.sector_count)));
-    PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", 
-              sizeof((channels->drives[0].controller.interrupt_reason)));
-
-    PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", 
-              sizeof((channels->drives[0].controller.cylinder_no)));
-    PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", 
-              sizeof((channels->drives[0].controller.byte_count)));
-
-
-    PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", 
-              sizeof((channels->drives[0].controller.control)));
-
 
     for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
   
index d578a17..7325bdf 100644 (file)
@@ -72,11 +72,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
 
     guest_state->cpl = 0;
 
-    //ctrl_area->instrs.instrs.CR0 = 1;
-    ctrl_area->cr_reads.cr0 = 1;
-    ctrl_area->cr_writes.cr0 = 1;
-    //ctrl_area->cr_reads.cr4 = 1;
-    ctrl_area->cr_writes.cr4 = 1;
+
 
 
     /* Set up the efer to enable 64 bit page tables */
@@ -90,15 +86,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
       cr4->pae = 1;
       }
     */
-
     guest_state->efer |= EFER_MSR_svm_enable;
-    vm_info->guest_efer.value = 0x0LL;
-    
-    v3_hook_msr(vm_info, EFER_MSR, 
-               &v3_handle_efer_read,
-               &v3_handle_efer_write, 
-               vm_info);
-
 
 
     guest_state->rflags = 0x00000002; // The reserved bit is always 1
@@ -115,11 +103,12 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
     ctrl_area->svm_instrs.MONITOR = 1;
     ctrl_area->svm_instrs.MWAIT_always = 1;
     ctrl_area->svm_instrs.MWAIT_if_armed = 1;
+    ctrl_area->instrs.INVLPGA = 1;
 
 
     ctrl_area->instrs.HLT = 1;
     // guest_state->cr0 = 0x00000001;    // PE 
-    ctrl_area->guest_ASID = 1;
+
 
   
     /*
@@ -235,28 +224,33 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
     if (vm_info->shdw_pg_mode == SHADOW_PAGING) {
        PrintDebug("Creating initial shadow page table\n");
        
+       ctrl_area->guest_ASID = 1;
        
-       
-       /* Testing 64 bit page tables for long paged real mode guests */
-       //    vm_info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_64(vm_info));
        vm_info->direct_map_pt = (addr_t)V3_PAddr((void *)v3_create_direct_passthrough_pts(vm_info));
-       /* End Test */
        
        vm_info->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
        PrintDebug("Created\n");
        
-       
        guest_state->cr3 = vm_info->direct_map_pt;
 
-
-       //PrintDebugPageTables((pde32_t*)(vm_info->shdw_pg_state.shadow_cr3.e_reg.low));
-       
+       ctrl_area->cr_reads.cr0 = 1;
+       ctrl_area->cr_writes.cr0 = 1;
+       //ctrl_area->cr_reads.cr4 = 1;
+       ctrl_area->cr_writes.cr4 = 1;
        ctrl_area->cr_reads.cr3 = 1;
        ctrl_area->cr_writes.cr3 = 1;
 
 
+       vm_info->guest_efer.value = 0x0LL;
+    
+       v3_hook_msr(vm_info, EFER_MSR, 
+                   &v3_handle_efer_read,
+                   &v3_handle_efer_write, 
+                   vm_info);
+
+
        ctrl_area->instrs.INVLPG = 1;
-       ctrl_area->instrs.INVLPGA = 1;
+
        
        ctrl_area->exceptions.pf = 1;
        
@@ -264,7 +258,6 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
        /* We need to fix this */
        ctrl_area->TLB_CONTROL = 1;
        
-       
        guest_state->g_pat = 0x7040600070406ULL;
        
        guest_state->cr0 |= 0x80000000;
@@ -272,6 +265,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
     } else if (vm_info->shdw_pg_mode == NESTED_PAGING) {
        // Flush the TLB on entries/exits
        ctrl_area->TLB_CONTROL = 1;
+       ctrl_area->guest_ASID = 1;
        
        // Enable Nested Paging
        ctrl_area->NP_ENABLE = 1;
@@ -279,7 +273,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
        PrintDebug("NP_Enable at 0x%p\n", (void *)&(ctrl_area->NP_ENABLE));
        
        // Set the Nested Page Table pointer
-       vm_info->direct_map_pt = ((addr_t)v3_create_direct_passthrough_pts(vm_info) & ~0xfff);
+       vm_info->direct_map_pt = (addr_t)V3_PAddr((void *)v3_create_direct_passthrough_pts(vm_info));
        ctrl_area->N_CR3 = vm_info->direct_map_pt;
        
        //   ctrl_area->N_CR3 = Get_CR3();
@@ -370,8 +364,8 @@ static int start_svm_guest(struct guest_info *info) {
        struct v3_msr host_gs_base;
        struct v3_msr host_kerngs_base;
 
-       v3_enable_ints();
-       v3_clgi();
+/*     v3_enable_ints(); */
+/*     v3_clgi(); */
 
 
        /*
@@ -413,7 +407,7 @@ static int start_svm_guest(struct guest_info *info) {
 
        //PrintDebug("Turning on global interrupts\n");
        v3_stgi();
-       
+       v3_clgi();
        
        if ((num_exits % 5000) == 0) {
            PrintDebug("SVM Exit number %d\n", num_exits);
@@ -557,6 +551,7 @@ static int has_svm_nested_paging() {
 void v3_init_SVM(struct v3_ctrl_ops * vmm_ops) {
     reg_ex_t msr;
     void * host_state;
+    extern v3_cpu_arch_t v3_cpu_type;
 
     // Enable SVM on the CPU
     v3_get_msr(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
@@ -578,7 +573,11 @@ void v3_init_SVM(struct v3_ctrl_ops * vmm_ops) {
     PrintDebug("Host State being saved at %p\n", (void *)(addr_t)host_state);
     v3_set_msr(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
 
-
+    if (has_svm_nested_paging() == 1) {
+       v3_cpu_type = V3_SVM_REV3_CPU;
+    } else {
+       v3_cpu_type = V3_SVM_CPU;
+    }
 
     // Setup the SVM specific vmm operations
     vmm_ops->init_guest = &init_svm_guest;
index 5afadae..931bb99 100644 (file)
@@ -32,7 +32,7 @@
 #include <palacios/svm_msr.h>
 #include <palacios/vmm_profiler.h>
 #include <palacios/vmm_hypercall.h>
-
+#include <palacios/vmm_direct_paging.h>
 
 
 
@@ -74,12 +74,15 @@ int v3_handle_svm_exit(struct guest_info * info) {
     if ((info->intr_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) {
        // Interrupt was taken in the guest
 #ifdef DEBUG_INTERRUPTS
-       if ((info->intr_state.irq_vector == 238) || 
-           (info->intr_state.irq_vector == 239)) {
-           PrintDebug("Interrupt %d taken by guest\n", info->intr_state.irq_vector);
-       }
+       PrintDebug("Interrupt %d taken by guest\n", info->intr_state.irq_vector);
+#endif
+       if (!guest_ctrl->exit_int_info.valid) {
+           v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ);
+       } else {
+#ifdef DEBUG_INTERRUPTS
+           PrintDebug("EXIT INT INFO is set (vec=%d)\n", guest_ctrl->exit_int_info.vector);
 #endif
-       v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ);
+       }
     }
 
     info->intr_state.irq_pending = 0;
@@ -244,12 +247,20 @@ int v3_handle_svm_exit(struct guest_info * info) {
            }
            break;
        } 
-       case VMEXIT_NPF: 
+       case VMEXIT_NPF: {
+           addr_t fault_addr = guest_ctrl->exit_info2;
+           pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
 
-           PrintError("Currently unhandled Nested Page Fault\n");
-           return -1;
-               
+           if (info->shdw_pg_mode == NESTED_PAGING) {
+               if (v3_handle_nested_pagefault(info, fault_addr, *error_code) == -1) {
+                   return -1;
+               }
+           } else {
+               PrintError("Currently unhandled Nested Page Fault\n");
+               return -1;
+                   }
            break;
+           }
        case VMEXIT_INVLPG: 
            if (info->shdw_pg_mode == SHADOW_PAGING) {
 #ifdef DEBUG_SHADOW_PAGING
@@ -350,7 +361,29 @@ int v3_handle_svm_exit(struct guest_info * info) {
 
     // Update the low level state
 
-    if (v3_intr_pending(info)) {
+    if (v3_excp_pending(info)) {
+       uint_t excp = v3_get_excp_number(info);
+               
+       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
+       
+       if (info->excp_state.excp_error_code_valid) {
+           guest_ctrl->EVENTINJ.error_code = info->excp_state.excp_error_code;
+           guest_ctrl->EVENTINJ.ev = 1;
+#ifdef DEBUG_INTERRUPTS
+           PrintDebug("Injecting exception %d with error code %x\n", excp, guest_ctrl->EVENTINJ.error_code);
+#endif
+       }
+       
+       guest_ctrl->EVENTINJ.vector = excp;
+       
+       guest_ctrl->EVENTINJ.valid = 1;
+#ifdef DEBUG_INTERRUPTS
+       PrintDebug("Injecting Exception %d (EIP=%p)\n", 
+                  guest_ctrl->EVENTINJ.vector, 
+                  (void *)(addr_t)info->rip);
+#endif
+       v3_injecting_excp(info, excp);
+    } else if (v3_intr_pending(info)) {
 
        switch (v3_get_intr_type(info)) {
            case EXTERNAL_IRQ: {
@@ -358,11 +391,6 @@ int v3_handle_svm_exit(struct guest_info * info) {
                    
                // check to see if ==-1 (non exists)
                    
-               /*      
-                 guest_ctrl->EVENTINJ.vector = irq;
-                 guest_ctrl->EVENTINJ.valid = 1;
-                 guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
-               */
                    
                guest_ctrl->guest_ctrl.V_IRQ = 1;
                guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
@@ -370,11 +398,9 @@ int v3_handle_svm_exit(struct guest_info * info) {
                guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
 
 #ifdef DEBUG_INTERRUPTS
-               if ((irq == 238) || (irq == 239)) {
-                   PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
-                              guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
-                              (void *)(addr_t)info->rip);
-               }
+               PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
+                          guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
+                          (void *)(addr_t)info->rip);
 #endif
 
                info->intr_state.irq_pending = 1;
@@ -385,32 +411,6 @@ int v3_handle_svm_exit(struct guest_info * info) {
            case NMI:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
                break;
-           case EXCEPTION: {
-               uint_t excp = v3_get_intr_number(info);
-               
-               guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
-               
-               if (info->intr_state.excp_error_code_valid) {  //PAD
-                   guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
-                   guest_ctrl->EVENTINJ.ev = 1;
-#ifdef DEBUG_INTERRUPTS
-                   // PrintDebug("Injecting exception %d with error code %x\n", excp, guest_ctrl->EVENTINJ.error_code);
-#endif
-               }
-               
-               guest_ctrl->EVENTINJ.vector = excp;
-               
-               guest_ctrl->EVENTINJ.valid = 1;
-#ifdef DEBUG_INTERRUPTS
-               /*
-               PrintDebug("Injecting Exception %d (EIP=%p)\n", 
-                          guest_ctrl->EVENTINJ.vector, 
-                          (void *)(addr_t)info->rip);
-               */
-#endif
-               v3_injecting_intr(info, excp, EXCEPTION);
-               break;
-           }
            case SOFTWARE_INTR:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
                break;
index 87a1ae6..c981a3c 100644 (file)
 
 v3_vm_cpu_mode_t v3_get_cpu_mode(struct guest_info * info) {
     struct cr0_32 * cr0;
+    struct efer_64 * efer;
     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
-    struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
     struct v3_segment * cs = &(info->segments.cs);
+    vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
 
     if (info->shdw_pg_mode == SHADOW_PAGING) {
        cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+       efer = (struct efer_64 *)&(info->guest_efer);
     } else if (info->shdw_pg_mode == NESTED_PAGING) {
        cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+       efer = (struct efer_64 *)&(guest_state->efer);
     } else {
        PrintError("Invalid Paging Mode...\n");
        V3_ASSERT(0);
@@ -60,13 +63,16 @@ v3_vm_cpu_mode_t v3_get_cpu_mode(struct guest_info * info) {
 uint_t v3_get_addr_width(struct guest_info * info) {
     struct cr0_32 * cr0;
     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
-    struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
+    struct efer_64 * efer;
     struct v3_segment * cs = &(info->segments.cs);
+    vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
 
     if (info->shdw_pg_mode == SHADOW_PAGING) {
        cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+       efer = (struct efer_64 *)&(info->guest_efer);
     } else if (info->shdw_pg_mode == NESTED_PAGING) {
        cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
+       efer = (struct efer_64 *)&(guest_state->efer);
     } else {
        PrintError("Invalid Paging Mode...\n");
        V3_ASSERT(0);
index b17dd76..c88ecd2 100644 (file)
@@ -68,15 +68,20 @@ int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
 int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
     struct v3_shadow_region * shdw_reg = v3_get_shadow_region(guest_info, guest_pa);
 
-    *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
-
-    if ((shdw_reg == NULL) ||
-       (shdw_reg->host_type == SHDW_REGION_INVALID) ||
-       (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)){
+    if (shdw_reg == NULL) {
+       PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n", 
+                  (void *)guest_pa);
+       return -1;
+    }
+    
+    if ((shdw_reg->host_type == SHDW_REGION_INVALID) ||
+       (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)) {
        PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n", 
                   (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
        return -1;
     }
+    
+    *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
 
     return 0;
 }
index a5ec77e..be73f33 100644 (file)
@@ -88,10 +88,12 @@ int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr)
     
     v3_init_hypercall_map(info);
     
-  
-    if (v3_cpu_type == V3_SVM_REV3_CPU) {
+    if ((v3_cpu_type == V3_SVM_REV3_CPU) && 
+       (config_ptr->enable_nested_paging == 1)) {
+       PrintDebug("Guest Page Mode: NESTED_PAGING\n");
        info->shdw_pg_mode = NESTED_PAGING;
     } else {
+       PrintDebug("Guest Page Mode: SHADOW_PAGING\n");
        v3_init_shadow_page_state(info);
        info->shdw_pg_mode = SHADOW_PAGING;
     }
index 75d11f0..9bbcf5b 100644 (file)
@@ -243,7 +243,7 @@ int v3_handle_cr0_read(struct guest_info * info) {
                *dst_reg = *shadow_cr0;
            }
 
-           PrintDebug("returned CR0: %p\n", (void *)*dst_reg);
+           PrintDebug("returned CR0: %p\n", (void *)*(addr_t *)dst_reg);
        } else {
            struct cr0_32 * dst_reg = (struct cr0_32 *)(dec_instr.dst_operand.operand);
        
index 783f696..9884620 100644 (file)
 #include <palacios/vm_guest_mem.h>
 #include <palacios/vm_guest.h>
 
+
+#ifndef DEBUG_NESTED_PAGING
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+
 static addr_t create_generic_pt_page() {
     void * page = 0;
     page = V3_VAddr(V3_AllocPages(1));
@@ -44,7 +51,7 @@ addr_t v3_create_direct_passthrough_pts(struct guest_info * info) {
 
 int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
     v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
-    
+
     switch(mode) {
        case REAL:
        case PROTECTED:
@@ -62,3 +69,32 @@ int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr,
     }
     return -1;
 }
+
+
+
+int v3_handle_nested_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+    // THIS IS VERY BAD
+    v3_vm_cpu_mode_t mode = LONG;
+
+
+    PrintDebug("Nested PageFault: fault_addr=%p, error_code=%u\n",(void*)fault_addr, *(uint_t *)&error_code);
+
+    switch(mode) {
+       case REAL:
+       case PROTECTED:
+           return handle_passthrough_pagefault_32(info, fault_addr, error_code);
+
+       case PROTECTED_PAE:
+           return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
+
+       case LONG:
+       case LONG_32_COMPAT:
+           return handle_passthrough_pagefault_64(info, fault_addr, error_code);           
+       
+       default:
+           PrintError("Unknown CPU Mode\n");
+           break;
+    }
+    return -1;
+}
+
index 4df18a9..6645f86 100644 (file)
@@ -33,7 +33,7 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info,
                                                  addr_t fault_addr, 
                                                  pf_error_t error_code) {
     // Check to see if pde and pte exist (create them if not)
-    pde32_t * pde = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
+    pde32_t * pde = NULL;
     pte32_t * pte = NULL;
     addr_t host_addr = 0;
     
@@ -51,6 +51,14 @@ static inline int handle_passthrough_pagefault_32(struct guest_info * info,
     
     host_addr = v3_get_shadow_addr(region, fault_addr);
     
+    // Lookup the correct PDE address based on the PAGING MODE
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       pde = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
+    } else {
+       pde = CR3_TO_PDE32_VA(info->direct_map_pt);
+    }
+
+
     // Fix up the PDE entry
     if (pde[pde_index].present == 0) {
        pte = (pte32_t *)create_generic_pt_page();
index 033c69d..27cc9b3 100644 (file)
@@ -31,7 +31,7 @@
 static inline int handle_passthrough_pagefault_32pae(struct guest_info * info, 
                                                     addr_t fault_addr, 
                                                     pf_error_t error_code) {
-    pdpe32pae_t * pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
+    pdpe32pae_t * pdpe = NULL;
     pde32pae_t * pde = NULL;
     pte32pae_t * pte = NULL;
     addr_t host_addr = 0;
@@ -51,6 +51,13 @@ static inline int handle_passthrough_pagefault_32pae(struct guest_info * info,
 
     host_addr = v3_get_shadow_addr(region, fault_addr);
 
+    // Lookup the correct PDPE address based on the PAGING MODE
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
+    } else {
+       pdpe = CR3_TO_PDPE32PAE_VA(info->direct_map_pt);
+    }
+
     // Fix up the PDPE entry
     if (pdpe[pdpe_index].present == 0) {
        pde = (pde32pae_t *)create_generic_pt_page();
index a840c2b..ab82c9a 100644 (file)
 #include <palacios/vm_guest.h>
 
 
+
 static inline int handle_passthrough_pagefault_64(struct guest_info * info, 
                                                     addr_t fault_addr, 
                                                     pf_error_t error_code) {
-  pml4e64_t * pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
-  pdpe64_t * pdpe = NULL;
-  pde64_t * pde = NULL;
-  pte64_t * pte = NULL;
-  addr_t host_addr = 0;
-
-  int pml_index = PML4E64_INDEX(fault_addr);
-  int pdpe_index = PDPE64_INDEX(fault_addr);
-  int pde_index = PDE64_INDEX(fault_addr);
-  int pte_index = PTE64_INDEX(fault_addr);
-
-  struct v3_shadow_region * region =  v3_get_shadow_region(info, fault_addr);
-  
-  if ((region == NULL) || 
-      (region->host_type == SHDW_REGION_INVALID)) {
-    PrintError("Invalid region in passthrough page fault 64, addr=%p\n", 
-              (void *)fault_addr);
-    return -1;
-  }
-
-  host_addr = v3_get_shadow_addr(region, fault_addr);
-
-  //Fix up the PML entry
-  if (pml[pml_index].present == 0) {
-    pdpe = (pdpe64_t *)create_generic_pt_page();
-   
-    pml[pml_index].present = 1;
-    // Set default PML Flags...
-    pml[pml_index].pdp_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pdpe));    
-  } else {
-    pdpe = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pml[pml_index].pdp_base_addr));
-  }
-
-  // Fix up the PDPE entry
-  if (pdpe[pdpe_index].present == 0) {
-    pde = (pde64_t *)create_generic_pt_page();
-   
-    pdpe[pdpe_index].present = 1;
-    // Set default PDPE Flags...
-    pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));    
-  } else {
-    pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
-  }
+    pml4e64_t * pml = NULL;
+    pdpe64_t * pdpe = NULL;
+    pde64_t * pde = NULL;
+    pte64_t * pte = NULL;
+    addr_t host_addr = 0;
 
+    int pml_index = PML4E64_INDEX(fault_addr);
+    int pdpe_index = PDPE64_INDEX(fault_addr);
+    int pde_index = PDE64_INDEX(fault_addr);
+    int pte_index = PTE64_INDEX(fault_addr);
 
-  // Fix up the PDE entry
-  if (pde[pde_index].present == 0) {
-    pte = (pte64_t *)create_generic_pt_page();
 
-    pde[pde_index].present = 1;
-    pde[pde_index].writable = 1;
-    pde[pde_index].user_page = 1;
+    
 
-    pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
-  } else {
-    pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
-  }
+    struct v3_shadow_region * region =  v3_get_shadow_region(info, fault_addr);
+  
+    if ((region == NULL) || 
+       (region->host_type == SHDW_REGION_INVALID)) {
+       PrintError("Invalid region in passthrough page fault 64, addr=%p\n", 
+                  (void *)fault_addr);
+       return -1;
+    }
 
+    host_addr = v3_get_shadow_addr(region, fault_addr);
+    //
 
-  // Fix up the PTE entry
-  if (pte[pte_index].present == 0) {
-    pte[pte_index].user_page = 1;
+    // Lookup the correct PML address based on the PAGING MODE
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
+    } else {
+       pml = CR3_TO_PML4E64_VA(info->direct_map_pt);
+    }
 
-    if (region->host_type == SHDW_REGION_ALLOCATED) {
-      // Full access
-      pte[pte_index].present = 1;
-      pte[pte_index].writable = 1;
+    //Fix up the PML entry
+    if (pml[pml_index].present == 0) {
+       pdpe = (pdpe64_t *)create_generic_pt_page();
+   
+       // Set default PML Flags...
+       pml[pml_index].present = 1;
+        pml[pml_index].writable = 1;
+        pml[pml_index].user_page = 1;
 
-      pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+       pml[pml_index].pdp_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pdpe));    
+    } else {
+       pdpe = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pml[pml_index].pdp_base_addr));
+    }
 
-    } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
-      // Only trap writes
-     pte[pte_index].present = 1; 
-     pte[pte_index].writable = 0;
+    // Fix up the PDPE entry
+    if (pdpe[pdpe_index].present == 0) {
+       pde = (pde64_t *)create_generic_pt_page();
+       
+       // Set default PDPE Flags...
+       pdpe[pdpe_index].present = 1;
+       pdpe[pdpe_index].writable = 1;
+       pdpe[pdpe_index].user_page = 1;
 
-     pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+       pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));    
+    } else {
+       pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
+    }
 
-    } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
-      // trap all accesses
-      return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
 
+    // Fix up the PDE entry
+    if (pde[pde_index].present == 0) {
+       pte = (pte64_t *)create_generic_pt_page();
+       
+       pde[pde_index].present = 1;
+       pde[pde_index].writable = 1;
+       pde[pde_index].user_page = 1;
+       
+       pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
     } else {
-      PrintError("Unknown Region Type...\n");
-      return -1;
+       pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
+    }
+
+
+    // Fix up the PTE entry
+    if (pte[pte_index].present == 0) {
+       pte[pte_index].user_page = 1;
+       
+       if (region->host_type == SHDW_REGION_ALLOCATED) {
+           // Full access
+           pte[pte_index].present = 1;
+           pte[pte_index].writable = 1;
+
+           pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+           
+       } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
+           // Only trap writes
+           pte[pte_index].present = 1; 
+           pte[pte_index].writable = 0;
+
+           pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+
+       } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
+           // trap all accesses
+           return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
+
+       } else {
+           PrintError("Unknown Region Type...\n");
+           return -1;
+       }
     }
-  }
    
-  if ( (region->host_type == SHDW_REGION_WRITE_HOOK) && 
-       (error_code.write == 1) ) {
-    return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
-  }
+    if ( (region->host_type == SHDW_REGION_WRITE_HOOK) && 
+        (error_code.write == 1) ) {
+       return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
+    }
 
-  return 0;
+    return 0;
 }
 
 
index e6adab1..2df0469 100644 (file)
@@ -150,12 +150,14 @@ static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * de
     PrintDebug("Emulating XCHG write\n");
 
     if (dec_instr->src_operand.type == MEM_OPERAND) {
-       if (dec_instr->src_operand.operand != write_gva) {
-           PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
-                      (void *)dec_instr->src_operand.operand, (void *)write_gva);
-           return -1;
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
+           if (dec_instr->src_operand.operand != write_gva) {
+               PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+                          (void *)dec_instr->src_operand.operand, (void *)write_gva);
+               return -1;
+           }
        }
-    
+
        src_addr = dst_addr;
     } else if (dec_instr->src_operand.type == REG_OPERAND) {
        src_addr = dec_instr->src_operand.operand;
@@ -166,41 +168,45 @@ static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * de
 
 
     if (dec_instr->dst_operand.type == MEM_OPERAND) {
-       if (dec_instr->dst_operand.operand != write_gva) {
-           PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
-                      (void *)dec_instr->dst_operand.operand, (void *)write_gva);
-           return -1;
+        if (info->shdw_pg_mode == SHADOW_PAGING) {
+           if (dec_instr->dst_operand.operand != write_gva) {
+               PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+                          (void *)dec_instr->dst_operand.operand, (void *)write_gva);
+               return -1;
+           }
+       } else {
+           //check that the operand (GVA) maps to the the faulting GPA
        }
-    
+       
        em_dst_addr = dst_addr;
     } else if (dec_instr->src_operand.type == REG_OPERAND) {
        em_dst_addr = dec_instr->src_operand.operand;
     } else {
        em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
     }
-
+    
     dst_op_len = dec_instr->dst_operand.size;
     src_op_len = dec_instr->src_operand.size;
-
+    
     PrintDebug("Dst_Addr = %p, SRC operand = %p\n", 
               (void *)dst_addr, (void *)src_addr);
-
-
+    
+    
     if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
        PrintError("Instruction Emulation Failed\n");
        return -1;
     }
-
+    
     if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
        PrintError("Did not fully write hooked data\n");
        return -1;
     }
-
+    
     info->rip += dec_instr->instr_length;
-
+    
     return dst_op_len;
 }
-
+    
 
 
 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr, 
@@ -232,12 +238,16 @@ static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec
 
 
     if (dec_instr->dst_operand.type == MEM_OPERAND) {
-       if (dec_instr->dst_operand.operand != read_gva) {
-           PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
-                      (void *)dec_instr->dst_operand.operand, (void *)read_gva);
-           return -1;
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
+           if (dec_instr->dst_operand.operand != read_gva) {
+               PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+                          (void *)dec_instr->dst_operand.operand, (void *)read_gva);
+               return -1;
+           }
+        } else {
+           //check that the operand (GVA) maps to the the faulting GPA
        }
-    
+
        em_dst_addr = src_addr;
     } else if (dec_instr->src_operand.type == REG_OPERAND) {
        em_dst_addr = dec_instr->src_operand.operand;
@@ -314,12 +324,15 @@ int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write
     }
 
 
-
-    if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
-       (dec_instr.dst_operand.operand != write_gva)) {
-       PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
-                  (void *)dec_instr.dst_operand.operand, (void *)write_gva);
-       return -1;
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
+           (dec_instr.dst_operand.operand != write_gva)) {
+           PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+                      (void *)dec_instr.dst_operand.operand, (void *)write_gva);
+           return -1;
+       }
+    } else {
+       //check that the operand (GVA) maps to the the faulting GPA
     }
 
 
@@ -401,15 +414,17 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp
        return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
     }
 
-
-    if ((dec_instr.src_operand.type != MEM_OPERAND) ||
-       (dec_instr.src_operand.operand != read_gva)) {
-       PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
-                  (void *)dec_instr.src_operand.operand, (void *)read_gva);
-       return -1;
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       if ((dec_instr.src_operand.type != MEM_OPERAND) ||
+           (dec_instr.src_operand.operand != read_gva)) {
+           PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
+                      (void *)dec_instr.src_operand.operand, (void *)read_gva);
+           return -1;
+       }
+    } else {
+       //check that the operand (GVA) maps to the the faulting GPA
     }
 
-
     if (dec_instr.dst_operand.type == MEM_OPERAND) {
        if (info->mem_mode == PHYSICAL_MEM) {
            if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
diff --git a/palacios/src/palacios/vmm_excp.c b/palacios/src/palacios/vmm_excp.c
new file mode 100644 (file)
index 0000000..ea6cdc5
--- /dev/null
@@ -0,0 +1,98 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm_excp.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_types.h>
+
+void v3_init_exception_state(struct guest_info * info) {
+    info->excp_state.excp_pending = 0;
+    info->excp_state.excp_num = 0;
+    info->excp_state.excp_error_code = 0;
+
+}
+
+
+
+int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
+    struct v3_excp_state * excp_state = &(info->excp_state);
+
+    if (excp_state->excp_pending == 0) {
+       excp_state->excp_pending = 1;
+       excp_state->excp_num = excp;
+       excp_state->excp_error_code = error_code;
+       excp_state->excp_error_code_valid = 1;
+       //      PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code);
+    } else {
+       PrintError("exception already pending, currently not implemented\n");
+       return -1;
+    }
+
+    return 0;
+}
+
+int v3_raise_exception(struct guest_info * info, uint_t excp) {
+    struct v3_excp_state * excp_state = &(info->excp_state);
+    //PrintDebug("[v3_raise_exception]\n");
+    if (excp_state->excp_pending == 0) {
+       excp_state->excp_pending = 1;
+       excp_state->excp_num = excp;
+       excp_state->excp_error_code = 0;
+       excp_state->excp_error_code_valid = 0;
+    } else {
+       PrintError("exception already pending, currently not implemented\n");
+       return -1;
+    }
+
+    return 0;
+}
+
+
+int v3_excp_pending(struct guest_info * info) {
+    struct v3_excp_state * excp_state = &(info->excp_state);
+    
+    if (excp_state->excp_pending == 1) {
+       return 1;
+    }
+
+    return 0;
+}
+
+
+int v3_get_excp_number(struct guest_info * info) {
+    struct v3_excp_state * excp_state = &(info->excp_state);
+
+    if (excp_state->excp_pending == 1) {
+       return excp_state->excp_num;
+    }
+
+    return 0;
+}
+
+
+int v3_injecting_excp(struct guest_info * info, uint_t excp) {
+    struct v3_excp_state * excp_state = &(info->excp_state);
+    
+    excp_state->excp_pending = 0;
+    excp_state->excp_num = 0;
+    excp_state->excp_error_code = 0;
+    excp_state->excp_error_code_valid = 0;
+    
+    return 0;
+}
index ce21ff3..953df0e 100644 (file)
@@ -40,14 +40,10 @@ struct intr_controller {
 
 
 void v3_init_interrupt_state(struct guest_info * info) {
-    info->intr_state.excp_pending = 0;
-    info->intr_state.excp_num = 0;
-    info->intr_state.excp_error_code = 0;
 
     info->intr_state.irq_pending = 0;
     info->intr_state.irq_vector = 0;
 
-
     INIT_LIST_HEAD(&(info->intr_state.controller_list));
 
     memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256);
@@ -147,39 +143,6 @@ int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
 
 
 
-int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
-
-    if (intr_state->excp_pending == 0) {
-       intr_state->excp_pending = 1;
-       intr_state->excp_num = excp;
-       intr_state->excp_error_code = error_code;
-       intr_state->excp_error_code_valid = 1;
-       //      PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code);
-    } else {
-       PrintError("exception already pending, currently not implemented\n");
-       return -1;
-    }
-
-    return 0;
-}
-
-int v3_raise_exception(struct guest_info * info, uint_t excp) {
-    struct v3_intr_state * intr_state = &(info->intr_state);
-    //PrintDebug("[v3_raise_exception]\n");
-    if (intr_state->excp_pending == 0) {
-       intr_state->excp_pending = 1;
-       intr_state->excp_num = excp;
-       intr_state->excp_error_code = 0;
-       intr_state->excp_error_code_valid = 0;
-    } else {
-       PrintError("exception already pending, currently not implemented\n");
-       return -1;
-    }
-
-    return 0;
-}
-
 
 int v3_lower_irq(struct guest_info * info, int irq) {
     struct intr_controller * ctrl = NULL;
@@ -211,61 +174,45 @@ int v3_raise_irq(struct guest_info * info, int irq) {
 
 int v3_intr_pending(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
-
+    struct intr_controller * ctrl = NULL;
     //  PrintDebug("[intr_pending]\n");
-    if (intr_state->excp_pending == 1) {
-       return 1;
-    } else {
-       struct intr_controller * ctrl = NULL;
 
-       list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-           if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
-               return 1;
-           }
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+       if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+           return 1;
        }
     }
 
+
     return 0;
 }
 
 
 uint_t v3_get_intr_number(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
+    struct intr_controller * ctrl = NULL;
 
-    if (intr_state->excp_pending == 1) {
-       return intr_state->excp_num;
-    } else {
-       struct intr_controller * ctrl = NULL;
-
-       list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-           if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
-               uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
-
-               //      PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
-
-               return intr_num;
-           }
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+       if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
+           uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
+           
+           //  PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
+           
+           return intr_num;
        }
     }
-
     return 0;
 }
 
 
 intr_type_t v3_get_intr_type(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
+    struct intr_controller * ctrl = NULL;
 
-    if (intr_state->excp_pending) {
-       //      PrintDebug("[get_intr_type] Exception\n");
-       return EXCEPTION;
-    } else {
-       struct intr_controller * ctrl = NULL;
-
-       list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-           if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
-               //PrintDebug("[get_intr_type] External_irq\n");
-               return EXTERNAL_IRQ;
-           }
+    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+       if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+           //PrintDebug("[get_intr_type] External_irq\n");
+           return EXTERNAL_IRQ;
        }
     }
 
@@ -281,14 +228,7 @@ intr_type_t v3_get_intr_type(struct guest_info * info) {
 int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) {
     struct v3_intr_state * intr_state = &(info->intr_state);
 
-    if (type == EXCEPTION) {
-       //      PrintDebug("[injecting_intr] Exception\n");
-       intr_state->excp_pending = 0;
-       intr_state->excp_num = 0;
-       intr_state->excp_error_code = 0;
-       intr_state->excp_error_code_valid = 0;
-    
-    } else if (type == EXTERNAL_IRQ) {
+    if (type == EXTERNAL_IRQ) {
        struct intr_controller * ctrl = NULL;
 
        //      PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
index 38eb602..c244793 100644 (file)
@@ -264,7 +264,7 @@ addr_t v3_get_shadow_addr(struct v3_shadow_region * reg, addr_t guest_addr) {
         (reg->host_type != SHDW_REGION_INVALID) ) {
        return (guest_addr - reg->guest_start) + reg->host_addr;
     } else {
-       PrintError("MEM Region Invalid\n");
+       PrintDebug("MEM Region Invalid\n");
        return 0;
     }
 }
index f7bc878..567f652 100644 (file)
@@ -120,9 +120,10 @@ void v3_profile_exit(struct guest_info * info, uint_t exit_code) {
        insert_event(info, evt);
     }
 
+    
   
 
-    evt->handler_time = (evt->handler_time * .99) + (time * .01);
+    evt->handler_time = (evt->handler_time * 127ull + time) / 128;
 
 
     evt->exit_count++;
index 2e7d853..25ca076 100644 (file)
@@ -568,7 +568,7 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
     int addr_width = v3_get_addr_width(info);;
     // struct v3_segment * seg_reg;
 
-    PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
+    PrintDebug("Xed mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
     PrintDebug("Address width: %s\n",
               xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
     PrintDebug("Stack Address width: %s\n",
diff --git a/palacios/src/vmboot/rombios/BIOS-bochs-latest b/palacios/src/vmboot/rombios/BIOS-bochs-latest
new file mode 100644 (file)
index 0000000..ea9a1ec
Binary files /dev/null and b/palacios/src/vmboot/rombios/BIOS-bochs-latest differ
diff --git a/palacios/src/vmboot/vgabios/VGABIOS-lgpl-latest.bin b/palacios/src/vmboot/vgabios/VGABIOS-lgpl-latest.bin
new file mode 100644 (file)
index 0000000..dc6785d
Binary files /dev/null and b/palacios/src/vmboot/vgabios/VGABIOS-lgpl-latest.bin differ