X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_paging.c;h=f63ddf18a44c7bdc2ea43c83a8ef12b67ace9e50;hb=11b5cccde17af54f3998c38952e0eeedf85ced0a;hp=7d2878ff31bbbdbe99d5f71cbedcb12941769493;hpb=ff90d0325fbbecf4d2acef912e830a711526c913;p=palacios.releases.git diff --git a/palacios/src/palacios/vmm_paging.c b/palacios/src/palacios/vmm_paging.c index 7d2878f..f63ddf1 100644 --- a/palacios/src/palacios/vmm_paging.c +++ b/palacios/src/palacios/vmm_paging.c @@ -1412,17 +1412,273 @@ pml4e64_t * create_passthrough_pts_64(struct guest_info * info) { 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), + void (*callback)(page_type_t type, 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; + int i, j; + + if (!callback) { + PrintError("Call back was not specified\n"); + return -1; + } + + if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) { + PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n", + (void *)guest_pde_pa); + return -1; + } + + callback(PAGE_PD32, (addr_t)guest_pde, guest_pde_pa, private_data); + + for (i = 0; i < MAX_PDE32_ENTRIES; i++) { + 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, + void (*callback)(page_type_t type, 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, + void (*callback)(page_type_t type, 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), + void (*callback)(page_type_t type, 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); @@ -1433,25 +1689,25 @@ int v3_walk_host_pt_32(v3_reg_t host_cr3, return -1; } - callback(PAGE_PD32, host_pde, pde_pa, private_data); + callback(PAGE_PD32, (addr_t)host_pde, pde_pa, private_data); for (i = 0; i < MAX_PDE32_ENTRIES; i++) { if (host_pde[i].present) { - if (host_pde[i].lage_page) { + if (host_pde[i].large_page) { pde32_4MB_t * large_pde = (pde32_4MB_t *)&(host_pde[i]); addr_t large_page_pa = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr); - callback(PAGE_4MB, V3_VAddr(large_page_pa), large_page_pa, private_data); + callback(PAGE_4MB, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data); } else { addr_t pte_pa = BASE_TO_PAGE_ADDR(host_pde[i].pt_base_addr); - pte32_t * tmp_pte = (pte32_t *)V3_VAddr(pte_pa); + pte32_t * tmp_pte = (pte32_t *)V3_VAddr((void *)pte_pa); - callback(PAGE_PT32, tmp_pte, pte_pa, private_data); + 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); - callback(PAGE_4KB, V3_VAddr(page_pa), page_pa, private_data); + callback(PAGE_4KB, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data); } } } @@ -1465,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); @@ -1476,14 +1732,14 @@ int v3_walk_host_pt_32pae(v3_reg_t host_cr3, return -1; } - callback(PAGE_PDP32PAE, host_pdpe, pdpe_pa, private_data); + callback(PAGE_PDP32PAE, (addr_t)host_pdpe, pdpe_pa, private_data); for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) { if (host_pdpe[i].present) { addr_t pde_pa = BASE_TO_PAGE_ADDR(host_pdpe[i].pd_base_addr); - pde32pae_t * tmp_pde = (pde32pae_t *)V3_VAddr(pde_pa); + pde32pae_t * tmp_pde = (pde32pae_t *)V3_VAddr((void *)pde_pa); - callback(PAGE_PD32PAE, tmp_pde, pde_pa, private_data); + callback(PAGE_PD32PAE, (addr_t)tmp_pde, pde_pa, private_data); for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) { if (tmp_pde[j].present) { @@ -1492,17 +1748,17 @@ int v3_walk_host_pt_32pae(v3_reg_t host_cr3, 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); - callback(PAGE_2MB, V3_VAddr(lage_page_pa), lage_page_pa, private_data); + callback(PAGE_2MB, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data); } else { addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[j].pt_base_addr); - pte32pae_t * tmp_pte = (pte32pae_t *)V3_VAddr(pte_pa); + pte32pae_t * tmp_pte = (pte32pae_t *)V3_VAddr((void *)pte_pa); - callback(PAGE_PT32PAE, tmp_pte, pte_pa, private_data); + 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); - callback(PAGE_4KB, V3_VAddr(page_pa), page_pa, private_data); + callback(PAGE_4KB, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data); } } } @@ -1515,9 +1771,9 @@ 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 = (pml3e64_t *)CR3_TO_PML4E64_VA(host_cr3); + pml4e64_t * host_pml = (pml4e64_t *)CR3_TO_PML4E64_VA(host_cr3); addr_t pml_pa = CR3_TO_PML4E64_PA(host_cr3); int i, j, k, m; @@ -1526,45 +1782,45 @@ int v3_walk_host_pt_64(v3_reg_t host_cr3, return -1; } - callback(PAGE_PML464, host_pml, pml_pa, private_data); + callback(PAGE_PML464, (addr_t)host_pml, pml_pa, private_data); for (i = 0; i < MAX_PML4E64_ENTRIES; i++) { if (host_pml[i].present) { addr_t pdpe_pa = BASE_TO_PAGE_ADDR(host_pml[i].pdp_base_addr); - pdpe64_t * tmp_pdpe = (pdpe64_t *)V3_VAddr(pdpe_pa); + pdpe64_t * tmp_pdpe = (pdpe64_t *)V3_VAddr((void *)pdpe_pa); - callback(PAGE_PDP64, tmp_pdpe, pdpe_pa, private_data); + 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_pdp = (pdpe64_t *)&(tmp_pdpe[j]); - addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdp->page_addr); + pdpe64_1GB_t * large_pdp = (pdpe64_1GB_t *)&(tmp_pdpe[j]); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_1GB(large_pdp->page_base_addr); - callback(PAGE_1GB, V3_VAddr(large_page_pa), large_page_pa, private_data); + callback(PAGE_1GB, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data); } else { addr_t pde_pa = BASE_TO_PAGE_ADDR(tmp_pdpe[j].pd_base_addr); - pde64_t * tmp_pde = (pde64_t *)V3_VAddr(pde_pa); + pde64_t * tmp_pde = (pde64_t *)V3_VAddr((void *)pde_pa); - callback(PAGE_PD64, tmp_pde, pde_pa, private_data); + callback(PAGE_PD64, (addr_t)tmp_pde, pde_pa, private_data); - for (k = 0; k < MAX_PDE64_ENRIES; k++) { + 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_addr); + addr_t large_page_pa = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr); - callback(PAGE_2MB, V3_VAddr(large_page_pa), large_page_pa, private_data); + callback(PAGE_2MB, (addr_t)V3_VAddr((void *)large_page_pa), large_page_pa, private_data); } else { addr_t pte_pa = BASE_TO_PAGE_ADDR(tmp_pde[k].pt_base_addr); - pte64_t * tmp_pte = (pte64_t *)V3_VAddr(pte_pa); + pte64_t * tmp_pte = (pte64_t *)V3_VAddr((void *)pte_pa); - callback(PAGE_PT64, tmp_pte, pte_pa, private_data); + 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); - callback(PAGE_4KB, V3_VAddr(page_pa), page_pa, private_data); + callback(PAGE_4KB, (addr_t)V3_VAddr((void *)page_pa), page_pa, private_data); } } } @@ -1577,3 +1833,53 @@ int v3_walk_host_pt_64(v3_reg_t host_cr3, } return 0; } + + + +static const uchar_t PAGE_4KB_STR[] = "4KB_PAGE"; +static const uchar_t PAGE_2MB_STR[] = "2MB_PAGE"; +static const uchar_t PAGE_4MB_STR[] = "4MB_PAGE"; +static const uchar_t PAGE_1GB_STR[] = "1GB_PAGE"; +static const uchar_t PAGE_PT32_STR[] = "32 Bit PT"; +static const uchar_t PAGE_PD32_STR[] = "32 Bit PD"; +static const uchar_t PAGE_PDP32PAE_STR[] = "32 Bit PAE PDP"; +static const uchar_t PAGE_PD32PAE_STR[] = "32 Bit PAE PD"; +static const uchar_t PAGE_PT32PAE_STR[] = "32 Bit PAE PT"; +static const uchar_t PAGE_PML464_STR[] = "64 Bit PML4"; +static const uchar_t PAGE_PDP64_STR[] = "64 Bit PDP"; +static const uchar_t PAGE_PD64_STR[] = "64 Bit PD"; +static const uchar_t PAGE_PT64_STR[] = "64 Bit PT"; + + +const uchar_t * v3_page_type_to_str(page_type_t type) { + switch (type) { + case PAGE_4KB: + return PAGE_4KB_STR; + case PAGE_2MB: + return PAGE_2MB_STR; + case PAGE_4MB: + return PAGE_4MB_STR; + case PAGE_1GB: + return PAGE_1GB_STR; + case PAGE_PT32: + return PAGE_PT32_STR; + case PAGE_PD32: + return PAGE_PD32_STR; + case PAGE_PDP32PAE: + return PAGE_PDP32PAE_STR; + case PAGE_PD32PAE: + return PAGE_PD32PAE_STR; + case PAGE_PT32PAE: + return PAGE_PT32PAE_STR; + case PAGE_PML464: + return PAGE_PML464_STR; + case PAGE_PDP64: + return PAGE_PDP64_STR; + case PAGE_PD64: + return PAGE_PD64_STR; + case PAGE_PT64: + return PAGE_PT64_STR; + default: + return NULL; + } +}