X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_shadow_paging_64.h;h=dcb7faf2c597865043f8b8f99945fc929c05b160;hb=f23519733b314e4cbaf0b2f1e4ea317302680898;hp=fa1e7fe3d04bb20d2f4ddfd53287be471f348b2a;hpb=3a47eb153e415d718e5d5601b79767b7335a149f;p=palacios.git diff --git a/palacios/src/palacios/vmm_shadow_paging_64.h b/palacios/src/palacios/vmm_shadow_paging_64.h index fa1e7fe..dcb7faf 100644 --- a/palacios/src/palacios/vmm_shadow_paging_64.h +++ b/palacios/src/palacios/vmm_shadow_paging_64.h @@ -269,7 +269,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault shadow_pde->writable = guest_pde->writable; PrintDebug("Returning due to large page Write Error\n"); - PrintHostPageTree(info->cpu_mode, fault_addr, info->ctrl_regs.cr3); + PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); return 0; } else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) && @@ -300,6 +300,9 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault if (guest_pde->large_page == 0) { shadow_pde->writable = guest_pde->writable; } else { + // This large page flag is temporary until we can get a working cache.... + ((pde64_2MB_t *)guest_pde)->vmm_info = V3_LARGE_PG; + if (error_code.write) { shadow_pde->writable = guest_pde->writable; ((pde64_2MB_t *)guest_pde)->dirty = 1; @@ -506,7 +509,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, // Inconsistent state... // Guest Re-Entry will flush tables and everything should now workd PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n"); - PrintHostPageTree(info->cpu_mode, fault_addr, info->ctrl_regs.cr3); + //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); return 0; } @@ -583,7 +586,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, return -1; } - PrintHostPageTree(info->cpu_mode, fault_addr, info->ctrl_regs.cr3); + // PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); PrintDebug("Returning from large page fault handler\n"); return 0; } @@ -591,8 +594,81 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, +static int invalidation_cb_64(struct guest_info * info, page_type_t type, + addr_t vaddr, addr_t page_ptr, addr_t page_pa, + void * private_data) { -static inline int handle_shadow_invlpg_64(struct guest_info * info, addr_t vaddr) { - PrintError("64 bit shadow paging not implemented\n"); + switch (type) { + case PAGE_PML464: + { + pml4e64_t * pml = (pml4e64_t *)page_ptr; + + if (pml[PML4E64_INDEX(vaddr)].present == 0) { + return 1; + } + return 0; + } + case PAGE_PDP64: + { + pdpe64_t * pdp = (pdpe64_t *)page_ptr; + pdpe64_t * pdpe = &(pdp[PDPE64_INDEX(vaddr)]); + + if (pdpe->present == 0) { + return 1; + } + + if (pdpe->vmm_info == V3_LARGE_PG) { + PrintError("1 Gigabyte pages not supported\n"); + return -1; + + pdpe->present = 0; + return 1; + } + + return 0; + } + case PAGE_PD64: + { + pde64_t * pd = (pde64_t *)page_ptr; + pde64_t * pde = &(pd[PDE64_INDEX(vaddr)]); + + if (pde->present == 0) { + return 1; + } + + if (pde->vmm_info == V3_LARGE_PG) { + pde->present = 0; + return 1; + } + + return 0; + } + case PAGE_PT64: + { + pte64_t * pt = (pte64_t *)page_ptr; + + pt[PTE64_INDEX(vaddr)].present = 0; + + return 1; + } + default: + PrintError("Invalid Page Type\n"); + return -1; + + } + + // should not get here + PrintError("Should not get here....\n"); return -1; } + + +static inline int handle_shadow_invlpg_64(struct guest_info * info, addr_t vaddr) { + int ret = v3_drill_host_pt_64(info, info->ctrl_regs.cr3, vaddr, invalidation_cb_64, NULL); + if (ret == -1) { + PrintError("Page table drill returned error.... \n"); + PrintHostPageTree(info, vaddr, info->ctrl_regs.cr3); + } + + return (ret == -1) ? -1 : 0; +}