hv: ept: remove find_next_table

We don't need find_next_table to walk to the next EPT page table.

Tracked-On: #1124

Signed-off-by: Li, Fei1 <fei1.li@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Li, Fei1 2018-08-24 10:24:48 +08:00 committed by lijinxia
parent 9257ecf4bb
commit 7f9befb643
3 changed files with 29 additions and 89 deletions

View File

@ -10,94 +10,55 @@
#define ACRN_DBG_EPT 6U #define ACRN_DBG_EPT 6U
static uint64_t find_next_table(uint32_t table_offset, const void *table_base)
{
uint64_t table_entry;
uint64_t table_present;
uint64_t sub_table_addr = 0UL;
/* Read the table entry */
table_entry = mem_read64(table_base
+ (table_offset * IA32E_COMM_ENTRY_SIZE));
/* If bit 7 is set, entry is not a subtable. */
if (((table_entry & IA32E_PDPTE_PS_BIT) != 0U)
|| ((table_entry & IA32E_PDE_PS_BIT) != 0U)) {
return sub_table_addr;
}
/* Set table present bits to any of the read/write/execute bits */
table_present = EPT_RWX;
/* Determine if a valid entry exists */
if ((table_entry & table_present) == 0UL) {
/* No entry present */
return sub_table_addr;
}
/* Get address of the sub-table */
sub_table_addr = table_entry & IA32E_REF_MASK;
/* Return the next table in the walk */
return sub_table_addr;
}
/** /**
* @pre pml4_addr != NULL * @pre pml4_addr != NULL
*/ */
void free_ept_mem(void *pml4_addr) void free_ept_mem(uint64_t *pml4_page)
{ {
void *pdpt_addr; uint64_t *pdpt_page, *pd_page, *pt_page;
void *pde_addr; uint64_t *pml4e, *pdpte, *pde;
void *pte_addr; uint64_t pml4e_idx, pdpte_idx, pde_idx;
uint32_t pml4_index;
uint32_t pdpt_index;
uint32_t pde_idx;
for (pml4_index = 0U; pml4_index < IA32E_NUM_ENTRIES; pml4_index++) { for (pml4e_idx = 0U; pml4e_idx < PTRS_PER_PML4E; pml4e_idx++) {
/* Walk from the PML4 table to the PDPT table */ pml4e = pml4_page + pml4e_idx;
pdpt_addr = HPA2HVA(find_next_table(pml4_index, pml4_addr)); if (pgentry_present(PTT_EPT, *pml4e) == 0UL) {
if (pdpt_addr == NULL) {
continue; continue;
} }
pdpt_page = pml4e_page_vaddr(*pml4e);
for (pdpt_index = 0U; pdpt_index < IA32E_NUM_ENTRIES; for (pdpte_idx = 0U; pdpte_idx < PTRS_PER_PDPTE; pdpte_idx++) {
pdpt_index++) { pdpte = pdpt_page + pdpte_idx;
/* Walk from the PDPT table to the PD table */ if ((pgentry_present(PTT_EPT, *pdpte) == 0UL) ||
pde_addr = HPA2HVA(find_next_table(pdpt_index, pdpte_large(*pdpte) != 0UL) {
pdpt_addr));
if (pde_addr == NULL) {
continue; continue;
} }
pd_page = pdpte_page_vaddr(*pdpte);
for (pde_idx = 0U; pde_idx < IA32E_NUM_ENTRIES; for (pde_idx = 0U; pde_idx < PTRS_PER_PDE; pde_idx++) {
pde_idx++) { pde = pd_page + pde_idx;
/* Walk from the PD table to the page table */ if ((pgentry_present(PTT_EPT, *pde) == 0UL) ||
pte_addr = HPA2HVA(find_next_table(pde_idx, pde_large(*pde) != 0UL) {
pde_addr)); continue;
}
pt_page = pde_page_vaddr(*pde);
/* Free page table entry table */ /* Free page table entry table */
if (pte_addr != NULL) { free_paging_struct((void *)pt_page);
free_paging_struct(pte_addr);
}
} }
/* Free page directory entry table */ /* Free page directory entry table */
if (pde_addr != NULL) { free_paging_struct((void *)pd_page);
free_paging_struct(pde_addr);
} }
free_paging_struct((void *)pdpt_page);
} }
free_paging_struct(pdpt_addr); free_paging_struct((void *)pml4_page);
}
free_paging_struct(pml4_addr);
} }
void destroy_ept(struct vm *vm) void destroy_ept(struct vm *vm)
{ {
if (vm->arch_vm.nworld_eptp != NULL) if (vm->arch_vm.nworld_eptp != NULL)
free_ept_mem(vm->arch_vm.nworld_eptp); free_ept_mem((uint64_t *)vm->arch_vm.nworld_eptp);
if (vm->arch_vm.m2p != NULL) if (vm->arch_vm.m2p != NULL)
free_ept_mem(vm->arch_vm.m2p); free_ept_mem((uint64_t *)vm->arch_vm.m2p);
} }
uint64_t local_gpa2hpa(const struct vm *vm, uint64_t gpa, uint32_t *size) uint64_t local_gpa2hpa(const struct vm *vm, uint64_t gpa, uint32_t *size)

View File

@ -181,8 +181,8 @@ void destroy_secure_world(struct vm *vm, bool need_clr_mem)
(void *)pml4e_page_vaddr(*(uint64_t *)vm->arch_vm.sworld_eptp); (void *)pml4e_page_vaddr(*(uint64_t *)vm->arch_vm.sworld_eptp);
/* memset PDPTEs except trusty memory */ /* memset PDPTEs except trusty memory */
(void)memset(pdpt_addr, 0UL, (void)memset(pdpt_addr, 0UL,
NON_TRUSTY_PDPT_ENTRIES * IA32E_COMM_ENTRY_SIZE); NON_TRUSTY_PDPT_ENTRIES * sizeof(uint64_t));
free_ept_mem(vm->arch_vm.sworld_eptp); free_ept_mem((uint64_t *)vm->arch_vm.sworld_eptp);
vm->arch_vm.sworld_eptp = NULL; vm->arch_vm.sworld_eptp = NULL;
} else { } else {
pr_err("sworld eptp is NULL"); pr_err("sworld eptp is NULL");

View File

@ -7,27 +7,6 @@
#ifndef MMU_H #ifndef MMU_H
#define MMU_H #define MMU_H
/* Size of all page-table entries (in bytes) */
#define IA32E_COMM_ENTRY_SIZE 8U
/* Definitions exclusive to a Page Directory Pointer Table Entry (PDPTE) */
#define IA32E_PDPTE_D_BIT 0x0000000000000040UL
#define IA32E_PDPTE_PS_BIT 0x0000000000000080UL
#define IA32E_PDPTE_PAT_BIT 0x0000000000001000UL
#define IA32E_PDPTE_ADDR_MASK 0x0000FFFFC0000000UL
/* Definitions exclusive to a Page Directory Entry (PDE) 1G or 2M */
#define IA32E_PDE_D_BIT 0x0000000000000040UL
#define IA32E_PDE_PS_BIT 0x0000000000000080UL
#define IA32E_PDE_PAT_BIT 0x0000000000001000UL
#define IA32E_PDE_ADDR_MASK 0x0000FFFFFFE00000UL
/* Definitions exclusive to Page Table Entries (PTE) */
#define IA32E_PTE_D_BIT 0x0000000000000040UL
#define IA32E_PTE_PAT_BIT 0x0000000000000080UL
#define IA32E_PTE_G_BIT 0x0000000000000100UL
#define IA32E_PTE_ADDR_MASK 0x0000FFFFFFFFF000UL
/** The flag that indicates that the page fault was caused by a non present /** The flag that indicates that the page fault was caused by a non present
* page. * page.
*/ */
@ -211,7 +190,7 @@ int ept_mr_modify(const struct vm *vm, uint64_t *pml4_page,
uint64_t prot_set, uint64_t prot_clr); uint64_t prot_set, uint64_t prot_clr);
int ept_mr_del(const struct vm *vm, uint64_t *pml4_page, int ept_mr_del(const struct vm *vm, uint64_t *pml4_page,
uint64_t gpa, uint64_t size); uint64_t gpa, uint64_t size);
void free_ept_mem(void *pml4_addr); void free_ept_mem(uint64_t *pml4_page);
int ept_violation_vmexit_handler(struct vcpu *vcpu); int ept_violation_vmexit_handler(struct vcpu *vcpu);
int ept_misconfig_vmexit_handler(__unused struct vcpu *vcpu); int ept_misconfig_vmexit_handler(__unused struct vcpu *vcpu);