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; 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 */ /* @pre: The PPT and EPT have same page granularity */
static inline bool large_page_support(enum _page_table_level level) static inline bool large_page_support(enum _page_table_level level)
{ {

View File

@ -13,6 +13,27 @@
#define DBG_LEVEL_MMU 6U #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. * 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 * type: MR_DEL
* delete [vaddr_start, vaddr_end) MT PT mapping * 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 prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type)
{ {
uint64_t *pt_page = pde_page_vaddr(*pde); 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; 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 * type: MR_DEL
* delete [vaddr_start, vaddr_end) MT PT mapping * 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 prot_set, uint64_t prot_clr, const struct memory_ops *mem_ops, uint32_t type)
{ {
uint64_t *pd_page = pdpte_page_vaddr(*pdpte); 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; 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; extern const struct memory_ops ppt_mem_ops;
void init_ept_mem_ops(struct memory_ops *mem_ops, uint16_t vm_id); void init_ept_mem_ops(struct memory_ops *mem_ops, uint16_t vm_id);
struct page *alloc_page(struct page_pool *pool); 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 *get_reserve_sworld_memory_base(void);
void reserve_buffer_for_ept_pages(void); void reserve_buffer_for_ept_pages(void);
#endif /* PAGE_H */ #endif /* PAGE_H */