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
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
*/
void free_ept_mem(void *pml4_addr)
void free_ept_mem(uint64_t *pml4_page)
{
void *pdpt_addr;
void *pde_addr;
void *pte_addr;
uint32_t pml4_index;
uint32_t pdpt_index;
uint32_t pde_idx;
uint64_t *pdpt_page, *pd_page, *pt_page;
uint64_t *pml4e, *pdpte, *pde;
uint64_t pml4e_idx, pdpte_idx, pde_idx;
for (pml4_index = 0U; pml4_index < IA32E_NUM_ENTRIES; pml4_index++) {
/* Walk from the PML4 table to the PDPT table */
pdpt_addr = HPA2HVA(find_next_table(pml4_index, pml4_addr));
if (pdpt_addr == NULL) {
for (pml4e_idx = 0U; pml4e_idx < PTRS_PER_PML4E; pml4e_idx++) {
pml4e = pml4_page + pml4e_idx;
if (pgentry_present(PTT_EPT, *pml4e) == 0UL) {
continue;
}
pdpt_page = pml4e_page_vaddr(*pml4e);
for (pdpt_index = 0U; pdpt_index < IA32E_NUM_ENTRIES;
pdpt_index++) {
/* Walk from the PDPT table to the PD table */
pde_addr = HPA2HVA(find_next_table(pdpt_index,
pdpt_addr));
if (pde_addr == NULL) {
for (pdpte_idx = 0U; pdpte_idx < PTRS_PER_PDPTE; pdpte_idx++) {
pdpte = pdpt_page + pdpte_idx;
if ((pgentry_present(PTT_EPT, *pdpte) == 0UL) ||
pdpte_large(*pdpte) != 0UL) {
continue;
}
pd_page = pdpte_page_vaddr(*pdpte);
for (pde_idx = 0U; pde_idx < IA32E_NUM_ENTRIES;
pde_idx++) {
/* Walk from the PD table to the page table */
pte_addr = HPA2HVA(find_next_table(pde_idx,
pde_addr));
for (pde_idx = 0U; pde_idx < PTRS_PER_PDE; pde_idx++) {
pde = pd_page + pde_idx;
if ((pgentry_present(PTT_EPT, *pde) == 0UL) ||
pde_large(*pde) != 0UL) {
continue;
}
pt_page = pde_page_vaddr(*pde);
/* Free page table entry table */
if (pte_addr != NULL) {
free_paging_struct(pte_addr);
}
free_paging_struct((void *)pt_page);
}
/* Free page directory entry table */
if (pde_addr != NULL) {
free_paging_struct(pde_addr);
}
free_paging_struct((void *)pd_page);
}
free_paging_struct(pdpt_addr);
free_paging_struct((void *)pdpt_page);
}
free_paging_struct(pml4_addr);
free_paging_struct((void *)pml4_page);
}
void destroy_ept(struct vm *vm)
{
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)
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)

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);
/* memset PDPTEs except trusty memory */
(void)memset(pdpt_addr, 0UL,
NON_TRUSTY_PDPT_ENTRIES * IA32E_COMM_ENTRY_SIZE);
free_ept_mem(vm->arch_vm.sworld_eptp);
NON_TRUSTY_PDPT_ENTRIES * sizeof(uint64_t));
free_ept_mem((uint64_t *)vm->arch_vm.sworld_eptp);
vm->arch_vm.sworld_eptp = NULL;
} else {
pr_err("sworld eptp is NULL");

View File

@ -7,27 +7,6 @@
#ifndef 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
* 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);
int ept_mr_del(const struct vm *vm, uint64_t *pml4_page,
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_misconfig_vmexit_handler(__unused struct vcpu *vcpu);