X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_shadow_paging_64.h;h=dd8397ce38d946d3da5ab7842be94b033d89b76f;hb=671625bf466a571d4db5c452004197a0488cee65;hp=0d45ca7a29a7add32610e1f2701ac644ccc731f5;hpb=30379ff13457e9687c5ab5acb67e92a5757fb5c6;p=palacios.git diff --git a/palacios/src/palacios/vmm_shadow_paging_64.h b/palacios/src/palacios/vmm_shadow_paging_64.h index 0d45ca7..dd8397c 100644 --- a/palacios/src/palacios/vmm_shadow_paging_64.h +++ b/palacios/src/palacios/vmm_shadow_paging_64.h @@ -1,3 +1,22 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + static inline int activate_shadow_pt_64(struct guest_info * info) { struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3); @@ -268,8 +287,8 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault ((pde64_2MB_t *)guest_pde)->dirty = 1; shadow_pde->writable = guest_pde->writable; - PrintDebug("Returning due to large page Write Error\n"); - PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); + //PrintDebug("Returning due to large page Write Error\n"); + //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); return 0; } else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) && @@ -300,6 +319,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 +528,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, fault_addr, info->ctrl_regs.cr3); + //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3); return 0; } @@ -583,7 +605,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info, return -1; } - PrintHostPageTree(info, 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 +613,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; +}