From: Jack Lange Date: Fri, 31 Oct 2008 23:05:16 +0000 (-0500) Subject: added guest page table walkers X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=2ec56652a07343b6f9b04a6adab12d7f5d49d466;p=palacios.git added guest page table walkers --- diff --git a/palacios/src/palacios/vmm_paging.c b/palacios/src/palacios/vmm_paging.c index 8c5d369..c6db0c0 100644 --- a/palacios/src/palacios/vmm_paging.c +++ b/palacios/src/palacios/vmm_paging.c @@ -1410,9 +1410,9 @@ pml4e64_t * create_passthrough_pts_64(struct guest_info * info) { return pml; } -/* + int v3_walk_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, - int (*callback)(int level, addr_t page_va, addr_t page_pa, void private_data), + int (*callback)(int level, addr_t page_ptr, addr_t page_pa, void * private_data), void * private_data) { addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3); pde32_t * guest_pde = NULL; @@ -1429,21 +1429,256 @@ int v3_walk_guest_pt_32(struct guest_info * info, v3_reg_t guest_cr3, return -1; } - callback(PAGE_PD32, guest_pde, guest_pde_pa, private_data); + callback(PAGE_PD32, (addr_t)guest_pde, guest_pde_pa, private_data); for (i = 0; i < MAX_PDE32_ENTRIES; i++) { - if (guet_pde[i].present) { + if (guest_pde[i].present) { if (guest_pde[i].large_page) { + pde32_4MB_t * large_pde = (pde32_4MB_t *)&(guest_pde[i]); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr); + addr_t large_page_va = 0; + + if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) { + PrintError("Could not get virtual address of Guest 4MB Page (PA=%p)\n", + (void *)large_page_pa); + return -1; + } + callback(PAGE_4MB, large_page_va, large_page_pa, private_data); + } else { + addr_t pte_pa = BASE_TO_PAGE_ADDR(guest_pde[i].pt_base_addr); + pte32_t * tmp_pte = NULL; + if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) { + PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n", + (void *)pte_pa); + return -1; + } + callback(PAGE_PT32, (addr_t)tmp_pte, pte_pa, private_data); + + for (j = 0; j < MAX_PTE32_ENTRIES; j++) { + if (tmp_pte[j].present) { + addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[j].page_base_addr); + addr_t page_va = 0; + + if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) { + PrintError("Could not get virtual address of Guest 4KB Page (PA=%p)\n", + (void *)page_pa); + return -1; + } + + callback(PAGE_4KB, page_va, page_pa, private_data); + } + } + } + } + } + return 0; } -*/ +int v3_walk_guest_pt_32pae(struct guest_info * info, v3_reg_t guest_cr3, + int (*callback)(int level, addr_t page_ptr, addr_t page_pa, void * private_data), + void * private_data) { + addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3); + pdpe32pae_t * guest_pdpe = NULL; + int i, j, k; + + if (!callback) { + PrintError("Call back was not specified\n"); + return -1; + } + + if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdpe) == -1) { + PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n", + (void *)guest_pdpe_pa); + return -1; + } + + + + callback(PAGE_PDP32PAE, (addr_t)guest_pdpe, guest_pdpe_pa, private_data); + + for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) { + if (guest_pdpe[i].present) { + addr_t pde_pa = BASE_TO_PAGE_ADDR(guest_pdpe[i].pd_base_addr); + pde32pae_t * tmp_pde = NULL; + + if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) { + PrintError("Could not get virtual address of Guest PDE32PAE (PA=%p)\n", + (void *)pde_pa); + return -1; + } + + callback(PAGE_PD32PAE, (addr_t)tmp_pde, pde_pa, private_data); + + for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) { + if (tmp_pde[j].present) { + if (tmp_pde[j].large_page) { + pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)&(tmp_pde[j]); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr); + addr_t large_page_va = 0; + + if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) { + PrintError("Could not get virtual address of Guest 2MB Page (PA=%p)\n", + (void *)large_page_pa); + return -1; + } + + callback(PAGE_2MB, large_page_va, large_page_pa, private_data); + } else { + addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr); + pte32pae_t * tmp_pte = NULL; + + if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) { + PrintError("Could not get virtual address of Guest PTE32PAE (PA=%p)\n", + (void *)pte_pa); + return -1; + } + + callback(PAGE_PT32PAE, (addr_t)tmp_pte, pte_pa, private_data); + + for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) { + if (tmp_pte[k].present) { + addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[k].page_base_addr); + addr_t page_va = 0; + + if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) { + PrintError("Could not get virtual address of Guest 4KB Page (PA=%p)\n", + (void *)page_pa); + return -1; + } + + callback(PAGE_4KB, page_va, page_pa, private_data); + } + } + } + } + } + } + } + return 0; +} + + + + +int v3_walk_guest_pt_64(struct guest_info * info, v3_reg_t guest_cr3, + int (*callback)(int level, addr_t page_ptr, addr_t page_pa, void * private_data), + void * private_data) { + addr_t guest_pml_pa = CR3_TO_PML4E64_PA(guest_cr3); + pml4e64_t * guest_pml = NULL; + int i, j, k, m; + + if (!callback) { + PrintError("Call back was not specified\n"); + return -1; + } + + if (guest_pa_to_host_va(info, guest_pml_pa, (addr_t *)&guest_pml) == -1) { + PrintError("Could not get virtual address of Guest PML464 (PA=%p)\n", + (void *)guest_pml); + return -1; + } + + + callback(PAGE_PML464, (addr_t)guest_pml, guest_pml_pa, private_data); + + for (i = 0; i < MAX_PML4E64_ENTRIES; i++) { + if (guest_pml[i].present) { + addr_t pdpe_pa = BASE_TO_PAGE_ADDR(guest_pml[i].pdp_base_addr); + pdpe64_t * tmp_pdpe = NULL; + + + if (guest_pa_to_host_va(info, pdpe_pa, (addr_t *)&tmp_pdpe) == -1) { + PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n", + (void *)pdpe_pa); + return -1; + } + + callback(PAGE_PDP64, (addr_t)tmp_pdpe, pdpe_pa, private_data); + + for (j = 0; j < MAX_PDPE64_ENTRIES; j++) { + if (tmp_pdpe[j].present) { + if (tmp_pdpe[j].large_page) { + pdpe64_1GB_t * large_pdpe = (pdpe64_1GB_t *)&(tmp_pdpe[j]); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdpe->page_base_addr); + addr_t large_page_va = 0; + + if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) { + PrintError("Could not get virtual address of Guest 1GB page (PA=%p)\n", + (void *)large_page_pa); + return -1; + } + + callback(PAGE_1GB, (addr_t)large_page_va, large_page_pa, private_data); + + } else { + addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr); + pde64_t * tmp_pde = NULL; + + if (guest_pa_to_host_va(info, pde_pa, (addr_t *)&tmp_pde) == -1) { + PrintError("Could not get virtual address of Guest PDE64 (PA=%p)\n", + (void *)pde_pa); + return -1; + } + + callback(PAGE_PD64, (addr_t)tmp_pde, pde_pa, private_data); + + for (k = 0; k < MAX_PDE64_ENTRIES; k++) { + if (tmp_pde[k].present) { + if (tmp_pde[k].large_page) { + pde64_2MB_t * large_pde = (pde64_2MB_t *)&(tmp_pde[k]); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr); + addr_t large_page_va = 0; + + if (guest_pa_to_host_va(info, large_page_pa, &large_page_va) == -1) { + PrintError("Could not get virtual address of Guest 2MB page (PA=%p)\n", + (void *)large_page_pa); + return -1; + } + + callback(PAGE_2MB, large_page_va, large_page_pa, private_data); + } else { + addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr); + pte64_t * tmp_pte = NULL; + + if (guest_pa_to_host_va(info, pte_pa, (addr_t *)&tmp_pte) == -1) { + PrintError("Could not get virtual address of Guest PTE64 (PA=%p)\n", + (void *)pte_pa); + return -1; + } + + callback(PAGE_PT64, (addr_t)tmp_pte, pte_pa, private_data); + + for (m = 0; m < MAX_PTE64_ENTRIES; m++) { + if (tmp_pte[m].present) { + addr_t page_pa = BASE_TO_PAGE_ADDR(tmp_pte[m].page_base_addr); + addr_t page_va = 0; + + if (guest_pa_to_host_va(info, page_pa, &page_va) == -1) { + PrintError("Could not get virtual address of Guest 4KB Page (PA=%p)\n", + (void *)page_pa); + return -1; + } + + callback(PAGE_4KB, page_va, page_pa, private_data); + } + } + } + } + } + } + } + } + } + } + return 0; +} int v3_walk_host_pt_32(v3_reg_t host_cr3, - int (*callback)(int level, addr_t page_va, addr_t page_pa, void * private_data), + int (*callback)(int level, addr_t page_ptr, addr_t page_pa, void * private_data), void * private_data) { pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3); addr_t pde_pa = CR3_TO_PDE32_PA(host_cr3); @@ -1486,7 +1721,7 @@ int v3_walk_host_pt_32(v3_reg_t host_cr3, int v3_walk_host_pt_32pae(v3_reg_t host_cr3, - void (*callback)(page_type_t type, addr_t page_va, addr_t page_pa, void * private_data), + void (*callback)(page_type_t type, addr_t page_ptr, addr_t page_pa, void * private_data), void * private_data) { pdpe32pae_t * host_pdpe = (pdpe32pae_t *)CR3_TO_PDPE32PAE_VA(host_cr3); addr_t pdpe_pa = CR3_TO_PDPE32PAE_PA(host_cr3); @@ -1536,7 +1771,7 @@ int v3_walk_host_pt_32pae(v3_reg_t host_cr3, int v3_walk_host_pt_64(v3_reg_t host_cr3, - void (*callback)(page_type_t type, addr_t page_va, addr_t page_pa, void * private_data), + void (*callback)(page_type_t type, addr_t page_ptr, addr_t page_pa, void * private_data), void * private_data) { pml4e64_t * host_pml = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3); addr_t pml_pa = CR3_TO_PML4E64_PA(host_cr3);