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.


lots of changes...
Jack Lange [Tue, 13 May 2008 00:01:44 +0000 (00:01 +0000)]
25 files changed:
palacios/build/Makefile
palacios/build/NOTES-QEMU.TXT
palacios/build/payload_layout.txt
palacios/build/vm_kernel
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_mem.h
palacios/include/palacios/vmm_paging.h
palacios/include/palacios/vmm_shadow_paging.h
palacios/src/devices/8259a.c
palacios/src/devices/nvram.c
palacios/src/devices/simple_pic.c
palacios/src/devices/timer.c
palacios/src/geekos/vm.c
palacios/src/geekos/vmm_stubs.c
palacios/src/palacios/svm.c
palacios/src/palacios/svm_ctrl_regs.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vm_dev.c
palacios/src/palacios/vmm_dev_mgr.c
palacios/src/palacios/vmm_io.c
palacios/src/palacios/vmm_irq.c
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_paging.c
palacios/src/palacios/vmm_shadow_paging.c

index ef7d453..0b13303 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.30 $
+# $Revision: 1.31 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -211,7 +211,7 @@ CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
 CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include
 
 # Flags used for VMM C source files
-CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include
+CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include -D__V3VEE__
 
 # Flags used for VMM C ASM files
 NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
index ef43309..e1f262c 100644 (file)
 memory, registers, disassemble, etc.  It's not a complete debugger,
 thoough
 
--s waits for a gdb connection.  This seems to only work for kgdb and linux kernels
+-S waits for a gdb connection.  This seems to only work for kgdb and linux kernels
 
 
 -serial stdio redirects COM1 to stdio
+-serial file:<file_name> writes COM1 to the given file
 
 
 
+MAKING an ISO image from a floppy image
+mkisofs -pad -b <floppy_image> -R -o <iso_output_image> <floppy_image>
+
+
+/usr/local/qemu/bin/qemu-system-x86_64 -serial file:serial.out -m 1024 -fda fd.img  -cdrom guest_no_timer.iso
index 719cbdb..1931d93 100755 (executable)
Binary files a/palacios/build/vm_kernel and b/palacios/build/vm_kernel differ
index cd2ce37..56245ef 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __VM_GUEST_H
 #define __VM_GUEST_H
 
+
+
+
 #include <palacios/vmm_mem.h>
 #include <palacios/vmm_types.h>
 #include <palacios/vmm_io.h>
@@ -9,6 +12,7 @@
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_irq.h>
 
+
 typedef ullong_t gpr_t;
 
 /*
@@ -44,6 +48,9 @@ struct vm_ctrl_ops {
 };
 
 
+
+
+
 typedef enum {SHADOW_PAGING, NESTED_PAGING} vm_page_mode_t;
 typedef enum {REAL, PROTECTED, PROTECTED_PG, PROTECTED_PAE, PROTECTED_PAE_PG, LONG, LONG_PG} vm_cpu_mode_t;
 
index 47bd00b..92597ff 100644 (file)
@@ -2,13 +2,16 @@
 #define __VMM_H
 
 
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_mem.h>
+
+#ifdef __V3VEE__
+
 //#include <palacios/vmm_types.h>
 #include <palacios/vmm_string.h>
 
-#include <palacios/vmm_mem.h>
-//#include <palacios/vmm_paging.h>
 
-#include <palacios/vm_guest.h>
+//#include <palacios/vmm_paging.h>
 
 /* utility definitions */
 #define PrintDebug(fmt, args...)                       \
 
 
 
+#define V3_AllocPages(ptr, num_pages)                  \
+  do {                                                 \
+    extern struct vmm_os_hooks * os_hooks;             \
+    if ((os_hooks) && (os_hooks)->allocate_pages) {    \
+      ptr = (os_hooks)->allocate_pages(num_pages);     \
+    }                                                  \
+  } while (0)                                          \
+
+
 
-/* This clearly won't work, we need some way to get a return value out of it */
-#define VMMMalloc(type, var, size)                     \
+#define V3_Malloc(type, var, size)                     \
   do {                                                 \
     extern struct vmm_os_hooks * os_hooks;             \
     if ((os_hooks) && (os_hooks)->malloc) {            \
@@ -52,7 +63,7 @@
 
 
 // We need to check the hook structure at runtime to ensure its SAFE
-#define VMMFree(addr)                                  \
+#define V3_Free(addr)                                  \
   do {                                                 \
     extern struct vmm_os_hooks * os_hooks;             \
     if ((os_hooks) && (os_hooks)->free) {              \
@@ -78,6 +89,7 @@
 #define VMM_VMX_CPU 1
 #define VMM_SVM_CPU 2
 
+#endif //!__V3VEE__
 
 
 /* This will contain function pointers that provide OS services */
index 62352d2..8a32f5f 100644 (file)
@@ -2,6 +2,7 @@
 #define __VMM_MEM_H
 
 
+
 #include <palacios/vmm_types.h>
 
 
@@ -42,6 +43,8 @@ typedef enum host_region_type {
 
 
 
+#define shadow_mem_type_t host_region_type_t
+
 typedef struct shadow_region {
   guest_region_type_t     guest_type;
   addr_t                  guest_start; 
@@ -95,6 +98,8 @@ shadow_region_t * get_shadow_region_by_index(struct shadow_map * map, uint_t ind
 
 host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr);
 
+host_region_type_t get_shadow_addr_type(struct guest_info * info, addr_t guest_addr);
+addr_t get_shadow_addr(struct guest_info * info, addr_t guest_addr);
 
 // Semantics:
 // Adding a region that overlaps with an existing region results is undefined
index 9a6d213..edc1d6f 100644 (file)
@@ -69,12 +69,10 @@ to the physical addresses epxected by the VMM/host.  On AMD SVM, this
 switch is done by the hardware.  On Intel VT, the switch is done
 by the hardware as well, but we are responsible for manually updating
 the host state in the vmcs before entering the guest.
-
-
 */
 
 
-
+#ifdef __V3VEE__
 
 #define MAX_PTE32_ENTRIES          1024
 #define MAX_PDE32_ENTRIES          1024
@@ -84,23 +82,38 @@ the host state in the vmcs before entering the guest.
 #define MAX_PDPE64_ENTRIES         512
 #define MAX_PML4E64_ENTRIES        512
 
+
+/* Converts an address into a page table index */
 #define PDE32_INDEX(x)  ((((uint_t)x) >> 22) & 0x3ff)
 #define PTE32_INDEX(x)  ((((uint_t)x) >> 12) & 0x3ff)
 
+/* Gets the base address needed for a Page Table entry */
+#define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
+#define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
 
-#define PAGE_ALIGNED_ADDR(x)   (((uint_t) (x)) >> 12)
+#define PT32_PAGE_ADDR(x)   (((uint_t)x) & 0xfffff000)
+#define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
+#define PT32_PAGE_POWER 12
 
-#ifndef PAGE_ADDR
-#define PAGE_ADDR(x)   (PAGE_ALIGNED_ADDR(x) << 12)
-#endif
+
+/* The following should be phased out */
 #define PAGE_OFFSET(x)  ((((uint_t)x) & 0xfff))
+#define PAGE_ALIGNED_ADDR(x)   (((uint_t) (x)) >> 12)
+#define PAGE_ADDR(x)   (PAGE_ALIGNED_ADDR(x) << 12)
+#define PAGE_POWER 12
+#define PAGE_SIZE 4096
+/* ** */
 
 
-#define PAGE_POWER 12
 
 #define CR3_TO_PDE32(cr3) (((ulong_t)cr3) & 0xfffff000)
 #define CR3_TO_PDPTRE(cr3) (((ulong_t)cr3) & 0xffffffe0)
-#define CR3_TO_PML4E64(cr3)  (((ullong_t)cr3) & 0x000ffffffffff000)
+#define CR3_TO_PML4E64(cr3)  (((ullong_t)cr3) & 0x000ffffffffff000LL)
+
+
+/* Accessor functions for the page table structures */
+#define PDE32_T_ADDR(x) ((x.pt_base_addr) << 12)
+#define PTE32_T_ADDR(x) ((x.page_base_addr) << 12)
 
 #define VM_WRITE     1
 #define VM_USER      2
@@ -109,6 +122,8 @@ the host state in the vmcs before entering the guest.
 #define VM_EXEC      0
 
 
+#endif
+
 /* PDE 32 bit PAGE STRUCTURES */
 typedef enum {NOT_PRESENT, PTE32, LARGE_PAGE} pde32_entry_type_t;
 
@@ -212,6 +227,14 @@ typedef struct pte64 {
 
 /* *************** */
 
+typedef struct pf_error_code {
+  uint_t present           : 1; // if 0, fault due to page not present
+  uint_t write             : 1; // if 1, faulting access was a write
+  uint_t user              : 1; // if 1, faulting access was in user mode
+  uint_t rsvd_access       : 1; // if 1, fault from reading a 1 from a reserved field (?)
+  uint_t ifetch            : 1; // if 1, faulting access was an instr fetch (only with NX)
+  uint_t rsvd              : 27;
+} pf_error_t;
 
 typedef enum { PDE32 } paging_mode_t;
 
@@ -238,6 +261,16 @@ pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info);
 void PrintDebugPageTables(pde32_t * pde);
 
 
+#ifdef __V3VEE__
+
+
+void PrintPT32(addr_t starting_address, pte32_t * pte);
+void PrintPD32(pde32_t * pde);
+void PrintPTE32(addr_t virtual_address, pte32_t * pte);
+void PrintPDE32(addr_t virtual_address, pde32_t * pde);
+
+#endif // !__V3VEE__
+
 
 
 #endif
index 7799e06..049ac50 100644 (file)
@@ -4,9 +4,6 @@
 
 
 #include <palacios/vmm_util.h>
-
-
-
 #include <palacios/vmm_paging.h>
 
 struct shadow_page_state {
@@ -14,15 +11,15 @@ struct shadow_page_state {
   // these two reflect the top-level page directory
   // of the guest page table
   paging_mode_t           guest_mode;
-  reg_ex_t                guest_cr3;         // points to guest's current page table
+  ullong_t                guest_cr3;         // points to guest's current page table
 
   // Should this be here??
   reg_ex_t                guest_cr0;
 
   // these two reflect the top-level page directory 
-  // the shadow page table
+  // of the shadow page table
   paging_mode_t           shadow_mode;
-  reg_ex_t                shadow_cr3;
+  ullong_t                shadow_cr3;
 
 
 };
@@ -37,11 +34,13 @@ struct guest_info;
 
 int init_shadow_page_state(struct shadow_page_state * state);
 
-// This function will cause the shadow page table to be deleted
-// and rewritten to reflect the guest page table and the shadow map
-int wholesale_update_shadow_page_state(struct guest_info * guest_info);
 
+addr_t create_new_shadow_pt32(struct guest_info * info);
 
+addr_t setup_shadow_pt32(struct guest_info * info, addr_t virt_cr3);
+addr_t setup_shadow_pte32(struct guest_info * info, addr_t pt_host_addr);
 
+int handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
+int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
 
 #endif
index 31aa28a..963e7a8 100644 (file)
@@ -517,7 +517,7 @@ static struct vm_device_ops dev_ops = {
 
 struct vm_device * create_pic() {
   struct pic_internal * state = NULL;
-  VMMMalloc(struct pic_internal *, state, sizeof(struct pic_internal));
+  V3_Malloc(struct pic_internal *, state, sizeof(struct pic_internal));
 
   struct vm_device *device = create_device("8259A", &dev_ops, state);
 
index e59b2f3..bf450ae 100644 (file)
@@ -112,7 +112,10 @@ static int set_nvram_defaults(struct vm_device *dev)
   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
 
   // Set the extended memory beyond 16 MB to 128-16 MB
-  nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x7;
+  // nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x7;
+  //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
+
+  nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x00;
   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
 
   
index c3539b7..55eea77 100644 (file)
@@ -69,7 +69,7 @@ static struct vm_device_ops dev_ops = {
 
 struct vm_device * create_simple_pic() {
   struct pic_internal * state = NULL;
-  VMMMalloc(struct pic_internal *, state, sizeof(struct pic_internal));
+  V3_Malloc(struct pic_internal *, state, sizeof(struct pic_internal));
 
   struct vm_device * pic_dev = create_device("Simple Pic", &dev_ops, state);
 
index 24c2a83..d941fe5 100644 (file)
@@ -40,7 +40,7 @@ static struct vm_device_ops dev_ops = {
 
 struct vm_device * create_timer() {
   struct timer_state * timer = NULL;
-  VMMMalloc(struct timer_state *, timer, sizeof(struct timer_state));
+  V3_Malloc(struct timer_state *, timer, sizeof(struct timer_state));
   struct vm_device * dev = create_device("Timer", &dev_ops, timer);
   
   return dev;
index f2c0343..adef732 100644 (file)
@@ -4,13 +4,14 @@
 #include <geekos/serial.h>
 #include <geekos/vm.h>
 #include <geekos/screen.h>
-#include <palacios/vmm_dev_mgr.h>
+
 #include <devices/nvram.h>
 #include <devices/timer.h>
 #include <devices/simple_pic.h>
 #include <devices/8259a.h>
-#include <palacios/vmm_intr.h>
 
+#include <palacios/vmm_intr.h>
+#include <palacios/vmm_dev_mgr.h>
 
 #define SPEAKER_PORT 0x61
 
@@ -151,7 +152,9 @@ void BuzzVM()
 
 
 
-
+/* We need a configuration mechanism, so we can wrap this completely inside the VMM code, 
+ * with no pollution into the HOST OS
+ */
 
 int RunVMM(struct Boot_Info * bootInfo) {
 
@@ -179,9 +182,11 @@ int RunVMM(struct Boot_Info * bootInfo) {
     os_hooks.hook_interrupt = &hook_irq_stub;
     os_hooks.ack_irq = &ack_irq;
  
-    //   DumpGDT();
+
     Init_VMM(&os_hooks, &vmm_ops);
   
+
+    /* MOVE THIS TO AN INIT GUEST ROUTINE */
     init_shadow_map(&(vm_info.mem_map));
     init_shadow_page_state(&(vm_info.shdw_pg_state));
     vm_info.page_mode = SHADOW_PAGING;
@@ -193,6 +198,7 @@ int RunVMM(struct Boot_Info * bootInfo) {
     init_interrupt_state(&vm_info);
 
     dev_mgr_init(&(vm_info.dev_mgr));
+    /* ** */
     
     if (0) {
       
@@ -239,33 +245,33 @@ int RunVMM(struct Boot_Info * bootInfo) {
       void * region_start;
 
  
-      PrintDebug("Guest Size: %lu\n", bootInfo->guest_size);
+      PrintBoth("Guest Size: %lu\n", bootInfo->guest_size);
 
       struct guest_mem_layout * layout = (struct guest_mem_layout *)0x100000;
 
       if (layout->magic != MAGIC_CODE) {
-       PrintDebug("Layout Magic Mismatch (0x%x)\n", layout->magic);
+       PrintBoth("Layout Magic Mismatch (0x%x)\n", layout->magic);
       }
 
-      PrintDebug("%d layout regions\n", layout->num_regions);
+      PrintBoth("%d layout regions\n", layout->num_regions);
 
       region_start = (void *)&(layout->regions[layout->num_regions]);
 
-      PrintDebug("region start = 0x%x\n", region_start);
+      PrintBoth("region start = 0x%x\n", region_start);
 
       for (i = 0; i < layout->num_regions; i++) {
        struct layout_region * reg = &(layout->regions[i]);
        uint_t num_pages = (reg->length / PAGE_SIZE) + ((reg->length % PAGE_SIZE) ? 1 : 0);
        void * guest_mem = Allocate_VMM_Pages(num_pages);
 
-       PrintDebug("Layout Region %d bytes\n", reg->length);
+       PrintBoth("Layout Region %d bytes\n", reg->length);
        memcpy(guest_mem, region_start, reg->length);
        
        SerialMemDump((unsigned char *)(guest_mem), 16);
 
        add_shadow_region_passthrough(&vm_info, reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
 
-       PrintDebug("Adding Shadow Region (0x%x-0x%x) -> 0x%x\n", reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), guest_mem);
+       PrintBoth("Adding Shadow Region (0x%x-0x%x) -> 0x%x\n", reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), guest_mem);
 
        region_start += reg->length;
       }
@@ -277,12 +283,12 @@ int RunVMM(struct Boot_Info * bootInfo) {
 
 
       // TEMP
-       add_shadow_region_passthrough(&vm_info, 0xc0000, 0xc8000, 0xc0000);
+      //add_shadow_region_passthrough(&vm_info, 0xc0000, 0xc8000, 0xc0000);
 
       if (1) {
        add_shadow_region_passthrough(&vm_info, 0xc7000, 0xc8000, (addr_t)Allocate_VMM_Pages(1));
        if (add_shadow_region_passthrough(&vm_info, 0xc8000, 0xf0000, (addr_t)Allocate_VMM_Pages(40)) == -1) {
-         PrintDebug("Error adding shadow region\n");
+         PrintBoth("Error adding shadow region\n");
        }
       } else {
        add_shadow_region_passthrough(&vm_info, 0xc0000, 0xc8000, 0xc0000);
@@ -290,7 +296,8 @@ int RunVMM(struct Boot_Info * bootInfo) {
       }
 
 
-      add_shadow_region_passthrough(&vm_info, 0x100000, 0x2000000, (addr_t)Allocate_VMM_Pages(8192));
+      //add_shadow_region_passthrough(&vm_info, 0x100000, 0x2000000, (addr_t)Allocate_VMM_Pages(8192));
+      add_shadow_region_passthrough(&vm_info, 0x100000, 0x1000000, (addr_t)Allocate_VMM_Pages(4096));
 
 
       print_shadow_map(&(vm_info.mem_map));
@@ -298,12 +305,7 @@ int RunVMM(struct Boot_Info * bootInfo) {
       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write, NULL);
       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
 
-      /*
-       hook_io_port(&(vm_info.io_map), 0x20, &IO_Read, &IO_Write_to_Serial, NULL);
-       hook_io_port(&(vm_info.io_map), 0x21, &IO_Read, &IO_Write_to_Serial, NULL);
-       hook_io_port(&(vm_info.io_map), 0xa0, &IO_Read, &IO_Write_to_Serial, NULL);
-       hook_io_port(&(vm_info.io_map), 0xa1, &IO_Read, &IO_Write_to_Serial, NULL);
-      */
+
       hook_io_port(&(vm_info.io_map), 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
       hook_io_port(&(vm_info.io_map), 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
       hook_io_port(&(vm_info.io_map), 0x402, &IO_Read, &IO_BOCHS_debug, NULL);
@@ -325,6 +327,7 @@ int RunVMM(struct Boot_Info * bootInfo) {
       hook_irq(&vm_info, 14);
       hook_irq(&vm_info, 15);
 
+
       vm_info.rip = 0xfff0;
       vm_info.vm_regs.rsp = 0x0;
     }
index 47e8886..aae2376 100644 (file)
@@ -75,8 +75,9 @@ int hook_irq_stub(struct guest_info * info, int irq) {
   irq_map[irq] = info;
   volatile void *foo = pic_intr_handler;
   foo=0;
-  //  Install_IRQ(irq, pic_intr_handler);
-  // Enable_IRQ(irq);
+  Disable_IRQ(irq);
+  Install_IRQ(irq, pic_intr_handler);
+  Enable_IRQ(irq);
   return 0;
 }
 
index 73d85a9..a95efa4 100644 (file)
@@ -279,10 +279,10 @@ void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) {
 
   if (vm_info.page_mode == SHADOW_PAGING) {
     PrintDebug("Creating initial shadow page table\n");
-    vm_info.shdw_pg_state.shadow_cr3.e_reg.low |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
+    vm_info.shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
     PrintDebug("Created\n");
 
-    guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
+    guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3;
 
     ctrl_area->cr_reads.cr3 = 1;
     ctrl_area->cr_writes.cr3 = 1;
@@ -425,10 +425,10 @@ void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) {
 
   if (vm_info.page_mode == SHADOW_PAGING) {
     PrintDebug("Creating initial shadow page table\n");
-    vm_info.shdw_pg_state.shadow_cr3.e_reg.low |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
+    vm_info.shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
     PrintDebug("Created\n");
 
-    guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
+    guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3;
 
     //PrintDebugPageTables((pde32_t*)(vm_info.shdw_pg_state.shadow_cr3.e_reg.low));
 
index 3586205..ae09fd0 100644 (file)
@@ -187,8 +187,6 @@ int handle_cr0_write(struct guest_info * info) {
       index++; 
     }
 
-
-    /* CHECK IF MOV_TO_CR CAN TAKE MEMORY OPERANDS... */
     if ((instr[index] == cr_access_byte) && 
        (instr[index + 1] == mov_to_cr_byte)) {
     
@@ -215,6 +213,8 @@ int handle_cr0_write(struct guest_info * info) {
        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;
@@ -223,6 +223,10 @@ int handle_cr0_write(struct guest_info * info) {
          //
          // Activate Shadow Paging
          //
+         PrintDebug("Turning on paging in the guest\n");
+
+         guest_state->cr3 = *(addr_t*)shadow_cr3;
+         
 
        } else if (new_cr0->pe == 0) {
          info->cpu_mode = REAL;
@@ -402,3 +406,141 @@ int handle_cr0_read(struct guest_info * info) {
 
   return 0;
 }
+
+
+
+
+int handle_cr3_write(struct guest_info * info) {
+  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+
+  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, guest_state->rip, guest_state->cs.base), 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
+         guest_state->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) {
+  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
+
+  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, guest_state->rip, guest_state->cs.base), 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 *)&(guest_state->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;
+}
index ab2faae..6f58b7c 100644 (file)
@@ -73,18 +73,41 @@ int handle_svm_exit(struct guest_info * info) {
     if (handle_cr0_read(info) == -1) {
       return -1;
     }
+  } else if (exit_code == VMEXIT_CR3_WRITE) {
+    PrintDebug("CR3 Write\n");
 
+    if (handle_cr3_write(info) == -1) {
+      return -1;
+    }    
+  } else if (exit_code == VMEXIT_CR3_READ) {
+    PrintDebug("CR3 Read\n");
+
+    if (handle_cr3_read(info) == -1) {
+      return -1;
+    }
+
+  } else if (exit_code == VMEXIT_EXCP14) {
+    addr_t fault_addr = guest_ctrl->exit_info2;
+    pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
+    
+    PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
+
+  
+
+    if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
+      return -1;
+    }
 
     /*
-  } else if (( (exit_code == VMEXIT_CR3_READ)  ||
-              (exit_code == VMEXIT_CR3_WRITE) ||
-              (exit_code == VMEXIT_INVLPG)    ||
-              (exit_code == VMEXIT_INVLPGA)   || 
-              (exit_code == VMEXIT_EXCP14)) && 
-            (info->page_mode == SHADOW_PAGING)) {
-    handle_shadow_paging(info);
+      } else if (( (exit_code == VMEXIT_CR3_READ)  ||
+      (exit_code == VMEXIT_CR3_WRITE) ||
+      (exit_code == VMEXIT_INVLPG)    ||
+      (exit_code == VMEXIT_INVLPGA)   || 
+      (exit_code == VMEXIT_EXCP14)) && 
+      (info->page_mode == SHADOW_PAGING)) {
+      handle_shadow_paging(info);
     */
-
+    
   } else if (exit_code == VMEXIT_INTR) {
 
     //    handle_svm_intr(info);
index 753bfcd..8cb45b4 100644 (file)
@@ -6,7 +6,7 @@
 struct vm_device * allocate_device() {
 
   struct vm_device * dev = NULL;
-  VMMMalloc(struct vm_device *, dev, sizeof(struct vm_device));
+  V3_Malloc(struct vm_device *, dev, sizeof(struct vm_device));
 
   dev->ops = NULL;
   memset(dev->name, 0, 32);
@@ -37,6 +37,6 @@ struct vm_device * create_device(char * name, struct vm_device_ops * ops, void *
 }
 
 void free_device(struct vm_device * dev) {
-  VMMFree(dev);
+  V3_Free(dev);
 }
 
index 2a458d0..bce853b 100644 (file)
@@ -304,7 +304,7 @@ int dev_mgr_hook_mem(struct guest_info    *vm,
 {
 
   struct dev_mem_hook *hook;
-  VMMMalloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
+  V3_Malloc(struct dev_mem_hook *, hook,sizeof(struct dev_mem_hook));
   
   if (!hook) { 
     return -1;
index f57bf39..9a9629f 100644 (file)
@@ -41,7 +41,7 @@ int add_io_hook(vmm_io_map_t * io_map, vmm_io_hook_t * io_hook) {
       //tmp_hook->read = io_hook->read;
       //tmp_hook->write = io_hook->write;
       
-      //VMMFree(io_hook);
+      //V3_Free(io_hook);
       return -1;
     } else {
       io_hook->prev = tmp_hook;
@@ -152,7 +152,7 @@ int hook_io_port(vmm_io_map_t * io_map, uint_t port,
   io_hook->priv_data = priv_data;
 
   if (add_io_hook(io_map, io_hook) != 0) {
-    VMMFree(io_hook);
+    V3_Free(io_hook);
     return -1;
   }
 
index 8210c72..1074245 100644 (file)
@@ -72,7 +72,7 @@ int hook_irq(struct vmm_irq_map * map, uint_t irq,
             void * private_data) {
 
   struct vmm_irq_hook * hook = NULL;
-  VMMMalloc(struct vmm_irq_hook *, hook, sizeof(struct vmm_irq_hook));
+  V3_Malloc(struct vmm_irq_hook *, hook, sizeof(struct vmm_irq_hook));
 
   if (!hook) {
     // big problems
@@ -86,7 +86,7 @@ int hook_irq(struct vmm_irq_map * map, uint_t irq,
   hook->prev = NULL;
   
   if (add_irq_hook(map, hook) != 0) {
-    VMMFree(hook);
+    V3_Free(hook);
     return -1;
   }
 
index cf18c10..39939a1 100644 (file)
@@ -49,10 +49,10 @@ void free_shadow_map(struct shadow_map * map) {
   while(cursor) {
     tmp = cursor;
     cursor = cursor->next;
-    VMMFree(tmp);
+    V3_Free(tmp);
   }
 
-  VMMFree(map);
+  V3_Free(map);
 }
 
 
@@ -155,6 +155,26 @@ shadow_region_t * get_shadow_region_by_addr(struct shadow_map * map,
 }
 
 
+host_region_type_t get_shadow_addr_type(struct guest_info * info, addr_t guest_addr) {
+  shadow_region_t * reg = get_shadow_region_by_addr(&(info->mem_map), guest_addr);
+
+  if (!reg) {
+    return HOST_REGION_INVALID;
+  } else {
+    return reg->host_type;
+  }
+}
+
+addr_t get_shadow_addr(struct guest_info * info, addr_t guest_addr) {
+  shadow_region_t * reg = get_shadow_region_by_addr(&(info->mem_map), guest_addr);
+
+  if (!reg) {
+    return 0;
+  } else {
+    return (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
+  }
+}
+
 
 host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr) {
   shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
index ac4fbbf..c437c4e 100644 (file)
@@ -174,7 +174,7 @@ pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info) {
 
 
 
-void PrintPDE32(void * virtual_address, pde32_t * pde)
+void PrintPDE32(addr_t virtual_address, pde32_t * pde)
 {
   PrintDebug("PDE %p -> %p : present=%x, flags=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
              virtual_address,
@@ -188,7 +188,7 @@ void PrintPDE32(void * virtual_address, pde32_t * pde)
              pde->vmm_info);
 }
   
-void PrintPTE32(void * virtual_address, pte32_t * pte)
+void PrintPTE32(addr_t virtual_address, pte32_t * pte)
 {
   PrintDebug("PTE %p -> %p : present=%x, flags=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
              virtual_address,
@@ -211,12 +211,12 @@ void PrintPD32(pde32_t * pde)
   PrintDebug("Page Directory at %p:\n", pde);
   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
     if ( pde[i].present) {
-      PrintPDE32((void*)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+      PrintPDE32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
     }
   }
 }
 
-void PrintPT32(void * starting_address, pte32_t * pte) 
+void PrintPT32(addr_t starting_address, pte32_t * pte) 
 {
   int i;
 
@@ -240,8 +240,8 @@ void PrintDebugPageTables(pde32_t * pde)
 
   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) { 
     if (pde[i].present) {
-      PrintPDE32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
-      PrintPT32((void *)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER));
+      PrintPDE32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), &(pde[i]));
+      PrintPT32((addr_t)(PAGE_SIZE * MAX_PTE32_ENTRIES * i), (pte32_t *)(pde[i].pt_base_addr << PAGE_POWER));
     }
   }
 }
index c9546e4..57fade1 100644 (file)
@@ -1,5 +1,6 @@
 #include <palacios/vmm_shadow_paging.h>
 
+
 #include <palacios/vmm.h>
 #include <palacios/vm_guest_mem.h>
 
@@ -10,200 +11,137 @@ int init_shadow_page_state(struct shadow_page_state * state) {
   state->guest_mode = PDE32;
   state->shadow_mode = PDE32;
   
-  state->guest_cr3.r_reg = 0;
-  state->shadow_cr3.r_reg = 0;
+  state->guest_cr3 = 0;
+  state->shadow_cr3 = 0;
 
   return 0;
 }
-  
 
-int wholesale_update_shadow_page_state(struct guest_info * guest_info) {
-  unsigned i, j;
-  pde32_t * guest_pde;
-  pde32_t * shadow_pde;
+int handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+  if (info->cpu_mode == PROTECTED_PG) {
+    return handle_shadow_pagefault32(info, fault_addr, error_code);
+  } else {
+    return -1;
+  }
+}
 
-  struct shadow_page_state * state = &(guest_info->shdw_pg_state);
 
+int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+  pde32_t * guest_pde = NULL;
+  pde32_t * shadow_pde = (pde32_t *)CR3_TO_PDE32(info->shdw_pg_state.shadow_cr3);
+  addr_t guest_cr3 = CR3_TO_PDE32(info->shdw_pg_state.guest_cr3);
 
-  // For now, we'll only work with PDE32
-  if (state->guest_mode != PDE32) { 
+  if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pde) == -1) {
     return -1;
   }
 
-  shadow_pde = (pde32_t *)(CR3_TO_PDE32(state->shadow_cr3.e_reg.low));  
-
-  if (host_pa_to_host_va(CR3_TO_PDE32(state->guest_cr3.e_reg.low), (addr_t*)&guest_pde) != 0) {
-    return -1;
+  if (error_code.present == 0) {
+    // Faulted because page was not present...
+    if (shadow_pde[PDE32_INDEX(fault_addr)].present) {
+      
+      
+    } else {
+      return -1;
+    }    
   }
 
-  // Delete the current page table
-  delete_page_tables_pde32(shadow_pde);
+  // Checks:
+  // Shadow PDE
+  // Guest PDE
+  // Shadow PTE
+  // Guest PTE
+  // Mem Map
+  
+  return -1;
+}
 
-  shadow_pde = os_hooks->allocate_pages(1);
 
-  state->shadow_cr3.e_reg.low = (addr_t)shadow_pde;
+addr_t create_new_shadow_pt32(struct guest_info * info) {
+  void * host_pde = 0;
 
-  state->shadow_mode = PDE32;
+  V3_AllocPages(host_pde, 1);
+  memset(host_pde, 0, PAGE_SIZE);
+
+  return (addr_t)host_pde;
+}
 
-  for (i = 0; i < MAX_PDE32_ENTRIES; i++) { 
-    shadow_pde[i] = guest_pde[i];
 
-    // The shadow can be identical to the guest if it's not present
-    if (!shadow_pde[i].present) { 
-      continue;
-    }
 
-    if (shadow_pde[i].large_pages) { 
-      // large page - just map it through shadow map to generate its physical location
-      addr_t guest_addr = PAGE_ADDR(shadow_pde[i].pt_base_addr);
-      addr_t host_addr;
-      shadow_region_t * ent;
 
-      ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
-      
-      if (!ent) { 
-       // FIXME Panic here - guest is trying to map to physical memory
-       // it does not own in any way!
-       return -1;
+addr_t setup_shadow_pt32(struct guest_info * info, addr_t virt_cr3) {
+  addr_t cr3_guest_addr = CR3_TO_PDE32(virt_cr3);
+  pde32_t * guest_pde;
+  pde32_t * host_pde = NULL;
+  int i;
+  
+  // Setup up guest_pde to point to the PageDir in host addr
+  if (guest_pa_to_host_va(info, cr3_guest_addr, (addr_t*)&guest_pde) == -1) {
+    return 0;
+  }
+  
+  V3_AllocPages(host_pde, 1);
+  memset(host_pde, 0, PAGE_SIZE);
+
+  for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
+    if (guest_pde[i].present == 1) {
+      addr_t pt_host_addr;
+      addr_t host_pte;
+
+      if (guest_pa_to_host_va(info, PDE32_T_ADDR(guest_pde[i]), &pt_host_addr) == -1) {
+       return 0;
       }
 
-      // FIXME Bounds check here to see if it's trying to trick us
-      
-      switch (ent->host_type) { 
-      case HOST_REGION_PHYSICAL_MEMORY:
-       // points into currently allocated physical memory, so we just
-       // set up the shadow to point to the mapped location
-       if (guest_pa_to_host_pa(guest_info, guest_addr, &host_addr)) { 
-         // Panic here
-         return -1;
-       }
-
-       shadow_pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(host_addr);
-       // FIXME set vmm_info bits here
-       break;
-      case HOST_REGION_UNALLOCATED:
-       // points to physical memory that is *allowed* but that we
-       // have not yet allocated.  We mark as not present and set a
-       // bit to remind us to allocate it later
-       shadow_pde[i].present = 0;
-       // FIXME Set vminfo bits here so that we know that we will be
-       // allocating it later
-       break;
-      case HOST_REGION_NOTHING:
-       // points to physical memory that is NOT ALLOWED.   
-       // We will mark it as not present and set a bit to remind
-       // us that it's bad later and insert a GPF then
-       shadow_pde[i].present = 0;
-       break;
-      case HOST_REGION_MEMORY_MAPPED_DEVICE:
-      case HOST_REGION_REMOTE:
-      case HOST_REGION_SWAPPED:
-      default:
-       // Panic.  Currently unhandled
-       return -1;
-       break;
+      if ((host_pte = setup_shadow_pte32(info, pt_host_addr)) == 0) {
+       return 0;
       }
-    } else {
-      pte32_t * guest_pte;
-      pte32_t * shadow_pte;
-      addr_t guest_addr;
-      addr_t guest_pte_host_addr;
-      shadow_region_t * ent;
 
-      // small page - set PDE and follow down to the child table
-      shadow_pde[i] = guest_pde[i];
+      host_pde[i].present = 1;
+      host_pde[i].pt_base_addr = PD32_BASE_ADDR(host_pte);
 
-      guest_addr = PAGE_ADDR(guest_pde[i].pt_base_addr);
+      //
+      // Set Page DIR flags
+      //
+    }
+  }
 
-      // Allocate a new second level page table for the shadow
-      shadow_pte = os_hooks->allocate_pages(1);
+  PrintDebugPageTables(host_pde);
 
-      // make our first level page table in the shadow point to it
-      shadow_pde[i].pt_base_addr = PAGE_ALIGNED_ADDR(shadow_pte);
-      
-      ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
-      
+  return (addr_t)host_pde;
+}
 
-      /* JRL: This is bad.... */
-      // For now the guest Page Table must always be mapped to host physical memory
-      /* If we swap out a page table or if it isn't present for some reason, this turns real ugly */
 
-      if ((!ent) || (ent->host_type != HOST_REGION_PHYSICAL_MEMORY)) { 
-       // FIXME Panic here - guest is trying to map to physical memory
-       // it does not own in any way!
-       return -1;
-      }
 
-      // Address of the relevant second level page table in the guest
-      if (guest_pa_to_host_pa(guest_info, guest_addr, &guest_pte_host_addr)) { 
-       // Panic here
-       return -1;
-      }
+addr_t setup_shadow_pte32(struct guest_info * info, addr_t pt_host_addr) {
+  pte32_t * guest_pte = (pte32_t *)pt_host_addr;
+  pte32_t * host_pte = NULL;
+  int i;
 
+  V3_AllocPages(host_pte, 1);
+  memset(host_pte, 0, PAGE_SIZE);
 
-      // host_addr now contains the host physical address for the guest's 2nd level page table
-      // Now we transform it to relevant virtual address
-      guest_pte = os_hooks->paddr_to_vaddr((void *)guest_pte_host_addr);
+  for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
+    if (guest_pte[i].present == 1) {
+      addr_t guest_pa = PTE32_T_ADDR(guest_pte[i]);
+      shadow_mem_type_t page_type;
+      addr_t host_pa = 0;
 
-      // Now we walk through the second level guest page table
-      // and clone it into the shadow
-      for (j = 0; j < MAX_PTE32_ENTRIES; j++) { 
-       shadow_pte[j] = guest_pte[j];
+      page_type = get_shadow_addr_type(info, guest_pa);
 
-       addr_t guest_addr = PAGE_ADDR(shadow_pte[j].page_base_addr);
+      if (page_type == HOST_REGION_PHYSICAL_MEMORY) {
+       host_pa = get_shadow_addr(info, guest_pa);
+      } else {
        
-       shadow_region_t * ent;
-
-       ent = get_shadow_region_by_addr(&(guest_info->mem_map), guest_addr);
-      
-       if (!ent) { 
-         // FIXME Panic here - guest is trying to map to physical memory
-         // it does not own in any way!
-         return -1;
-       }
-
-       switch (ent->host_type) { 
-       case HOST_REGION_PHYSICAL_MEMORY:
-         {
-           addr_t host_addr;
-           
-           // points into currently allocated physical memory, so we just
-           // set up the shadow to point to the mapped location
-           if (guest_pa_to_host_pa(guest_info, guest_addr, &host_addr)) { 
-             // Panic here
-             return -1;
-           }
-           
-           shadow_pte[j].page_base_addr = PAGE_ALIGNED_ADDR(host_addr);
-           // FIXME set vmm_info bits here
-           break;
-         }
-       case HOST_REGION_UNALLOCATED:
-         // points to physical memory that is *allowed* but that we
-         // have not yet allocated.  We mark as not present and set a
-         // bit to remind us to allocate it later
-         shadow_pte[j].present = 0;
-         // FIXME Set vminfo bits here so that we know that we will be
-         // allocating it later
-         break;
-       case HOST_REGION_NOTHING:
-         // points to physical memory that is NOT ALLOWED.   
-         // We will mark it as not present and set a bit to remind
-         // us that it's bad later and insert a GPF then
-         shadow_pte[j].present = 0;
-         break;
-       case HOST_REGION_MEMORY_MAPPED_DEVICE:
-       case HOST_REGION_REMOTE:
-       case HOST_REGION_SWAPPED:
-       default:
-         // Panic.  Currently unhandled
-         return -1;
-       break;
-       }
+       //
+       // Setup various memory types
+       //
       }
+
+      host_pte[i].page_base_addr = PT32_BASE_ADDR(host_pa);
+      host_pte[i].present = 1;
     }
   }
-  return 0;
+
+  return (addr_t)host_pte;
 }
-      
+