From: Jack Lange Date: Tue, 1 Jul 2008 00:12:44 +0000 (+0000) Subject: moved further along in the boot process.... X-Git-Tag: boot386puppy-26-to-ide~8 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=684409c4ad29c0f06167bebf2bb51e21374a6840 moved further along in the boot process.... Bombing due to unhandled large page, and gruesome hack to vm_guest_mem.c --- diff --git a/palacios/src/palacios/vm_guest_mem.c b/palacios/src/palacios/vm_guest_mem.c index 70914b4..eb342b4 100644 --- a/palacios/src/palacios/vm_guest_mem.c +++ b/palacios/src/palacios/vm_guest_mem.c @@ -122,6 +122,8 @@ int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t return 0; } + + // Guest Is in Paged mode switch (guest_info->cpu_mode) { case PROTECTED: @@ -130,6 +132,7 @@ int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t pde32_t * pde = 0; addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3); + if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) { PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PDE32 lookup\n", guest_pde); return -1; @@ -318,10 +321,41 @@ int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int co int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge; addr_t host_addr = 0; - if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) { + + + /* JRL FIXME: + * This should be somewhere else.... + */ + addr_t tmp_addr; + + addr_t shadow_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.shadow_cr3); + + // Check the Shadow Page Tables first (Virtual TLB) + if (pt32_lookup((pde32_t *)shadow_pde, cursor, &tmp_addr) == 0) { + host_addr = tmp_addr; + + if (host_pa_to_host_va(tmp_addr, &host_addr) != 0) { + return bytes_read; + } + } else { + + // No entry in the VTLB, do a guest page table walk + + if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) { + PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor); + return bytes_read; + } + } + /* JRL: END GRUESOME HACK */ + + + /* + if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) { PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor); return bytes_read; - } + } + */ + memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy); @@ -352,8 +386,7 @@ int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int co if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) { return bytes_read; - } - + } /* PrintDebug("Trying to read %d bytes\n", bytes_to_copy); diff --git a/palacios/src/palacios/vmm_ctrl_regs.c b/palacios/src/palacios/vmm_ctrl_regs.c index 82853bc..58d0465 100644 --- a/palacios/src/palacios/vmm_ctrl_regs.c +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@ -578,19 +578,29 @@ int handle_cr3_write(struct guest_info * info) { /* Delete the current Page Tables */ delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3)); + PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n", + info->shdw_pg_state.shadow_cr3, 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); + PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n", + info->shdw_pg_state.shadow_cr3, info->shdw_pg_state.guest_cr3); + + if (info->mem_mode == VIRTUAL_MEM) { // If we aren't in paged mode then we have to preserve the identity mapped CR3 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3; diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index e1dbfd8..9582232 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -34,7 +34,7 @@ int hook_irq(struct guest_info * info, int irq) { int raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) { struct vm_intr * intr_state = &(info->intr_state); - if (intr_state->excp_pending) { + if (intr_state->excp_pending == 0) { intr_state->excp_pending = 1; intr_state->excp_num = excp; intr_state->excp_error_code = error_code; @@ -91,9 +91,9 @@ int raise_irq(struct guest_info * info, int irq) { int intr_pending(struct guest_info * info) { struct vm_intr * intr_state = &(info->intr_state); - if (intr_state->excp_pending) { + if (intr_state->excp_pending == 1) { return 1; - } else if (intr_state->controller->intr_pending(intr_state->controller_state)) { + } else if (intr_state->controller->intr_pending(intr_state->controller_state) == 1) { return 1; } @@ -106,7 +106,7 @@ int intr_pending(struct guest_info * info) { uint_t get_intr_number(struct guest_info * info) { struct vm_intr * intr_state = &(info->intr_state); - if (intr_state->excp_pending) { + if (intr_state->excp_pending == 1) { return intr_state->excp_num; } else if (intr_state->controller->intr_pending(intr_state->controller_state)) { return intr_state->controller->get_intr_number(intr_state->controller_state); diff --git a/palacios/src/palacios/vmm_paging.c b/palacios/src/palacios/vmm_paging.c index 7c8d8af..8eefd53 100644 --- a/palacios/src/palacios/vmm_paging.c +++ b/palacios/src/palacios/vmm_paging.c @@ -38,6 +38,26 @@ void delete_page_tables_pde32(pde32_t * pde) { +int pt32_lookup(pde32_t * pd, addr_t vaddr, addr_t * paddr) { + addr_t pde_entry; + pde32_entry_type_t pde_entry_type; + + if (pd == 0) { + return -1; + } + + pde_entry_type = pde32_lookup(pd, vaddr, &pde_entry); + + if (pde_entry_type == PDE32_ENTRY_PTE32) { + return pte32_lookup((pte32_t *)pde_entry, vaddr, paddr); + } else if (pde_entry_type == PDE32_ENTRY_LARGE_PAGE) { + *paddr = pde_entry; + return 0; + } + + return -1; +} + /* We can't do a full lookup because we don't know what context the page tables are in... diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index 360e532..a2f09f9 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -69,6 +69,7 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er info->ctrl_regs.cr2 = fault_addr; raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code); + PrintDebug("Injecting PDE pf to guest\n"); return 0; } @@ -102,6 +103,10 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er * Check the Intel manual because we are ignoring Large Page issues here * Also be wary of hooked pages */ + + PrintDebug("Large PAge!!!\n"); + return -1; + } } else if (shadow_pde_access == PT_WRITE_ERROR) { @@ -154,7 +159,7 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er } //PrintDebugPageTables(shadow_pde); - + PrintDebug("Returning end of PDE function\n"); return 0; } @@ -185,6 +190,7 @@ int handle_shadow_pte32_fault(struct guest_info * info, info->ctrl_regs.cr2 = fault_addr; raise_exception_with_error(info, PF_EXCEPTION, *(uint_t *)&error_code); + PrintDebug("Access error injecting pf to guest\n"); return 0; } @@ -194,6 +200,7 @@ int handle_shadow_pte32_fault(struct guest_info * info, if (shadow_pte_access == PT_ACCESS_OK) { // Inconsistent state... // Guest Re-Entry will flush page tables and everything should now work + PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n"); return 0; } else if (shadow_pte_access == PT_ENTRY_NOT_PRESENT) { addr_t shadow_pa; @@ -249,6 +256,8 @@ int handle_shadow_pte32_fault(struct guest_info * info, guest_pte_entry->dirty = 1; shadow_pte_entry->writable = guest_pte_entry->writable; + PrintDebug("Shadow PTE Write Error\n"); + return 0; } else { // Inject page fault into the guest @@ -261,6 +270,7 @@ int handle_shadow_pte32_fault(struct guest_info * info, return -1; } + PrintDebug("Returning end of function\n"); return 0; }