X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_ctrl_regs.c;h=69d51ffab62e464b8695138e8693415ac1859ee4;hb=d4073a9dbe24ae160b8d6bd8fd5fd4ad8aa995a3;hp=4b0ff6595f529f1019b0d983c7d722e9258ff7d2;hpb=c3b81025fc7957141b1bc8d790f5850f008cc289;p=palacios.git diff --git a/palacios/src/palacios/vmm_ctrl_regs.c b/palacios/src/palacios/vmm_ctrl_regs.c index 4b0ff65..69d51ff 100644 --- a/palacios/src/palacios/vmm_ctrl_regs.c +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@ -9,6 +9,81 @@ extern void SerialMemDump(unsigned char *start, int n); + +#if VMM_DEBUG +void PrintCtrlRegs(struct guest_info *info) +{ + struct cr0_32 cr0 = *((struct cr0_32 *) &(info->ctrl_regs.cr0)); + struct cr2_32 cr2 = *((struct cr2_32 *) &(info->ctrl_regs.cr2)); + struct cr3_32 cr3 = *((struct cr3_32 *) &(info->ctrl_regs.cr3)); + struct cr4_32 cr4 = *((struct cr4_32 *) &(info->ctrl_regs.cr4)); + struct rflags rflags = *((struct rflags *) &(info->ctrl_regs.rflags)); + + PrintDebug("CR0: pe 0x%x\n",cr0.pe); + PrintDebug("CR0: mp 0x%x\n",cr0.mp); + PrintDebug("CR0: em 0x%x\n",cr0.em); + PrintDebug("CR0: ts 0x%x\n",cr0.ts); + PrintDebug("CR0: et 0x%x\n",cr0.et); + PrintDebug("CR0: ne 0x%x\n",cr0.ne); + PrintDebug("CR0: rsvd1 0x%x\n",cr0.rsvd1); + PrintDebug("CR0: wp 0x%x\n",cr0.wp); + PrintDebug("CR0: rsvd2 0x%x\n",cr0.rsvd2); + PrintDebug("CR0: am 0x%x\n",cr0.am); + PrintDebug("CR0: rsvd3 0x%x\n",cr0.rsvd3); + PrintDebug("CR0: nw 0x%x\n",cr0.nw); + PrintDebug("CR0: cd 0x%x\n",cr0.cd); + PrintDebug("CR0: pg 0x%x\n",cr0.pg); + + PrintDebug("CR2: pfadd 0x%x\n",cr2.pf_vaddr); + + PrintDebug("CR3: rsvd1 0x%x\n",cr3.rsvd1); + PrintDebug("CR3: pwt 0x%x\n",cr3.pwt); + PrintDebug("CR3: pcd 0x%x\n",cr3.pcd); + PrintDebug("CR3: rsvd2 0x%x\n",cr3.rsvd2); + PrintDebug("CR3: pdt 0x%x\n",cr3.pdt_base_addr); + + PrintDebug("CR4: vme 0x%x\n",cr4.vme); + PrintDebug("CR4: pvi 0x%x\n",cr4.pvi); + PrintDebug("CR4: tsd 0x%x\n",cr4.tsd); + PrintDebug("CR4: de 0x%x\n",cr4.de); + PrintDebug("CR4: pse 0x%x\n",cr4.pse); + PrintDebug("CR4: pae 0x%x\n",cr4.pae); + PrintDebug("CR4: mce 0x%x\n",cr4.mce); + PrintDebug("CR4: pge 0x%x\n",cr4.pge); + PrintDebug("CR4: pce 0x%x\n",cr4.pce); + PrintDebug("CR4: osfx 0x%x\n",cr4.osf_xsr); + PrintDebug("CR4: osx 0x%x\n",cr4.osx); + PrintDebug("CR4: rsvd1 0x%x\n",cr4.rsvd1); + + PrintDebug("RFLAGS: cf 0x%x\n",rflags.cf); + PrintDebug("RFLAGS: rsvd1 0x%x\n",rflags.rsvd1); + PrintDebug("RFLAGS: pf 0x%x\n",rflags.pf); + PrintDebug("RFLAGS: rsvd2 0x%x\n",rflags.rsvd2); + PrintDebug("RFLAGS: af 0x%x\n",rflags.af); + PrintDebug("RFLAGS: rsvd3 0x%x\n",rflags.rsvd3); + PrintDebug("RFLAGS: zf 0x%x\n",rflags.zf); + PrintDebug("RFLAGS: sf 0x%x\n",rflags.sf); + PrintDebug("RFLAGS: tf 0x%x\n",rflags.tf); + PrintDebug("RFLAGS: intr 0x%x\n",rflags.intr); + PrintDebug("RFLAGS: df 0x%x\n",rflags.df); + PrintDebug("RFLAGS: of 0x%x\n",rflags.of); + PrintDebug("RFLAGS: iopl 0x%x\n",rflags.iopl); + PrintDebug("RFLAGS: nt 0x%x\n",rflags.nt); + PrintDebug("RFLAGS: rsvd4 0x%x\n",rflags.rsvd4); + PrintDebug("RFLAGS: rf 0x%x\n",rflags.rf); + PrintDebug("RFLAGS: vm 0x%x\n",rflags.vm); + PrintDebug("RFLAGS: ac 0x%x\n",rflags.ac); + PrintDebug("RFLAGS: vif 0x%x\n",rflags.vif); + PrintDebug("RFLAGS: id 0x%x\n",rflags.id); + PrintDebug("RFLAGS: rsvd5 0x%x\n",rflags.rsvd5); + PrintDebug("RFLAGS: rsvd6 0x%x\n",rflags.rsvd6); + +} +#else +void PrintCtrlRegs(struct guest_info *info) +{} +#endif + /* Segmentation is a problem here... * * When we get a memory operand, presumably we use the default segment (which is?) @@ -98,6 +173,7 @@ int handle_cr0_write(struct guest_info * info) { *(char*)shadow_cr0 &= 0xf0; *(char*)shadow_cr0 |= new_cr0_val; + PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0); } else { PrintDebug("Old CR0=%x\n", *real_cr0); @@ -165,8 +241,10 @@ int handle_cr0_write(struct guest_info * info) { PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0); *real_cr0 = *new_cr0; real_cr0->pg = 1; + real_cr0->et = 1; *shadow_cr0 = *new_cr0; + shadow_cr0->et = 1; PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0); } else { @@ -207,6 +285,7 @@ int handle_cr0_write(struct guest_info * info) { ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr); } + if (ret != 15) { // I think we should inject a GPF into the guest PrintDebug("Could not read instruction (ret=%d)\n", ret); @@ -233,6 +312,9 @@ int handle_cr0_write(struct guest_info * info) { index += 2; + PrintDebug("MovToCR0 instr:\n"); + PrintTraceMemDump(instr, 15); + PrintDebug("EAX=%x\n", *(uint_t*)&(info->vm_regs.rax)); addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32); @@ -243,7 +325,7 @@ int handle_cr0_write(struct guest_info * info) { new_cr0 = (struct cr0_32 *)first_operand; - + PrintDebug("first operand=%x\n", *(uint_t *)first_operand); if (info->shdw_pg_mode == SHADOW_PAGING) { struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0); @@ -258,6 +340,8 @@ int handle_cr0_write(struct guest_info * info) { *shadow_cr0 = *new_cr0; *real_cr0 = *new_cr0; + shadow_cr0->et = 1; + real_cr0->et = 1; // // Activate Shadow Paging @@ -269,10 +353,25 @@ int handle_cr0_write(struct guest_info * info) { } else if (new_cr0->pe == 0) { info->cpu_mode = REAL; + info->mem_mode = PHYSICAL_MEM; + PrintDebug("Entering Real Mode\n"); + + PrintV3CtrlRegs(&(info->ctrl_regs)); + // reinstate the identity mapped paged tables + // But keep the shadow tables around to handle TLB issues.... UGH... + //info->shdw_pg_state.shadow_cr3 &= 0x00000fff; + //info->shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff); + + //info->ctrl_regs.cr3 = info->shdw_pg_state.shadow_cr3; + info->ctrl_regs.cr3 = ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff); + *shadow_cr0 = *new_cr0; *real_cr0 = *new_cr0; real_cr0->pg = 1; + shadow_cr0->et = 1; + real_cr0->et = 1; + } @@ -286,8 +385,8 @@ int handle_cr0_write(struct guest_info * info) { (instr[index + 1] == 0x06)) { // CLTS instruction PrintDebug("CLTS instruction - clearing TS flag of real and shadow CR0\n"); - shadow_cr0->ts=0; - real_cr0->ts=0; + shadow_cr0->ts = 0; + real_cr0->ts = 0; index+=2; @@ -489,9 +588,15 @@ int handle_cr0_read(struct guest_info * info) { if (info->shdw_pg_mode == SHADOW_PAGING) { *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0); - if (info->cpu_mode==PROTECTED) { - virt_cr0->pg=0; // clear the pg bit because guest doesn't think it's on + + if (info->mem_mode == PHYSICAL_MEM) { + virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on } + + PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0); + PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0); + + } else { *virt_cr0 = *real_cr0; } @@ -587,6 +692,11 @@ int handle_cr3_write(struct guest_info * info) { struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3); + if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) { + PrintDebug("Shadow Page Table\n"); + PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3)); + } + /* Delete the current Page Tables */ delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3)); @@ -605,6 +715,14 @@ int handle_cr3_write(struct guest_info * info) { /* Copy Various flags */ *shadow_cr3 = *new_cr3; + { + addr_t tmp_addr; + guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr); + PrintDebug("Guest PD\n"); + PrintPD32((pde32_t *)tmp_addr); + + } + shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt); @@ -639,7 +757,38 @@ int handle_cr3_write(struct guest_info * info) { int handle_cr3_read(struct guest_info * info) { - if (info->cpu_mode == PROTECTED) { + + if (info->cpu_mode == REAL) { + // what does this mean??? + + /* + + addr_t host_addr; + addr_t linear_addr = 0; + + + + linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); + + + PrintDebug("RIP Linear: %x\n", linear_addr); + PrintV3Segments(&(info->segments)); + + + if (info->mem_mode == PHYSICAL_MEM) { + guest_pa_to_host_pa(info, linear_addr, &host_addr); + } else if (info->mem_mode == VIRTUAL_MEM) { + guest_va_to_host_pa(info, linear_addr, &host_addr); + } + + + pt32_lookup((pde32_t *)CR3_TO_PDE32(info->shdw_pg_state.shadow_cr3), , addr_t * paddr); + */ + + + return -1; + } else if (info->cpu_mode == PROTECTED) { + int index = 0; int ret; char instr[15]; @@ -696,7 +845,8 @@ int handle_cr3_read(struct guest_info * info) { return -1; } } else { - PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode); + PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode); + PrintCtrlRegs(info); return -1; }