diff options
Diffstat (limited to 'include/asm-um/pgtable.h')
-rw-r--r-- | include/asm-um/pgtable.h | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index a88040920311..b48e0966ecd7 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h @@ -16,13 +16,15 @@ #define _PAGE_PRESENT 0x001 #define _PAGE_NEWPAGE 0x002 -#define _PAGE_NEWPROT 0x004 -#define _PAGE_FILE 0x008 /* set:pagecache unset:swap */ -#define _PAGE_PROTNONE 0x010 /* If not present */ +#define _PAGE_NEWPROT 0x004 #define _PAGE_RW 0x020 #define _PAGE_USER 0x040 #define _PAGE_ACCESSED 0x080 #define _PAGE_DIRTY 0x100 +/* If _PAGE_PRESENT is clear, we use these: */ +#define _PAGE_FILE 0x008 /* nonlinear file mapping, saved PTE; unset:swap */ +#define _PAGE_PROTNONE 0x010 /* if the user mapped it with PROT_NONE; + pte_present gives true */ #ifdef CONFIG_3_LEVEL_PGTABLES #include "asm/pgtable-3level.h" @@ -151,10 +153,24 @@ extern unsigned long pg0[1024]; #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK) +#define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_address(x) (__va(pte_val(x) & PAGE_MASK)) #define mk_phys(a, r) ((a) + (((unsigned long) r) << REGION_SHIFT)) #define phys_addr(p) ((p) & ~REGION_MASK) +#define pte_present(x) pte_get_bits(x, (_PAGE_PRESENT | _PAGE_PROTNONE)) + +/* + * ================================= + * Flags checking section. + * ================================= + */ + +static inline int pte_none(pte_t pte) +{ + return pte_is_zero(pte); +} + /* * The following only work if pte_present() is true. * Undefined behaviour if not.. @@ -210,6 +226,18 @@ static inline int pte_newprot(pte_t pte) return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT))); } +/* + * ================================= + * Flags setting section. + * ================================= + */ + +static inline pte_t pte_mknewprot(pte_t pte) +{ + pte_set_bits(pte, _PAGE_NEWPROT); + return(pte); +} + static inline pte_t pte_rdprotect(pte_t pte) { pte_clear_bits(pte, _PAGE_USER); @@ -278,6 +306,26 @@ static inline pte_t pte_mkuptodate(pte_t pte) return(pte); } +static inline pte_t pte_mknewpage(pte_t pte) +{ + pte_set_bits(pte, _PAGE_NEWPAGE); + return(pte); +} + +static inline void set_pte(pte_t *pteptr, pte_t pteval) +{ + pte_copy(*pteptr, pteval); + + /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so + * fix_range knows to unmap it. _PAGE_NEWPROT is specific to + * mapped pages. + */ + + *pteptr = pte_mknewpage(*pteptr); + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr); +} +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + extern phys_t page_to_phys(struct page *page); /* |