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.


fixes to the emulator to handle nested paging
Jack Lange [Wed, 25 Mar 2009 23:43:30 +0000 (18:43 -0500)]
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vmm_emulator.c
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_xed.c

index d5faa6c..c981a3c 100644 (file)
@@ -63,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 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) {
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 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",