@ -87,6 +87,11 @@
# define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */
# define L_PTE_NONE (_AT(pteval_t, 1) << 57) /* PROT_NONE */
# define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0)
# define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
# define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 56)
# define PMD_SECT_NONE (_AT(pmdval_t, 1) << 57)
/*
* To be used in assembly code with the upper page attributes .
*/
@ -196,6 +201,61 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
# define pte_huge(pte) (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
# define pte_mkhuge(pte) (__pte(pte_val(pte) & ~PTE_TABLE_BIT))
# define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
# define __HAVE_ARCH_PMD_WRITE
# define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
# ifdef CONFIG_TRANSPARENT_HUGEPAGE
# define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
# define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
# endif
# define PMD_BIT_FUNC(fn,op) \
static inline pmd_t pmd_ # # fn ( pmd_t pmd ) { pmd_val ( pmd ) op ; return pmd ; }
PMD_BIT_FUNC ( wrprotect , | = PMD_SECT_RDONLY ) ;
PMD_BIT_FUNC ( mkold , & = ~ PMD_SECT_AF ) ;
PMD_BIT_FUNC ( mksplitting , | = PMD_SECT_SPLITTING ) ;
PMD_BIT_FUNC ( mkwrite , & = ~ PMD_SECT_RDONLY ) ;
PMD_BIT_FUNC ( mkdirty , | = PMD_SECT_DIRTY ) ;
PMD_BIT_FUNC ( mkyoung , | = PMD_SECT_AF ) ;
# define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
# define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
# define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
# define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
# define pmd_mknotpresent(pmd) (__pmd(0))
static inline pmd_t pmd_modify ( pmd_t pmd , pgprot_t newprot )
{
const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY |
PMD_SECT_VALID | PMD_SECT_NONE ;
pmd_val ( pmd ) = ( pmd_val ( pmd ) & ~ mask ) | ( pgprot_val ( newprot ) & mask ) ;
return pmd ;
}
static inline void set_pmd_at ( struct mm_struct * mm , unsigned long addr ,
pmd_t * pmdp , pmd_t pmd )
{
BUG_ON ( addr > = TASK_SIZE ) ;
/* create a faulting entry if PROT_NONE protected */
if ( pmd_val ( pmd ) & PMD_SECT_NONE )
pmd_val ( pmd ) & = ~ PMD_SECT_VALID ;
* pmdp = __pmd ( pmd_val ( pmd ) | PMD_SECT_nG ) ;
flush_pmd_entry ( pmdp ) ;
}
static inline int has_transparent_hugepage ( void )
{
return 1 ;
}
# endif /* __ASSEMBLY__ */
# endif /* _ASM_PGTABLE_3LEVEL_H */