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.


bug fixes for:
Jack Lange [Sat, 7 Feb 2009 01:11:04 +0000 (19:11 -0600)]
xed decoder
passthrough paging
emulator

added apic memory hooks

palacios/include/palacios/vmm_direct_paging.h
palacios/src/devices/apic.c
palacios/src/palacios/vmm_direct_paging.c
palacios/src/palacios/vmm_direct_paging_32.h
palacios/src/palacios/vmm_emulator.c
palacios/src/palacios/vmm_shadow_paging.c
palacios/src/palacios/vmm_xed.c

index c33833a..00eac31 100644 (file)
@@ -8,7 +8,7 @@
 
 pde32_t * v3_create_direct_passthrough_pts(struct guest_info * guest_info);
 
-int v3_handle_shadow_pagefault_physical_mode(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
+int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code);
 
 #endif // ! __V3VEE__
 
index 8f4b8fe..f899419 100644 (file)
 #include <palacios/vmm_msr.h>
 
 #define BASE_ADDR_MSR 0x0000001B
+#define DEFAULT_BASE_ADDR 0xfee00000
 
 
+struct apic_base_addr_reg {
+  uchar_t rsvd;
+  uint_t bsc           : 1;
+  uint_t rsvd2         : 2;
+  uint_t apic_enable   : 1;
+  ullong_t base_addr   : 40;
+  uint_t rsvd3         : 12;
+} __attribute__((packed));
+
 struct apic_state {
+  addr_t base_addr;
+
   v3_msr_t base_addr_reg;
 
+  
+
 };
 
 
-static int read_base_addr(uint_t msr, v3_msr_t * dst, void * priv_data) {
+static int read_apic_msr(uint_t msr, v3_msr_t * dst, void * priv_data) {
   struct vm_device * dev = (struct vm_device *)priv_data;
   struct apic_state * apic = (struct apic_state *)dev->private_data;
   PrintDebug("READING APIC BASE ADDR: HI=%x LO=%x\n", apic->base_addr_reg.hi, apic->base_addr_reg.lo);
@@ -40,7 +54,7 @@ static int read_base_addr(uint_t msr, v3_msr_t * dst, void * priv_data) {
 }
 
 
-static int write_base_addr(uint_t msr, v3_msr_t src, void * priv_data) {
+static int write_apic_msr(uint_t msr, v3_msr_t src, void * priv_data) {
   //  struct vm_device * dev = (struct vm_device *)priv_data;
   //  struct apic_state * apic = (struct apic_state *)dev->private_data;
 
@@ -50,6 +64,18 @@ static int write_base_addr(uint_t msr, v3_msr_t src, void * priv_data) {
 }
 
 
+static int apic_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+  PrintDebug("Read from apic address space\n");
+  return -1;
+}
+
+
+static int apic_write(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
+  PrintDebug("Write to apic address space\n");
+  return -1;
+}
+
+
 static int apic_deinit(struct vm_device * dev) {
   struct guest_info * info = dev->vm;
 
@@ -61,8 +87,13 @@ static int apic_deinit(struct vm_device * dev) {
 
 static int apic_init(struct vm_device * dev) {
   struct guest_info * info = dev->vm;
+  struct apic_state * apic = (struct apic_state *)(dev->private_data);
+
+  apic->base_addr = DEFAULT_BASE_ADDR;
+
+  v3_hook_msr(info, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
 
-  v3_hook_msr(info, BASE_ADDR_MSR, read_base_addr, write_base_addr, dev);
+  v3_hook_full_mem(info, DEFAULT_BASE_ADDR, DEFAULT_BASE_ADDR + PAGE_SIZE_4KB, apic_read, apic_write, dev);
 
   return 0;
 }
index c197c4c..44742cb 100644 (file)
@@ -1,19 +1,20 @@
 #include <palacios/vmm_direct_paging.h>
-
-// Inline handler functions for each cpu mode
-#include "vmm_direct_paging_32.h"
-
 #include <palacios/vmm_paging.h>
 #include <palacios/vmm.h>
 #include <palacios/vm_guest_mem.h>
 #include <palacios/vm_guest.h>
 
+
+
+// Inline handler functions for each cpu mode
+#include "vmm_direct_paging_32.h"
+
 pde32_t * v3_create_direct_passthrough_pts(struct guest_info * info) {
   v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
   switch(mode) {
     case REAL:
     case PROTECTED:
-      return v3_create_direct_passthrough_pts_32(info);
+      return create_direct_passthrough_pts_32(info);
     case PROTECTED_PAE:
       break;
     case LONG:
@@ -27,12 +28,13 @@ pde32_t * v3_create_direct_passthrough_pts(struct guest_info * info) {
   return NULL;
 }
 
-int v3_handle_shadow_pagefault_physical_mode(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+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:
-      return v3_handle_shadow_pagefault_physical_mode_32(info, fault_addr, error_code);
+      return handle_passthrough_pagefault_32(info, fault_addr, error_code);
     case PROTECTED_PAE:
       break;
     case LONG:
index d075e74..2b34cf2 100644 (file)
@@ -25,52 +25,67 @@ static pte32_t * create_pte32() {
 }
 
 
-static inline pde32_t * v3_create_direct_passthrough_pts_32(struct guest_info * info) {
+static inline pde32_t * create_direct_passthrough_pts_32(struct guest_info * info) {
   return create_pde32();
 }
 
 
-static inline int v3_handle_shadow_pagefault_physical_mode_32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+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);
   int pde_index = PDE32_INDEX(fault_addr);
   int pte_index = PTE32_INDEX(fault_addr);
-  if(pde[pde_index].present != 1) {
+
+  if (pde[pde_index].present != 1) {
+
     PrintError("Creating new page table for PTE index: %d\n", pde_index);
+
     pte32_t * pte = create_pte32();
     addr_t host_addr;
+
     if(guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
+
     struct v3_shadow_region * region =  v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
+
+    pte[pte_index].present = 1;
+    pte[pte_index].writable = 1;
+    pte[pte_index].user_page = 1;
+    pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
+    
+    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));
+    
+    if (region->host_type == SHDW_REGION_WRITE_HOOK) {
+      pte[pte_index].writable = 0;
+    }
+    
+    PrintError("Fault Addr: 0x%p\nHost Addr: 0x%p\n", (void*)fault_addr, (void*)host_addr);
+    
+  } else {
+    pte32_t * pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
+    
+    if (pte[pte_index].present != 1) {
+      addr_t host_addr;
+      
+      if (guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
+      
+      struct v3_shadow_region * region =  v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
+      
       pte[pte_index].present = 1;
       pte[pte_index].writable = 1;
       pte[pte_index].user_page = 1;
       pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
-
-      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));
-      if(region->host_type == SHDW_REGION_WRITE_HOOK) {
+      
+      if (region->host_type == SHDW_REGION_WRITE_HOOK) {
        pte[pte_index].writable = 0;
       }
-      PrintError("Fault Addr: 0x%p\nHost Addr: 0x%p\n", (void*)fault_addr, (void*)host_addr);
-    }
-    else {
-      pte32_t * pte = (void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr);
-      if(pte[pte_index].present != 1) {
-       addr_t host_addr;
-       if(guest_pa_to_host_pa(info, fault_addr, &host_addr) == -1) return -1;
-       struct v3_shadow_region * region =  v3_get_shadow_region(info, PAGE_BASE_ADDR(host_addr));
-       pte[pte_index].present = 1;
-       pte[pte_index].writable = 1;
-       pte[pte_index].user_page = 1;
-       pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
-       if(region->host_type == SHDW_REGION_WRITE_HOOK) {
-         pte[pte_index].writable = 0;
-       }
-      }
     }
-    return 0;
+  }
+  return 0;
 }
 
 
index 2870ba0..9d166c4 100644 (file)
@@ -93,16 +93,17 @@ static int emulate_string_write_op(struct guest_info * info, struct x86_instr *
 
 
     if (dec_instr->dst_operand.size == 1) {
-      movs8((addr_t *)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+      movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
     } else if (dec_instr->dst_operand.size == 2) {
-      movs16((addr_t *)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+      movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
     } else if (dec_instr->dst_operand.size == 4) {
-      movs32((addr_t*)dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
+      movs32((addr_t*)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
     } else {
       PrintError("Invalid operand length\n");
       return -1;
     }
 
+    PrintDebug("Calling Write function\n");
 
     if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
       PrintError("Did not fully read hooked data\n");
@@ -232,7 +233,7 @@ int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gp
   int op_len = 0;
 
   PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
-  PrintDebug("GVA=%p\n", (void *)write_gva);
+  PrintDebug("GVA=%p\n", (void *)read_gva);
 
   if (info->mem_mode == PHYSICAL_MEM) { 
     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
index 3ae28d4..2475734 100644 (file)
@@ -129,7 +129,7 @@ int v3_handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_e
   
   if (v3_get_mem_mode(info) == PHYSICAL_MEM) {
     // If paging is not turned on we need to handle the special cases
-    return v3_handle_shadow_pagefault_physical_mode(info, fault_addr, error_code);
+    return v3_handle_passthrough_pagefault(info, fault_addr, error_code);
   } else if (v3_get_mem_mode(info) == VIRTUAL_MEM) {
 
     switch (v3_get_cpu_mode(info)) {
index e6de1e1..5975797 100644 (file)
@@ -112,7 +112,6 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
    break;
   case PROTECTED:
   case PROTECTED_PAE:
-  case LONG_32_COMPAT:
     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
       xed_state_init(state,
                     XED_MACHINE_MODE_LEGACY_32, 
@@ -120,9 +119,23 @@ static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
                     XED_ADDRESS_WIDTH_32b);
     }
     break;
+  case LONG_32_COMPAT:
+    if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
+      xed_state_init(state,
+                    XED_MACHINE_MODE_LONG_COMPAT_32, 
+                    XED_ADDRESS_WIDTH_32b, 
+                    XED_ADDRESS_WIDTH_32b);
+    }
+    break;
   case LONG:
-    if (state->mmode != XED_MACHINE_MODE_LONG_64) {    
-      state->mmode = XED_MACHINE_MODE_LONG_64;
+    if (state->mmode != XED_MACHINE_MODE_LONG_64) {
+      PrintDebug("Setting decoder to long mode\n");
+      //      state->mmode = XED_MACHINE_MODE_LONG_64;
+      //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
+      xed_state_init(state,
+                    XED_MACHINE_MODE_LONG_64, 
+                    XED_ADDRESS_WIDTH_64b, 
+                    XED_ADDRESS_WIDTH_64b);
     }
     break;
   default:
@@ -154,6 +167,10 @@ int v3_init_decoder(struct guest_info * info) {
 
   xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
   xed_state_zero(decoder_state);
+  xed_state_init(decoder_state,
+                XED_MACHINE_MODE_LEGACY_32, 
+                XED_ADDRESS_WIDTH_32b, 
+                XED_ADDRESS_WIDTH_32b);
 
   info->decoder_state = decoder_state;
 
@@ -527,8 +544,11 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
   ullong_t displacement;
   // struct v3_segment * seg_reg;
 
-
-
+  PrintDebug("Xen 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",
+            xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
 
   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
 
@@ -596,7 +616,8 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
   base = MASK(mem_op.base, mem_op.base_size);
   index = MASK(mem_op.index, mem_op.index_size);
   scale = mem_op.scale;
-  displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+  // displacement = MASK(mem_op.displacement, mem_op.displacement_size);
+  displacement = mem_op.displacement;
 
   PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
             (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
@@ -608,7 +629,7 @@ static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xe
 
 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
 
-  // PrintError("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
+  PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
 
   switch (xed_reg) {
   case XED_REG_INVALID: