/*
* The following only work if pte_present(). Undefined behaviour otherwise.
*/
-#define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
-#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
-#define pte_young(pte) (pte_val(pte) & PTE_AF)
-#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
-#define pte_write(pte) (pte_val(pte) & PTE_WRITE)
+#define pte_present(pte) (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)))
+#define pte_dirty(pte) (!!(pte_val(pte) & PTE_DIRTY))
+#define pte_young(pte) (!!(pte_val(pte) & PTE_AF))
+#define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL))
+#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
#define pte_valid_user(pte) \
pte_t *ptep, pte_t pte)
{
if (pte_valid_user(pte)) {
- if (pte_exec(pte))
+ if (!pte_special(pte) && pte_exec(pte))
__sync_icache_dcache(pte, addr);
if (pte_dirty(pte) && pte_write(pte))
pte_val(pte) &= ~PTE_RDONLY;
#define __HAVE_ARCH_PTE_SPECIAL
- /*
- * Software PMD bits for THP
- */
+ static inline pte_t pmd_pte(pmd_t pmd)
+ {
+ return __pte(pmd_val(pmd));
+ }
- #define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
- #define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
+ static inline pmd_t pte_pmd(pte_t pte)
+ {
+ return __pmd(pte_val(pte));
+ }
/*
* THP definitions.
*/
- #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)
+ #define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
#endif
- #define PMD_BIT_FUNC(fn,op) \
- static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+ #define pmd_young(pmd) pte_young(pmd_pte(pmd))
+ #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+ #define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
+ #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
+ #define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+ #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+ #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+ #define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
- 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);
- PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
+ #define __HAVE_ARCH_PMD_WRITE
+ #define pmd_write(pmd) pte_write(pmd_pte(pmd))
#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
- static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
- {
- const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
- PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
- PMD_SECT_VALID;
- pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
- return pmd;
- }
-
#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
static inline int has_transparent_hugepage(void)
* Mark the prot value as uncacheable and unbufferable.
*/
#define pgprot_noncached(prot) \
- __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
#define pgprot_writecombine(prot) \
- __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
- #define pgprot_dmacoherent(prot) \
- __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
return pte;
}
+ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+ {
+ return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
+ }
+
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern pgd_t idmap_pg_dir[PTRS_PER_PGD];