Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / arch / powerpc / include / asm / nohash / 32 / pgtable.h
index 6c82b96..3ffb0ff 100644 (file)
@@ -128,14 +128,65 @@ extern int icache_44x_need_flush;
 #include <asm/nohash/32/pte-8xx.h>
 #endif
 
-/* And here we include common definitions */
-#include <asm/pte-common.h>
+/*
+ * Location of the PFN in the PTE. Most 32-bit platforms use the same
+ * as _PAGE_SHIFT here (ie, naturally aligned).
+ * Platform who don't just pre-define the value so we don't override it here.
+ */
+#ifndef PTE_RPN_SHIFT
+#define PTE_RPN_SHIFT  (PAGE_SHIFT)
+#endif
+
+/*
+ * The mask covered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs.
+ */
+#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+#define PTE_RPN_MASK   (~((1ULL << PTE_RPN_SHIFT) - 1))
+#else
+#define PTE_RPN_MASK   (~((1UL << PTE_RPN_SHIFT) - 1))
+#endif
+
+/*
+ * _PAGE_CHG_MASK masks of bits that are to be preserved across
+ * pgprot changes.
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPECIAL)
 
 #ifndef __ASSEMBLY__
 
 #define pte_clear(mm, addr, ptep) \
        do { pte_update(ptep, ~0, 0); } while (0)
 
+#ifndef pte_mkwrite
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+       return __pte(pte_val(pte) | _PAGE_RW);
+}
+#endif
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+       return __pte(pte_val(pte) | _PAGE_DIRTY);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+       return __pte(pte_val(pte) | _PAGE_ACCESSED);
+}
+
+#ifndef pte_wrprotect
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+       return __pte(pte_val(pte) & ~_PAGE_RW);
+}
+#endif
+
+static inline pte_t pte_mkexec(pte_t pte)
+{
+       return __pte(pte_val(pte) | _PAGE_EXEC);
+}
+
 #define pmd_none(pmd)          (!pmd_val(pmd))
 #define        pmd_bad(pmd)            (pmd_val(pmd) & _PMD_BAD)
 #define        pmd_present(pmd)        (pmd_val(pmd) & _PMD_PRESENT_MASK)
@@ -244,7 +295,10 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
                                      pte_t *ptep)
 {
-       pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
+       unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
+       unsigned long set = pte_val(pte_wrprotect(__pte(0)));
+
+       pte_update(ptep, clr, set);
 }
 
 static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
@@ -252,9 +306,10 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
                                           unsigned long address,
                                           int psize)
 {
-       unsigned long set = pte_val(entry) &
-               (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
-       unsigned long clr = ~pte_val(entry) & (_PAGE_RO | _PAGE_NA);
+       pte_t pte_set = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0)))));
+       pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0)))));
+       unsigned long set = pte_val(entry) & pte_val(pte_set);
+       unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr);
 
        pte_update(ptep, clr, set);
 
@@ -317,7 +372,7 @@ static inline int pte_young(pte_t pte)
 #define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) >> 3 })
 #define __swp_entry_to_pte(x)          ((pte_t) { (x).val << 3 })
 
-int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
+int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
 
 #endif /* !__ASSEMBLY__ */