mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
mmu: add mmu invlpg support
when host mmu got updated, it should invalidate TLB & page-struct cache. currently, there is no mmu update will be done after any AP start, so the simplest way(to avoid shootdown) is just do invlpg for BSP. Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Tian, Kevin <kevin.tian@intel.com> Acked-by: Xu, Anthony <anthony.xu@intel.com>
This commit is contained in:
parent
2d6c75408e
commit
ebba622d78
@ -55,7 +55,7 @@ spinlock_t up_count_spinlock = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void *per_cpu_data_base_ptr;
|
void *per_cpu_data_base_ptr;
|
||||||
int phy_cpu_num;
|
int phy_cpu_num = 0;
|
||||||
unsigned long pcpu_sync = 0;
|
unsigned long pcpu_sync = 0;
|
||||||
uint32_t up_count = 0;
|
uint32_t up_count = 0;
|
||||||
|
|
||||||
|
@ -88,6 +88,11 @@ static inline void _invept(uint64_t type, struct invept_desc desc)
|
|||||||
ASSERT(error == 0, "invept error");
|
ASSERT(error == 0, "invept error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void inv_tlb_one_page(void *addr)
|
||||||
|
{
|
||||||
|
asm volatile ("invlpg (%0)" : : "r" (addr) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
static void check_mmu_capability(void)
|
static void check_mmu_capability(void)
|
||||||
{
|
{
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
@ -271,6 +276,24 @@ static uint32_t map_mem_region(void *vaddr, void *paddr,
|
|||||||
|
|
||||||
/* Check to see if mapping should occur */
|
/* Check to see if mapping should occur */
|
||||||
if (mapped_size != 0) {
|
if (mapped_size != 0) {
|
||||||
|
/* Get current table entry */
|
||||||
|
uint64_t entry = MEM_READ64(table_base + table_offset);
|
||||||
|
bool prev_entry_present = false;
|
||||||
|
bool mmu_need_invtlb = false;
|
||||||
|
|
||||||
|
switch(check_page_table_present(table_type, entry)) {
|
||||||
|
case PT_PRESENT:
|
||||||
|
prev_entry_present = true;
|
||||||
|
break;
|
||||||
|
case PT_NOT_PRESENT:
|
||||||
|
prev_entry_present = false;
|
||||||
|
break;
|
||||||
|
case PT_MISCFG_PRESENT:
|
||||||
|
default:
|
||||||
|
ASSERT(0, "entry misconfigurated present bits");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (request_type) {
|
switch (request_type) {
|
||||||
case PAGING_REQUEST_TYPE_MAP:
|
case PAGING_REQUEST_TYPE_MAP:
|
||||||
{
|
{
|
||||||
@ -286,18 +309,27 @@ static uint32_t map_mem_region(void *vaddr, void *paddr,
|
|||||||
|
|
||||||
/* Write the table entry to map this memory */
|
/* Write the table entry to map this memory */
|
||||||
MEM_WRITE64(table_base + table_offset, table_entry);
|
MEM_WRITE64(table_base + table_offset, table_entry);
|
||||||
|
|
||||||
|
/* Invalidate TLB and page-structure cache,
|
||||||
|
* if it is the first mapping no need to invalidate TLB
|
||||||
|
*/
|
||||||
|
if ((table_type == PTT_HOST) && prev_entry_present)
|
||||||
|
mmu_need_invtlb = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PAGING_REQUEST_TYPE_UNMAP:
|
case PAGING_REQUEST_TYPE_UNMAP:
|
||||||
{
|
{
|
||||||
/* Get current table entry */
|
if (prev_entry_present) {
|
||||||
uint64_t entry = MEM_READ64(table_base + table_offset);
|
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
/* Table is present.
|
/* Table is present.
|
||||||
* Write the table entry to map this memory
|
* Write the table entry to map this memory
|
||||||
*/
|
*/
|
||||||
MEM_WRITE64(table_base + table_offset, 0);
|
MEM_WRITE64(table_base + table_offset, 0);
|
||||||
|
|
||||||
|
/* Unmap, need to invalidate TLB and
|
||||||
|
* page-structure cache
|
||||||
|
*/
|
||||||
|
if (table_type == PTT_HOST)
|
||||||
|
mmu_need_invtlb = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -312,12 +344,36 @@ static uint32_t map_mem_region(void *vaddr, void *paddr,
|
|||||||
/* Write the table entry to map this memory */
|
/* Write the table entry to map this memory */
|
||||||
MEM_WRITE64(table_base + table_offset, table_entry);
|
MEM_WRITE64(table_base + table_offset, table_entry);
|
||||||
|
|
||||||
|
/* Modify, need to invalidate TLB and
|
||||||
|
* page-structure cache
|
||||||
|
*/
|
||||||
|
if (table_type == PTT_HOST)
|
||||||
|
mmu_need_invtlb = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ASSERT(0, "Bad memory map request type");
|
ASSERT(0, "Bad memory map request type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mmu_need_invtlb) {
|
||||||
|
/* currently, all native mmu update is done at BSP,
|
||||||
|
* the assumption is that after AP start, there
|
||||||
|
* is no mmu update - so we can avoid shootdown issue
|
||||||
|
* for MP system.
|
||||||
|
* For invlpg after AP start, just panic here.
|
||||||
|
*
|
||||||
|
* TODO: add shootdown APs operation if MMU will be
|
||||||
|
* modified after AP start in the future.
|
||||||
|
*/
|
||||||
|
if ((phy_cpu_num != 0) &&
|
||||||
|
(pcpu_active_bitmap &
|
||||||
|
((1UL << phy_cpu_num) - 1))
|
||||||
|
!= (1UL << CPU_BOOT_ID)) {
|
||||||
|
panic("need shootdown for invlpg");
|
||||||
|
}
|
||||||
|
inv_tlb_one_page(vaddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return mapped size to caller */
|
/* Return mapped size to caller */
|
||||||
|
Loading…
Reference in New Issue
Block a user