ContiguousPTE[1/12] add page table access functions
Change-Id: I3291c170e66592c871f316d78d71248d26748501
This commit is contained in:
committed by
Masamichi Takagi
parent
8a2f4be443
commit
d1b36aab62
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user