From: Jack Lange Date: Wed, 25 Mar 2009 19:58:17 +0000 (-0500) Subject: Revert "breaking shadow paging to handle speculative page mapping" X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=61d51be2ae5c4ba6d6824204d5a7136f21dd7d38 Revert "breaking shadow paging to handle speculative page mapping" This reverts commit 35b12c60af3cecffd00068990e61ab6fa01d49fe. --- diff --git a/manual/manual.pdf b/manual/manual.pdf index 78e5043..887fd33 100644 Binary files a/manual/manual.pdf and b/manual/manual.pdf differ diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index 91004f9..8074c16 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -30,14 +30,6 @@ #include - -// set this to 1 if you want us to attempt to -// fetch multiple entries on a page fault -#define SPECULATIVE_PAGING 1 - -#define REGULAR_PAGE_FAULT 0 -#define SPECULATIVE_PAGE_FAULT 1 - #ifndef DEBUG_SHADOW_PAGING #undef PrintDebug #define PrintDebug(fmt, args...) @@ -134,7 +126,6 @@ int v3_activate_passthrough_pt(struct guest_info * info) { int v3_handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) { - int rc; if (v3_get_mem_mode(info) == PHYSICAL_MEM) { // If paging is not turned on we need to handle the special cases @@ -143,38 +134,14 @@ int v3_handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_e switch (v3_get_cpu_mode(info)) { case PROTECTED: - return handle_shadow_pagefault_32(info, fault_addr, error_code); + return handle_shadow_pagefault_32(info, fault_addr, error_code); break; case PROTECTED_PAE: return handle_shadow_pagefault_32pae(info, fault_addr, error_code); case LONG: case LONG_32_COMPAT: - case LONG_16_COMPAT: { - addr_t curr_addr; - addr_t fault_addr_base; - // first, we will handle the actual fault, non-speculatively - rc=handle_shadow_pagefault_64(info, fault_addr, error_code, REGULAR_PAGE_FAULT); - if (rc) { - return -1; - } - if (!SPECULATIVE_PAGING) { - return 0; - } - fault_addr_base=PAGE_ADDR_4KB(fault_addr); - PrintDebug("Attempting speculative paging around %p\n",(void*)fault_addr_base); - for (curr_addr = (fault_addr_base & (~0x1fffffLL)) ; - curr_addr < (fault_addr_base | (0x1fffffLL)) ; - curr_addr+=PAGE_SIZE) { - if (curr_addr!=fault_addr_base) { - rc=handle_shadow_pagefault_64(info, curr_addr, error_code, SPECULATIVE_PAGE_FAULT); - if (rc) { - PrintDebug("Speculative page fault handler failed at %p\n",(void*)curr_addr); - return -1; - } - } - } - return 0; - } + case LONG_16_COMPAT: + return handle_shadow_pagefault_64(info, fault_addr, error_code); break; default: PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info))); diff --git a/palacios/src/palacios/vmm_shadow_paging_64.h b/palacios/src/palacios/vmm_shadow_paging_64.h index b75f358..f0dcd31 100644 --- a/palacios/src/palacios/vmm_shadow_paging_64.h +++ b/palacios/src/palacios/vmm_shadow_paging_64.h @@ -53,19 +53,19 @@ static inline int activate_shadow_pt_64(struct guest_info * info) { */ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde, int speculative); + pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde); static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pte64_t * shadow_pt, pte64_t * guest_pt, int speculative); + pte64_t * shadow_pt, pte64_t * guest_pt); static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pde64_t * shadow_pd, pde64_t * guest_pd, int speculative); + pde64_t * shadow_pd, pde64_t * guest_pd); static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp, int speculative); + pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp); -static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, int speculative) { +static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) { pml4e64_t * guest_pml = NULL; pml4e64_t * shadow_pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3); addr_t guest_cr3 = CR3_TO_PML4E64_PA(info->shdw_pg_state.guest_cr3); @@ -96,9 +96,7 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa if (is_guest_pf(guest_pml4e_access, shadow_pml4e_access) == 1) { PrintDebug("Injecting PML4E pf to guest: (guest access error=%d) (pf error code=%d)\n", *(uint_t *)&guest_pml4e_access, *(uint_t *)&error_code); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } @@ -108,16 +106,12 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa // PrintDebug("Shadow Paging User access error (shadow_pml4e_access=0x%x, guest_pml4e_access=0x%x)\n", shadow_pml4e_access, guest_pml4e_access); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } else if ((shadow_pml4e_access != PT_ACCESS_NOT_PRESENT) && (shadow_pml4e_access != PT_ACCESS_OK)) { // inject page fault in guest - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pml4e_access); PrintDebug("Manual Says to inject page fault into guest\n"); return 0; @@ -155,13 +149,11 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr), (addr_t *)&guest_pdp) == -1) { // Machine check the guest PrintDebug("Invalid Guest PDP Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr)); - if (!speculative) { - v3_raise_exception(info, MC_EXCEPTION); - } + v3_raise_exception(info, MC_EXCEPTION); return 0; } - if (handle_pdpe_shadow_pagefault_64(info, fault_addr, error_code, shadow_pdp, guest_pdp, speculative) == -1) { + if (handle_pdpe_shadow_pagefault_64(info, fault_addr, error_code, shadow_pdp, guest_pdp) == -1) { PrintError("Error handling Page fault caused by PDPE\n"); return -1; } @@ -173,7 +165,7 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa // For now we are not going to handle 1 Gigabyte pages static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp, int speculative) { + pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp) { pt_access_status_t guest_pdpe_access; pt_access_status_t shadow_pdpe_access; pdpe64_t * guest_pdpe = (pdpe64_t *)&(guest_pdp[PDPE64_INDEX(fault_addr)]); @@ -198,9 +190,7 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul if (is_guest_pf(guest_pdpe_access, shadow_pdpe_access) == 1) { PrintDebug("Injecting PDPE pf to guest: (guest access error=%d) (pf error code=%d)\n", *(uint_t *)&guest_pdpe_access, *(uint_t *)&error_code); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } @@ -210,16 +200,12 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul // PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n", shadow_pdpe_access, guest_pdpe_access); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } else if ((shadow_pdpe_access != PT_ACCESS_NOT_PRESENT) && (shadow_pdpe_access != PT_ACCESS_OK)) { // inject page fault in guest - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pdpe_access); PrintDebug("Manual Says to inject page fault into guest\n"); return 0; @@ -257,13 +243,11 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr), (addr_t *)&guest_pd) == -1) { // Machine check the guest PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr)); - if (!speculative) { - v3_raise_exception(info, MC_EXCEPTION); - } + v3_raise_exception(info, MC_EXCEPTION); return 0; } - if (handle_pde_shadow_pagefault_64(info, fault_addr, error_code, shadow_pd, guest_pd, speculative) == -1) { + if (handle_pde_shadow_pagefault_64(info, fault_addr, error_code, shadow_pd, guest_pd) == -1) { PrintError("Error handling Page fault caused by PDE\n"); return -1; } @@ -273,7 +257,7 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pde64_t * shadow_pd, pde64_t * guest_pd, int speculative) { + pde64_t * shadow_pd, pde64_t * guest_pd) { pt_access_status_t guest_pde_access; pt_access_status_t shadow_pde_access; pde64_t * guest_pde = (pde64_t *)&(guest_pd[PDE64_INDEX(fault_addr)]); @@ -291,9 +275,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) { PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n", *(uint_t *)&guest_pde_access, *(uint_t *)&error_code); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } @@ -303,9 +285,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault // PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n", shadow_pde_access, guest_pde_access); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); return 0; } else if ((shadow_pde_access == PT_ACCESS_WRITE_ERROR) && @@ -321,9 +301,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault } else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) && (shadow_pde_access != PT_ACCESS_OK)) { // inject page fault in guest - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + inject_guest_pf(info, fault_addr, error_code); PrintDebug("Unknown Error occurred (shadow_pde_access=%d)\n", shadow_pde_access); PrintDebug("Manual Says to inject page fault into guest\n"); return 0; @@ -378,18 +356,16 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault if (guest_pa_to_host_va(info, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t *)&guest_pt) == -1) { // Machine check the guest PrintDebug("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr)); - if (!speculative) { - v3_raise_exception(info, MC_EXCEPTION); - } + v3_raise_exception(info, MC_EXCEPTION); return 0; } - if (handle_pte_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, guest_pt, speculative) == -1) { + if (handle_pte_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, guest_pt) == -1) { PrintError("Error handling Page fault caused by PDE\n"); return -1; } } else { - if (handle_2MB_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde, speculative) == -1) { + if (handle_2MB_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde) == -1) { PrintError("Error handling large pagefault\n"); return -1; } @@ -400,7 +376,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pte64_t * shadow_pt, pte64_t * guest_pt, int speculative) { + pte64_t * shadow_pt, pte64_t * guest_pt) { pt_access_status_t guest_pte_access; pt_access_status_t shadow_pte_access; pte64_t * guest_pte = (pte64_t *)&(guest_pt[PTE64_INDEX(fault_addr)]);; @@ -418,9 +394,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault (shdw_reg->host_type == SHDW_REGION_INVALID)) { // Inject a machine check in the guest PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa); - if (!speculative) { - v3_raise_exception(info, MC_EXCEPTION); - } + v3_raise_exception(info, MC_EXCEPTION); return 0; } @@ -433,10 +407,8 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault /* Was the page fault caused by the Guest's page tables? */ if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) { PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n", - guest_pte_access, *(uint_t*)&error_code); - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + guest_pte_access, *(uint_t*)&error_code); + inject_guest_pf(info, fault_addr, error_code); return 0; } @@ -524,10 +496,8 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault return 0; } else { - // Inject page fault into the guest - if (!speculative) { - inject_guest_pf(info, fault_addr, error_code); - } + // Inject page fault into the guest + inject_guest_pf(info, fault_addr, error_code); PrintError("PTE Page fault fell through... Not sure if this should ever happen\n"); PrintError("Manual Says to inject page fault into guest\n"); return -1; @@ -540,7 +510,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault static int handle_2MB_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code, - pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde, int speculative) + pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde) { pt_access_status_t shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code); pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]); @@ -557,9 +527,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, (shdw_reg->host_type == SHDW_REGION_INVALID)) { // Inject a machine check in the guest PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa); - if (!speculative) { - v3_raise_exception(info, MC_EXCEPTION); - } + v3_raise_exception(info, MC_EXCEPTION); return -1; }