Merge branch 'akpm' (patches from Andrew)
[cascardo/linux.git] / arch / mips / include / asm / pgtable.h
index f6de4f4..a6b611f 100644 (file)
@@ -133,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)
 
@@ -143,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;
+               }
        }
 }
 
@@ -160,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();
@@ -302,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;
 }
@@ -309,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;
 }
@@ -316,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;
 }
@@ -323,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_NO_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
@@ -438,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);
@@ -447,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)
 {
@@ -492,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)