X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_shadow_paging.c;h=3ae28d4b95e52b9a2dbedbde487983f2f63c90a6;hb=496b928649b2a63c3e21e099ce914ec00b3d7227;hp=e6bad8a470ae9a2ab1bca5bd96f58398be430bac;hpb=e4c0bf63a6e95019f79f7ff9915fd5d360d2c31a;p=palacios.releases.git diff --git a/palacios/src/palacios/vmm_shadow_paging.c b/palacios/src/palacios/vmm_shadow_paging.c index e6bad8a..3ae28d4 100644 --- a/palacios/src/palacios/vmm_shadow_paging.c +++ b/palacios/src/palacios/vmm_shadow_paging.c @@ -28,6 +28,8 @@ #include +#include + #ifndef DEBUG_SHADOW_PAGING #undef PrintDebug #define PrintDebug(fmt, args...) @@ -61,7 +63,7 @@ static int pte_equals(addr_t key1, addr_t key2) { return (key1 == key2); } -static addr_t create_new_shadow_pt(struct guest_info * info); +static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info); static void inject_guest_pf(struct guest_info * info, addr_t fault_addr, pf_error_t error_code); static int is_guest_pf(pt_access_status_t guest_access, pt_access_status_t shadow_access); @@ -92,7 +94,7 @@ int v3_init_shadow_page_state(struct guest_info * info) { // creates new shadow page tables // updates the shadow CR3 register to point to the new pts int v3_activate_shadow_pt(struct guest_info * info) { - switch (info->cpu_mode) { + switch (v3_get_cpu_mode(info)) { case PROTECTED: return activate_shadow_pt_32(info); @@ -103,7 +105,7 @@ int v3_activate_shadow_pt(struct guest_info * info) { case LONG_16_COMPAT: return activate_shadow_pt_64(info); default: - PrintError("Invalid CPU mode: %d\n", info->cpu_mode); + PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info))); return -1; } @@ -125,22 +127,24 @@ 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) { - if (info->mem_mode == PHYSICAL_MEM) { + if (v3_get_mem_mode(info) == PHYSICAL_MEM) { // If paging is not turned on we need to handle the special cases - return handle_special_page_fault(info, fault_addr, fault_addr, error_code); - } else if (info->mem_mode == VIRTUAL_MEM) { + return v3_handle_shadow_pagefault_physical_mode(info, fault_addr, error_code); + } else if (v3_get_mem_mode(info) == VIRTUAL_MEM) { - switch (info->cpu_mode) { + switch (v3_get_cpu_mode(info)) { case PROTECTED: 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: return handle_shadow_pagefault_64(info, fault_addr, error_code); break; default: - PrintError("Unhandled CPU Mode\n"); + PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info))); return -1; } } else { @@ -156,14 +160,14 @@ int v3_handle_shadow_invlpg(struct guest_info * info) { int ret = 0; addr_t vaddr = 0; - if (info->mem_mode != VIRTUAL_MEM) { + if (v3_get_mem_mode(info) != VIRTUAL_MEM) { // Paging must be turned on... // should handle with some sort of fault I think PrintError("ERROR: INVLPG called in non paged mode\n"); return -1; } - if (info->mem_mode == PHYSICAL_MEM) { + if (v3_get_mem_mode(info) == PHYSICAL_MEM) { ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr); } else { ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr); @@ -190,7 +194,7 @@ int v3_handle_shadow_invlpg(struct guest_info * info) { info->rip += dec_instr.instr_length; - switch (info->cpu_mode) { + switch (v3_get_cpu_mode(info)) { case PROTECTED: return handle_shadow_invlpg_32(info, vaddr); case PROTECTED_PAE: @@ -200,7 +204,7 @@ int v3_handle_shadow_invlpg(struct guest_info * info) { case LONG_16_COMPAT: return handle_shadow_invlpg_64(info, vaddr); default: - PrintError("Invalid CPU mode: %d\n", info->cpu_mode); + PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_cpu_mode(info))); return -1; } } @@ -208,7 +212,7 @@ int v3_handle_shadow_invlpg(struct guest_info * info) { -static addr_t create_new_shadow_pt(struct guest_info * info) { +static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) { struct shadow_page_state * state = &(info->shdw_pg_state); v3_reg_t cur_cr3 = info->ctrl_regs.cr3; struct shadow_page_data * page_tail = NULL; @@ -218,13 +222,15 @@ static addr_t create_new_shadow_pt(struct guest_info * info) { page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node); if (page_tail->cr3 != cur_cr3) { - page_tail->cr3 = cur_cr3; + PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n", + (void *) page_tail->page_pa, (void *)cur_cr3, (void *)(page_tail->cr3)); + list_move(&(page_tail->page_list_node), &(state->page_list)); memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB); - PrintDebug("Reusing old shadow Page\n"); - return (addr_t)V3_VAddr((void *)(page_tail->page_pa)); + + return page_tail; } } @@ -233,13 +239,15 @@ static addr_t create_new_shadow_pt(struct guest_info * info) { page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data)); page_tail->page_pa = (addr_t)V3_AllocPages(1); + PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n", (void *)page_tail->page_pa, (void *)cur_cr3); + page_tail->cr3 = cur_cr3; list_add(&(page_tail->page_list_node), &(state->page_list)); shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa)); memset((void *)shdw_page, 0, PAGE_SIZE_4KB); - return shdw_page; + return page_tail; }