hv: ept: add lookup_address to lookup the page table

Add lookup_address to lokup the page table for a virtual address
of primary page table or a physical address of extended page table.
The remaining obtain_last_page_table_entry could be removed with their
called function later.

Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2018-07-26 09:25:19 +08:00 committed by lijinxia
parent e2516fa6a0
commit f815415b70
3 changed files with 54 additions and 24 deletions

View File

@ -120,18 +120,13 @@ void destroy_ept(struct vm *vm)
uint64_t _gpa2hpa(struct vm *vm, uint64_t gpa, uint32_t *size)
{
uint64_t hpa = 0UL;
uint32_t pg_size = 0U;
struct entry_params entry;
struct map_params map_params;
uint64_t *pgentry, pg_size = 0UL;
map_params.page_table_type = PTT_EPT;
map_params.pml4_base = vm->arch_vm.nworld_eptp;
map_params.pml4_inverted = vm->arch_vm.m2p;
obtain_last_page_table_entry(&map_params, &entry, (void *)gpa, true);
if (entry.entry_present == PT_PRESENT) {
hpa = ((entry.entry_val & (~(entry.page_size - 1)))
| (gpa & (entry.page_size - 1)));
pg_size = entry.page_size;
pgentry = lookup_address((uint64_t *)vm->arch_vm.nworld_eptp,
gpa, &pg_size, PTT_EPT);
if (pgentry != NULL) {
hpa = ((*pgentry & (~(pg_size - 1UL)))
| (gpa & (pg_size - 1UL)));
pr_dbg("GPA2HPA: 0x%llx->0x%llx", gpa, hpa);
} else {
pr_err("VM %d GPA2HPA: failed for gpa 0x%llx",
@ -139,7 +134,7 @@ uint64_t _gpa2hpa(struct vm *vm, uint64_t gpa, uint32_t *size)
}
if (size != NULL) {
*size = pg_size;
*size = (uint32_t)pg_size;
}
return hpa;
@ -153,23 +148,17 @@ uint64_t gpa2hpa(struct vm *vm, uint64_t gpa)
uint64_t hpa2gpa(struct vm *vm, uint64_t hpa)
{
struct entry_params entry;
struct map_params map_params;
uint64_t *pgentry, pg_size = 0UL;
map_params.page_table_type = PTT_EPT;
map_params.pml4_base = vm->arch_vm.nworld_eptp;
map_params.pml4_inverted = vm->arch_vm.m2p;
obtain_last_page_table_entry(&map_params, &entry,
(void *)hpa, false);
if (entry.entry_present == PT_NOT_PRESENT) {
pgentry = lookup_address((uint64_t *)vm->arch_vm.m2p,
hpa, &pg_size, PTT_EPT);
if (pgentry == NULL) {
pr_err("VM %d hpa2gpa: failed for hpa 0x%llx",
vm->attr.boot_idx, hpa);
ASSERT(false, "hpa2gpa not found");
}
return ((entry.entry_val & (~(entry.page_size - 1)))
| (hpa & (entry.page_size - 1)));
return ((*pgentry & (~(pg_size - 1UL)))
| (hpa & (pg_size - 1UL)));
}
bool is_ept_supported(void)

View File

@ -452,3 +452,42 @@ int mmu_add(uint64_t *pml4_page, uint64_t paddr_base,
return 0;
}
uint64_t *lookup_address(uint64_t *pml4_page,
uint64_t addr, uint64_t *pg_size, enum _page_table_type ptt)
{
uint64_t *pml4e, *pdpte, *pde, *pte;
if ((pml4_page == NULL) || (pg_size == NULL)) {
return NULL;
}
pml4e = pml4e_offset(pml4_page, addr);
if (pgentry_present(ptt, *pml4e) == 0UL) {
return NULL;
}
pdpte = pdpte_offset(pml4e, addr);
if (pgentry_present(ptt, *pdpte) == 0UL) {
return NULL;
} else if (pdpte_large(*pdpte) != 0UL) {
*pg_size = PDPTE_SIZE;
return pdpte;
}
pde = pde_offset(pdpte, addr);
if (pgentry_present(ptt, *pde) == 0UL) {
return NULL;
} else if (pde_large(*pde) != 0UL) {
*pg_size = PDE_SIZE;
return pde;
}
pte = pte_offset(pde, addr);
if (pgentry_present(ptt, *pte) == 0UL) {
return NULL;
} else {
*pg_size = PTE_SIZE;
return pte;
}
}

View File

@ -339,6 +339,8 @@ void invept(struct vcpu *vcpu);
bool check_continuous_hpa(struct vm *vm, uint64_t gpa_arg, uint64_t size_arg);
int obtain_last_page_table_entry(struct map_params *map_params,
struct entry_params *entry, void *addr, bool direct);
uint64_t *lookup_address(uint64_t *pml4_page, uint64_t addr,
uint64_t *pg_size, enum _page_table_type ptt);
int register_mmio_emulation_handler(struct vm *vm,
hv_mem_io_handler_t read_write, uint64_t start,