mmu: refine functions get_table_entry & obtain_last_page_table_entry

- remove unused map_params in get_table_entry
- add error return for both, which is valid under release version,
  as at that time, ASSERT in get_table_entry is empty.

Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Jason Chen CJ 2018-04-05 07:19:29 +08:00 committed by lijinxia
parent e863b4135c
commit 7611251339
2 changed files with 37 additions and 29 deletions

View File

@ -346,27 +346,22 @@ static inline uint32_t check_page_table_present(struct map_params *map_params,
return (table_entry) ? PT_PRESENT : PT_NOT_PRESENT; return (table_entry) ? PT_PRESENT : PT_NOT_PRESENT;
} }
static uint64_t get_table_entry(struct map_params *map_params, void *addr, static int get_table_entry(void *addr, void *table_base,
void *table_base, uint32_t table_level) uint32_t table_level, uint64_t *table_entry)
{ {
uint32_t table_offset; uint32_t table_offset;
uint64_t table_entry;
int status = 0;
if (table_base == NULL if (table_base == NULL || table_level >= IA32E_UNKNOWN) {
|| table_level >= IA32E_UNKNOWN ASSERT(0, "Incorrect Arguments");
|| map_params == NULL) { return -EINVAL;
status = -EINVAL;
} }
ASSERT(status == 0, "Incorrect Arguments");
table_offset = fetch_page_table_offset(addr, table_level); table_offset = fetch_page_table_offset(addr, table_level);
/* Read the table entry */ /* Read the table entry */
table_entry = MEM_READ64(table_base + table_offset); *table_entry = MEM_READ64(table_base + table_offset);
/* Return the next table in the walk */ return 0;
return table_entry;
} }
static void *walk_paging_struct(void *addr, void *table_base, static void *walk_paging_struct(void *addr, void *table_base,
@ -602,18 +597,20 @@ uint64_t config_page_table_attr(struct map_params *map_params, uint32_t flags)
} }
void obtain_last_page_table_entry(struct map_params *map_params, int obtain_last_page_table_entry(struct map_params *map_params,
struct entry_params *entry, void *addr, bool direct) struct entry_params *entry, void *addr, bool direct)
{ {
uint64_t table_entry; uint64_t table_entry;
uint32_t table_present = 0; uint32_t table_present = 0;
int ret = 0;
/* Obtain the PML4 address */ /* Obtain the PML4 address */
void *table_addr = direct ? (map_params->pml4_base) void *table_addr = direct ? (map_params->pml4_base)
: (map_params->pml4_inverted); : (map_params->pml4_inverted);
/* Obtain page table entry from PML4 table*/ /* Obtain page table entry from PML4 table*/
table_entry = get_table_entry(map_params, addr, ret = get_table_entry(addr, table_addr, IA32E_PML4, &table_entry);
table_addr, IA32E_PML4); if (ret < 0)
return ret;
table_present = check_page_table_present(map_params, table_entry); table_present = check_page_table_present(map_params, table_entry);
if (table_present == PT_NOT_PRESENT) { if (table_present == PT_NOT_PRESENT) {
/* PML4E not present, return PML4 base address */ /* PML4E not present, return PML4 base address */
@ -624,13 +621,14 @@ void obtain_last_page_table_entry(struct map_params *map_params,
(PAGE_SIZE_1G) : (PAGE_SIZE_2M); (PAGE_SIZE_1G) : (PAGE_SIZE_2M);
entry->entry_off = fetch_page_table_offset(addr, IA32E_PML4); entry->entry_off = fetch_page_table_offset(addr, IA32E_PML4);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return; return 0;
} }
/* Obtain page table entry from PDPT table*/ /* Obtain page table entry from PDPT table*/
table_addr = (void *)(table_entry & IA32E_REF_MASK); table_addr = (void *)(table_entry & IA32E_REF_MASK);
table_entry = get_table_entry(map_params, addr, ret = get_table_entry(addr, table_addr, IA32E_PDPT, &table_entry);
table_addr, IA32E_PDPT); if (ret < 0)
return ret;
table_present = check_page_table_present(map_params, table_entry); table_present = check_page_table_present(map_params, table_entry);
if (table_present == PT_NOT_PRESENT) { if (table_present == PT_NOT_PRESENT) {
/* PDPTE not present, return PDPT base address */ /* PDPTE not present, return PDPT base address */
@ -641,7 +639,7 @@ void obtain_last_page_table_entry(struct map_params *map_params,
(PAGE_SIZE_1G) : (PAGE_SIZE_2M); (PAGE_SIZE_1G) : (PAGE_SIZE_2M);
entry->entry_off = fetch_page_table_offset(addr, IA32E_PDPT); entry->entry_off = fetch_page_table_offset(addr, IA32E_PDPT);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return; return 0;
} }
if (table_entry & IA32E_PDPTE_PS_BIT) { if (table_entry & IA32E_PDPTE_PS_BIT) {
/* 1GB page size, return the base addr of the pg entry*/ /* 1GB page size, return the base addr of the pg entry*/
@ -652,13 +650,14 @@ void obtain_last_page_table_entry(struct map_params *map_params,
entry->entry_present = PT_PRESENT; entry->entry_present = PT_PRESENT;
entry->entry_off = fetch_page_table_offset(addr, IA32E_PDPT); entry->entry_off = fetch_page_table_offset(addr, IA32E_PDPT);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return; return 0;
} }
/* Obtain page table entry from PD table*/ /* Obtain page table entry from PD table*/
table_addr = (void *)(table_entry & IA32E_REF_MASK); table_addr = (void *)(table_entry & IA32E_REF_MASK);
table_entry = get_table_entry(map_params, addr, ret = get_table_entry(addr, table_addr, IA32E_PD, &table_entry);
table_addr, IA32E_PD); if (ret < 0)
return ret;
table_present = check_page_table_present(map_params, table_entry); table_present = check_page_table_present(map_params, table_entry);
if (table_present == PT_NOT_PRESENT) { if (table_present == PT_NOT_PRESENT) {
/* PDE not present, return PDE base address */ /* PDE not present, return PDE base address */
@ -668,7 +667,7 @@ void obtain_last_page_table_entry(struct map_params *map_params,
entry->page_size = PAGE_SIZE_2M; entry->page_size = PAGE_SIZE_2M;
entry->entry_off = fetch_page_table_offset(addr, IA32E_PD); entry->entry_off = fetch_page_table_offset(addr, IA32E_PD);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return; return 0;
} }
if (table_entry & IA32E_PDE_PS_BIT) { if (table_entry & IA32E_PDE_PS_BIT) {
@ -679,13 +678,14 @@ void obtain_last_page_table_entry(struct map_params *map_params,
entry->page_size = PAGE_SIZE_2M; entry->page_size = PAGE_SIZE_2M;
entry->entry_off = fetch_page_table_offset(addr, IA32E_PD); entry->entry_off = fetch_page_table_offset(addr, IA32E_PD);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return; return 0;
} }
/* Obtain page table entry from PT table*/ /* Obtain page table entry from PT table*/
table_addr = (void *)(table_entry & IA32E_REF_MASK); table_addr = (void *)(table_entry & IA32E_REF_MASK);
table_entry = get_table_entry(map_params, addr, ret = get_table_entry(addr, table_addr, IA32E_PT, &table_entry);
table_addr, IA32E_PT); if (ret < 0)
return ret;
table_present = check_page_table_present(map_params, table_entry); table_present = check_page_table_present(map_params, table_entry);
entry->entry_present = ((table_present == PT_PRESENT) entry->entry_present = ((table_present == PT_PRESENT)
? (PT_PRESENT):(PT_NOT_PRESENT)); ? (PT_PRESENT):(PT_NOT_PRESENT));
@ -694,6 +694,8 @@ void obtain_last_page_table_entry(struct map_params *map_params,
entry->page_size = PAGE_SIZE_4K; entry->page_size = PAGE_SIZE_4K;
entry->entry_off = fetch_page_table_offset(addr, IA32E_PT); entry->entry_off = fetch_page_table_offset(addr, IA32E_PT);
entry->entry_val = table_entry; entry->entry_val = table_entry;
return 0;
} }
static uint64_t update_page_table_entry(struct map_params *map_params, static uint64_t update_page_table_entry(struct map_params *map_params,
@ -782,7 +784,11 @@ static uint64_t break_page_table(struct map_params *map_params, void *paddr,
} }
if (page_size != next_page_size) { if (page_size != next_page_size) {
obtain_last_page_table_entry(map_params, &entry, vaddr, direct); if (obtain_last_page_table_entry(map_params, &entry, vaddr,
direct) < 0) {
pr_err("Fail to obtain last page table entry");
return 0;
}
/* New entry present - need to allocate a new table */ /* New entry present - need to allocate a new table */
sub_tab_addr = alloc_paging_struct(); sub_tab_addr = alloc_paging_struct();
@ -871,7 +877,9 @@ static int modify_paging(struct map_params *map_params, void *paddr,
* MAP/UNMAP/MODIFY * MAP/UNMAP/MODIFY
*/ */
while (remaining_size > 0) { while (remaining_size > 0) {
obtain_last_page_table_entry(map_params, &entry, vaddr, direct); if (obtain_last_page_table_entry(map_params, &entry, vaddr,
direct) < 0)
return -EINVAL;
/* filter the unmap request, no action in this case*/ /* filter the unmap request, no action in this case*/
page_size = entry.page_size; page_size = entry.page_size;
if ((request_type == PAGING_REQUEST_TYPE_UNMAP) if ((request_type == PAGING_REQUEST_TYPE_UNMAP)

View File

@ -326,7 +326,7 @@ int modify_mem(struct map_params *map_params, void *paddr, void *vaddr,
uint64_t size, uint32_t flags); uint64_t size, uint32_t flags);
void mmu_invept(struct vcpu *vcpu); void mmu_invept(struct vcpu *vcpu);
bool check_continuous_hpa(struct vm *vm, uint64_t gpa, uint64_t size); bool check_continuous_hpa(struct vm *vm, uint64_t gpa, uint64_t size);
void obtain_last_page_table_entry(struct map_params *map_params, int obtain_last_page_table_entry(struct map_params *map_params,
struct entry_params *entry, void *addr, bool direct); struct entry_params *entry, void *addr, bool direct);
int register_mmio_emulation_handler(struct vm *vm, int register_mmio_emulation_handler(struct vm *vm,