ContiguousPTE[1/12] add page table access functions

Change-Id: I3291c170e66592c871f316d78d71248d26748501
This commit is contained in:
TOIDA,Suguru
2018-11-30 09:17:05 +09:00
committed by Masamichi Takagi
parent 8a2f4be443
commit d1b36aab62
3 changed files with 438 additions and 27 deletions

View File

@ -387,6 +387,7 @@ static inline void ptl_set(pte_t* p, pte_t v, int level)
panic("ptl_set failed.\n");
}
}
/* clear */
static inline void ptl4_clear(pte_t* l4p)
{
@ -407,22 +408,23 @@ static inline void ptl1_clear(pte_t* l1p)
static inline void ptl_clear(pte_t* p, int level)
{
switch (level) {
case 4:
case 4:
ptl4_clear(p);
break;
case 3:
case 3:
ptl3_clear(p);
break;
case 2:
case 2:
ptl2_clear(p);
break;
case 1:
case 1:
ptl1_clear(p);
break;
default:
panic("ptl_clear failed.\n");
}
}
/* null */
static inline int ptl4_null(const pte_t* l4p)
{
@ -465,6 +467,7 @@ static inline int ptl_null(const pte_t* p, int level)
}
return ret;
}
/* present */
static inline int ptl4_present(const pte_t* l4p)
{
@ -507,6 +510,7 @@ static inline int ptl_present(const pte_t* p, int level)
}
return ret;
}
/* type_block/type_page */
static inline int ptl4_type_block(const pte_t* l4p)
{
@ -553,6 +557,55 @@ static inline int ptl_type_page(const pte_t* p, int level)
}
return ret;
}
/* contiguous */
static inline int ptl4_is_contiguous(const pte_t *l4p)
{
pte_t pte = ptl4_val(l4p);
return pte_is_contiguous(&pte);
}
static inline int ptl3_is_contiguous(const pte_t *l3p)
{
pte_t pte = ptl3_val(l3p);
return pte_is_contiguous(&pte);
}
static inline int ptl2_is_contiguous(const pte_t *l2p)
{
pte_t pte = ptl2_val(l2p);
return pte_is_contiguous(&pte);
}
static inline int ptl1_is_contiguous(const pte_t *l1p)
{
pte_t pte = ptl1_val(l1p);
return pte_is_contiguous(&pte);
}
static inline int ptl_is_contiguous(const pte_t *p, int level)
{
int ret = 0;
switch (level) {
case 4:
ret = ptl4_is_contiguous(p);
break;
case 3:
ret = ptl3_is_contiguous(p);
break;
case 2:
ret = ptl2_is_contiguous(p);
break;
case 1:
ret = ptl1_is_contiguous(p);
break;
default:
panic("ptl_is_contiguous failed.\n");
}
return ret;
}
/* type_table */
static inline int ptl4_type_table(const pte_t* l4p)
{
@ -594,6 +647,7 @@ static inline int ptl_type_table(const pte_t* p, int level)
}
return ret;
}
/* phys */
static inline unsigned long ptl4_phys(const pte_t* l4p)
{
@ -636,6 +690,7 @@ static inline unsigned long ptl_phys(const pte_t* p, int level)
}
return ret;
}
/* dirty */
static inline int ptl4_dirty(const pte_t* l4p)
{
@ -678,6 +733,7 @@ static inline int ptl_dirty(const pte_t* p, int level)
}
return ret;
}
/* fileoff */
static inline int ptl4_fileoff(const pte_t* l4p)
{
@ -3156,3 +3212,45 @@ void remote_flush_tlb_cpumask(struct process_vm *vm,
}
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
void arch_adjust_allocate_page_size(uintptr_t fault_addr,
pte_t *ptep,
void **pgaddrp,
size_t *pgsizep)
{
if (ptep == NULL) {
int level = pgsize_to_tbllv(*pgsizep);
*pgsizep = tbllv_to_pgsize(level);
*pgaddrp = (void *)__page_align(fault_addr, *pgsizep);
} else if (pte_is_null(ptep) && pgsize_is_contiguous(*pgsizep)) {
struct memobj *obj;
uintptr_t zeropage = NOPHYS;
pte_t *head;
pte_t *tail;
if (zeroobj_create(&obj)) {
panic("zeroobj_create");
}
memobj_get_page(obj, 0, PAGE_P2ALIGN, &zeropage, NULL, 0);
head = get_contiguous_head(ptep, *pgsizep);
tail = get_contiguous_tail(ptep, *pgsizep);
for (/*nop*/; head <= tail; head++) {
uintptr_t phys;
int level;
if (pte_is_null(head)) {
continue;
}
phys = pte_get_phys(head);
if (phys == zeropage) {
continue;
}
level = pgsize_to_tbllv(*pgsizep);
*pgsizep = tbllv_to_pgsize(level);
*pgaddrp = (void *)__page_align(fault_addr, *pgsizep);
break;
}
}
}