Merge branch 'akpm' (patches from Andrew)
[cascardo/linux.git] / arch / mips / include / asm / pgtable.h
index 7f42250..a6b611f 100644 (file)
 struct mm_struct;
 struct vm_area_struct;
 
-#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | \
+#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
+                                _CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
                                 _page_cachable_default)
-#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_NO_EXEC | \
+#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
                                 _page_cachable_default)
-#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_READ | \
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | \
                                 _page_cachable_default)
 #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
                                 _PAGE_GLOBAL | _page_cachable_default)
 #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
                                 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
                                 _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
                        __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
@@ -132,7 +133,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 
-#define pte_none(pte)          (!(((pte).pte_high) & ~_PAGE_GLOBAL))
+#ifdef CONFIG_XPA
+# define pte_none(pte)         (!(((pte).pte_high) & ~_PAGE_GLOBAL))
+#else
+# define pte_none(pte)         (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
+#endif
+
 #define pte_present(pte)       ((pte).pte_low & _PAGE_PRESENT)
 #define pte_no_exec(pte)       ((pte).pte_low & _PAGE_NO_EXEC)
 
@@ -142,14 +148,21 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
        smp_wmb();
        ptep->pte_low = pte.pte_low;
 
+#ifdef CONFIG_XPA
        if (pte.pte_high & _PAGE_GLOBAL) {
+#else
+       if (pte.pte_low & _PAGE_GLOBAL) {
+#endif
                pte_t *buddy = ptep_buddy(ptep);
                /*
                 * Make sure the buddy is global too (if it's !none,
                 * it better already be global)
                 */
-               if (pte_none(*buddy))
+               if (pte_none(*buddy)) {
+                       if (!config_enabled(CONFIG_XPA))
+                               buddy->pte_low |= _PAGE_GLOBAL;
                        buddy->pte_high |= _PAGE_GLOBAL;
+               }
        }
 }
 
@@ -159,8 +172,13 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
 
        htw_stop();
        /* Preserve global status for the pair */
-       if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL)
-               null.pte_high = _PAGE_GLOBAL;
+       if (config_enabled(CONFIG_XPA)) {
+               if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL)
+                       null.pte_high = _PAGE_GLOBAL;
+       } else {
+               if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
+                       null.pte_low = null.pte_high = _PAGE_GLOBAL;
+       }
 
        set_pte_at(mm, addr, ptep, null);
        htw_start();
@@ -301,6 +319,8 @@ static inline int pte_young(pte_t pte)      { return pte.pte_low & _PAGE_ACCESSED; }
 static inline pte_t pte_wrprotect(pte_t pte)
 {
        pte.pte_low  &= ~_PAGE_WRITE;
+       if (!config_enabled(CONFIG_XPA))
+               pte.pte_low &= ~_PAGE_SILENT_WRITE;
        pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
@@ -308,6 +328,8 @@ static inline pte_t pte_wrprotect(pte_t pte)
 static inline pte_t pte_mkclean(pte_t pte)
 {
        pte.pte_low  &= ~_PAGE_MODIFIED;
+       if (!config_enabled(CONFIG_XPA))
+               pte.pte_low &= ~_PAGE_SILENT_WRITE;
        pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
@@ -315,6 +337,8 @@ static inline pte_t pte_mkclean(pte_t pte)
 static inline pte_t pte_mkold(pte_t pte)
 {
        pte.pte_low  &= ~_PAGE_ACCESSED;
+       if (!config_enabled(CONFIG_XPA))
+               pte.pte_low &= ~_PAGE_SILENT_READ;
        pte.pte_high &= ~_PAGE_SILENT_READ;
        return pte;
 }
@@ -322,24 +346,33 @@ static inline pte_t pte_mkold(pte_t pte)
 static inline pte_t pte_mkwrite(pte_t pte)
 {
        pte.pte_low |= _PAGE_WRITE;
-       if (pte.pte_low & _PAGE_MODIFIED)
+       if (pte.pte_low & _PAGE_MODIFIED) {
+               if (!config_enabled(CONFIG_XPA))
+                       pte.pte_low |= _PAGE_SILENT_WRITE;
                pte.pte_high |= _PAGE_SILENT_WRITE;
+       }
        return pte;
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
        pte.pte_low |= _PAGE_MODIFIED;
-       if (pte.pte_low & _PAGE_WRITE)
+       if (pte.pte_low & _PAGE_WRITE) {
+               if (!config_enabled(CONFIG_XPA))
+                       pte.pte_low |= _PAGE_SILENT_WRITE;
                pte.pte_high |= _PAGE_SILENT_WRITE;
+       }
        return pte;
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
        pte.pte_low |= _PAGE_ACCESSED;
-       if (pte.pte_low & _PAGE_READ)
+       if (!(pte.pte_low & _PAGE_NO_READ)) {
+               if (!config_enabled(CONFIG_XPA))
+                       pte.pte_low |= _PAGE_SILENT_READ;
                pte.pte_high |= _PAGE_SILENT_READ;
+       }
        return pte;
 }
 #else
@@ -384,13 +417,8 @@ static inline pte_t pte_mkdirty(pte_t pte)
 static inline pte_t pte_mkyoung(pte_t pte)
 {
        pte_val(pte) |= _PAGE_ACCESSED;
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_CPU_LOONGSON3)
        if (!(pte_val(pte) & _PAGE_NO_READ))
                pte_val(pte) |= _PAGE_SILENT_READ;
-       else
-#endif
-       if (pte_val(pte) & _PAGE_READ)
-               pte_val(pte) |= _PAGE_SILENT_READ;
        return pte;
 }
 
@@ -442,7 +470,7 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
  */
 #define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
 
-#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
+#if defined(CONFIG_XPA)
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
        pte.pte_low  &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK);
@@ -451,6 +479,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK;
        return pte;
 }
+#elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+       pte.pte_low  &= _PAGE_CHG_MASK;
+       pte.pte_high &= (_PFN_MASK | _CACHE_MASK);
+       pte.pte_low  |= pgprot_val(newprot);
+       pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK);
+       return pte;
+}
 #else
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
@@ -496,6 +533,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 
+#define has_transparent_hugepage has_transparent_hugepage
 extern int has_transparent_hugepage(void);
 
 static inline int pmd_trans_huge(pmd_t pmd)
@@ -570,13 +608,8 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
 {
        pmd_val(pmd) |= _PAGE_ACCESSED;
 
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_CPU_LOONGSON3)
        if (!(pmd_val(pmd) & _PAGE_NO_READ))
                pmd_val(pmd) |= _PAGE_SILENT_READ;
-       else
-#endif
-       if (pmd_val(pmd) & _PAGE_READ)
-               pmd_val(pmd) |= _PAGE_SILENT_READ;
 
        return pmd;
 }