hv: page: add free_page

Add free_page to free page when unmap pagetable.

Signed-off-by: Li Fei1 <fei1.li@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Tracked-On: #5788
This commit is contained in:
Li Fei1 2021-02-19 14:27:35 +08:00 committed by wenlingz
parent 04a104e856
commit 38be61e374
3 changed files with 42 additions and 2 deletions

View File

@ -73,6 +73,20 @@ struct page *alloc_page(struct page_pool *pool)
return page;
}
/*
*@pre: ((page - pool->start_page) >> 6U) < pool->bitmap_size
*/
void free_page(struct page_pool *pool, struct page *page)
{
uint64_t idx, bit;
spinlock_obtain(&pool->lock);
idx = (page - pool->start_page) >> 6U;
bit = (page - pool->start_page) & 0x3fUL;
bitmap_clear_nolock(bit, pool->bitmap + idx);
spinlock_release(&pool->lock);
}
/* @pre: The PPT and EPT have same page granularity */
static inline bool large_page_support(enum _page_table_level level)
{

View File

@ -13,6 +13,27 @@
#define DBG_LEVEL_MMU 6U
static void try_to_free_pgtable_page(const struct memory_ops *mem_ops,
uint64_t *pde, uint64_t *pt_page, uint32_t type)
{
if (type == MR_DEL) {
uint64_t index;
for (index = 0UL; index < PTRS_PER_PTE; index++) {
uint64_t *pte = pt_page + index;
if ((mem_ops->pgentry_present(*pte) != 0UL)) {
break;
}
}
if (index == PTRS_PER_PTE) {
free_page(mem_ops->pool, (void *)pt_page);
sanitize_pte_entry(pde, mem_ops);
}
}
}
/*
* Split a large page table into next level page table.
*
@ -85,7 +106,7 @@ static inline void construct_pgentry(uint64_t *pde, void *pd_page, uint64_t prot
* type: MR_DEL
* delete [vaddr_start, vaddr_end) MT PT mapping
*/
static void modify_or_del_pte(const uint64_t *pde, uint64_t vaddr_start, uint64_t vaddr_end,
static void modify_or_del_pte(uint64_t *pde, uint64_t vaddr_start, uint64_t vaddr_end,
uint64_t prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type)
{
uint64_t *pt_page = pde_page_vaddr(*pde);
@ -113,6 +134,8 @@ static void modify_or_del_pte(const uint64_t *pde, uint64_t vaddr_start, uint64_
break;
}
}
try_to_free_pgtable_page(mem_ops, pde, pt_page, type);
}
/*
@ -122,7 +145,7 @@ static void modify_or_del_pte(const uint64_t *pde, uint64_t vaddr_start, uint64_
* type: MR_DEL
* delete [vaddr_start, vaddr_end) MT PT mapping
*/
static void modify_or_del_pde(const uint64_t *pdpte, uint64_t vaddr_start, uint64_t vaddr_end,
static void modify_or_del_pde(uint64_t *pdpte, uint64_t vaddr_start, uint64_t vaddr_end,
uint64_t prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type)
{
uint64_t *pd_page = pdpte_page_vaddr(*pdpte);
@ -158,6 +181,8 @@ static void modify_or_del_pde(const uint64_t *pdpte, uint64_t vaddr_start, uint6
}
vaddr = vaddr_next;
}
try_to_free_pgtable_page(mem_ops, pdpte, pd_page, type);
}
/*

View File

@ -79,6 +79,7 @@ struct memory_ops {
extern const struct memory_ops ppt_mem_ops;
void init_ept_mem_ops(struct memory_ops *mem_ops, uint16_t vm_id);
struct page *alloc_page(struct page_pool *pool);
void free_page(struct page_pool *pool, struct page *page);
void *get_reserve_sworld_memory_base(void);
void reserve_buffer_for_ept_pages(void);
#endif /* PAGE_H */