X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_shadow_paging.c;h=702b6f01a25c3f4dec2e461680c4588ee90d10f4;hb=11b5cccde17af54f3998c38952e0eeedf85ced0a;hp=5e57c63cedd349a0c8705d3933e3ff8ace5c8148;hpb=ddd9b6c1a6d0051ba8eae32d25492145c8ca5995;p=palacios.releases.git diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index 5e57c63..702b6f0 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -78,6 +78,10 @@ static int handle_shadow_pagefault_32(struct guest_info * info, addr_t fault_add static int handle_shadow_pagefault_32pae(struct guest_info * info, addr_t fault_addr, pf_error_t error_code); static int handle_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code); + +static int cache_page_tables_32(struct guest_info * info, addr_t pde); +static int cache_page_tables_64(struct guest_info * info, addr_t pde); + int v3_init_shadow_page_state(struct guest_info * info) { struct shadow_page_state * state = &(info->shdw_pg_state); @@ -149,13 +153,13 @@ int cache_page_tables32(struct guest_info * info, addr_t pde) { int v3_cache_page_tables(struct guest_info * info, addr_t cr3) { switch(v3_get_cpu_mode(info)) { case PROTECTED: - return v3_cache_page_tables32(info, CR3_TO_PDE32_PA(cr3)); + return cache_page_tables_32(info, CR3_TO_PDE32_PA(cr3)); default: return -1; } } -int v3_cache_page_tables32(struct guest_info * info, addr_t pde) { +static int cache_page_tables_32(struct guest_info * info, addr_t pde) { struct shadow_page_state * state = &(info->shdw_pg_state); addr_t pde_host_addr; pde32_t * tmp_pde; @@ -204,6 +208,10 @@ int v3_cache_page_tables32(struct guest_info * info, addr_t pde) { } +static int cache_page_tables_64(struct guest_info * info, addr_t pde) { + return -1; +} + int v3_replace_shdw_page32(struct guest_info * info, addr_t location, pte32_t * new_page, pte32_t * old_page) { pde32_t * shadow_pd = (pde32_t *)CR3_TO_PDE32_VA(info->ctrl_regs.cr3); @@ -221,6 +229,7 @@ int v3_replace_shdw_page32(struct guest_info * info, addr_t location, pte32_t * } else { // currently unhandled + PrintError("Replacing large shadow pages not implemented\n"); return -1; } @@ -234,34 +243,34 @@ int v3_replace_shdw_page32(struct guest_info * info, addr_t location, pte32_t * // We assume that shdw_pg_state.guest_cr3 is pointing to the page tables we want to activate // We also assume that the CPU mode has not changed during this page table transition static int activate_shadow_pt_32(struct guest_info * info) { - struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3); - struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3); - int cached = 0; - - // Check if shadow page tables are in the cache - cached = v3_cache_page_tables32(info, CR3_TO_PDE32_PA(*(addr_t *)guest_cr3)); + struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3); + struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3); + int cached = 0; + + // Check if shadow page tables are in the cache + cached = cache_page_tables_32(info, CR3_TO_PDE32_PA(*(addr_t *)guest_cr3)); + + if (cached == -1) { + PrintError("CR3 Cache failed\n"); + return -1; + } else if (cached == 0) { + addr_t shadow_pt; - if (cached == -1) { - PrintError("CR3 Cache failed\n"); - return -1; - } else if (cached == 0) { - addr_t shadow_pt; - - PrintDebug("New CR3 is different - flushing shadow page table %p\n", shadow_cr3 ); - delete_page_tables_32(CR3_TO_PDE32_VA(*(uint_t*)shadow_cr3)); - - shadow_pt = v3_create_new_shadow_pt(); - - shadow_cr3->pdt_base_addr = (addr_t)V3_PAddr((void *)(addr_t)PAGE_BASE_ADDR(shadow_pt)); - PrintDebug( "Created new shadow page table %p\n", (void *)(addr_t)shadow_cr3->pdt_base_addr ); - } else { - PrintDebug("Reusing cached shadow Page table\n"); - } - - shadow_cr3->pwt = guest_cr3->pwt; - shadow_cr3->pcd = guest_cr3->pcd; - - return 0; + PrintDebug("New CR3 is different - flushing shadow page table %p\n", shadow_cr3 ); + delete_page_tables_32(CR3_TO_PDE32_VA(*(uint_t*)shadow_cr3)); + + shadow_pt = v3_create_new_shadow_pt(); + + shadow_cr3->pdt_base_addr = (addr_t)V3_PAddr((void *)(addr_t)PAGE_BASE_ADDR(shadow_pt)); + PrintDebug( "Created new shadow page table %p\n", (void *)(addr_t)shadow_cr3->pdt_base_addr ); + } else { + PrintDebug("Reusing cached shadow Page table\n"); + } + + shadow_cr3->pwt = guest_cr3->pwt; + shadow_cr3->pcd = guest_cr3->pcd; + + return 0; } static int activate_shadow_pt_32pae(struct guest_info * info) { @@ -269,9 +278,48 @@ static int activate_shadow_pt_32pae(struct guest_info * info) { return -1; } +static void activate_shadow_pt_64_cb(page_type_t type, addr_t page_ptr, addr_t page_pa, void * private_data) { + PrintDebug("CB: Page: %p, Type: %s\n", (void *)page_pa, v3_page_type_to_str(type)); +} + + static int activate_shadow_pt_64(struct guest_info * info) { - PrintError("Activating 64 bit page tables not implemented\n"); + // struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3); + struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3); + int cached = 0; + + v3_walk_guest_pt_64(info, info->shdw_pg_state.guest_cr3, activate_shadow_pt_64_cb, NULL); + + + return -1; + + + // Check if shadow page tables are in the cache + cached = cache_page_tables_64(info, CR3_TO_PDE32_PA(*(addr_t *)guest_cr3)); + /* + if (cached == -1) { + PrintError("CR3 Cache failed\n"); + return -1; + } else if (cached == 0) { + addr_t shadow_pt; + + PrintDebug("New CR3 is different - flushing shadow page table %p\n", shadow_cr3 ); + delete_page_tables_32(CR3_TO_PDE32_VA(*(uint_t*)shadow_cr3)); + + shadow_pt = v3_create_new_shadow_pt(); + + shadow_cr3->pml4t_base_addr = (addr_t)V3_PAddr((void *)(addr_t)PAGE_BASE_ADDR(shadow_pt)); + PrintDebug( "Created new shadow page table %p\n", (void *)(addr_t)shadow_cr3->pml4t_base_addr ); + } else { + PrintDebug("Reusing cached shadow Page table\n"); + } + + shadow_cr3->pwt = guest_cr3->pwt; + shadow_cr3->pcd = guest_cr3->pcd; + + return 0; + */ } @@ -400,6 +448,20 @@ static int is_guest_pf(pt_access_status_t guest_access, pt_access_status_t shado */ static int handle_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) { + pt_access_status_t guest_access; + pt_access_status_t shadow_access; + int ret; + PrintDebug("64 bit shadow page fault\n"); + + ret = v3_check_guest_pt_32(info, info->shdw_pg_state.guest_cr3, fault_addr, error_code, &guest_access); + + PrintDebug("Guest Access Check: %d (access=%d)\n", ret, guest_access); + + ret = v3_check_host_pt_32(info->ctrl_regs.cr3, fault_addr, error_code, &shadow_access); + + PrintDebug("Shadow Access Check: %d (access=%d)\n", ret, shadow_access); + + PrintError("64 bit shadow paging not implemented\n"); return -1; }