mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 14:33:38 +00:00
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:
parent
e863b4135c
commit
7611251339
@ -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)
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user