]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/powerpc/include/asm/book3s/64/pgtable.h
power/mm: update pte_write and pte_wrprotect to handle savedwrite
[mirror_ubuntu-artful-kernel.git] / arch / powerpc / include / asm / book3s / 64 / pgtable.h
index f0b08acda5ebf845084b33da895807bc86d65ab3..ec1e731e6a2d6dc738d50ca7700e554f438dc050 100644 (file)
@@ -347,7 +347,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
        __r;                                                    \
 })
 
-static inline int pte_write(pte_t pte)
+static inline int __pte_write(pte_t pte)
 {
        return !!(pte_raw(pte) & cpu_to_be64(_PAGE_WRITE));
 }
@@ -373,11 +373,16 @@ static inline bool pte_savedwrite(pte_t pte)
 }
 #endif
 
+static inline int pte_write(pte_t pte)
+{
+       return __pte_write(pte) || pte_savedwrite(pte);
+}
+
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
                                      pte_t *ptep)
 {
-       if (pte_write(*ptep))
+       if (__pte_write(*ptep))
                pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
        else if (unlikely(pte_savedwrite(*ptep)))
                pte_update(mm, addr, ptep, 0, _PAGE_PRIVILEGED, 0);
@@ -390,7 +395,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
         * We should not find protnone for hugetlb, but this complete the
         * interface.
         */
-       if (pte_write(*ptep))
+       if (__pte_write(*ptep))
                pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
        else if (unlikely(pte_savedwrite(*ptep)))
                pte_update(mm, addr, ptep, 0, _PAGE_PRIVILEGED, 1);
@@ -490,7 +495,13 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
        VM_BUG_ON(!pte_protnone(pte));
        return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
 }
-
+#else
+#define pte_clear_savedwrite pte_clear_savedwrite
+static inline pte_t pte_clear_savedwrite(pte_t pte)
+{
+       VM_WARN_ON(1);
+       return __pte(pte_val(pte) & ~_PAGE_WRITE);
+}
 #endif /* CONFIG_NUMA_BALANCING */
 
 static inline int pte_present(pte_t pte)
@@ -518,6 +529,8 @@ static inline unsigned long pte_pfn(pte_t pte)
 /* Generic modifiers for PTE bits */
 static inline pte_t pte_wrprotect(pte_t pte)
 {
+       if (unlikely(pte_savedwrite(pte)))
+               return pte_clear_savedwrite(pte);
        return __pte(pte_val(pte) & ~_PAGE_WRITE);
 }
 
@@ -938,6 +951,7 @@ static inline int pmd_protnone(pmd_t pmd)
 
 #define __HAVE_ARCH_PMD_WRITE
 #define pmd_write(pmd)         pte_write(pmd_pte(pmd))
+#define __pmd_write(pmd)       __pte_write(pmd_pte(pmd))
 #define pmd_savedwrite(pmd)    pte_savedwrite(pmd_pte(pmd))
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -994,7 +1008,7 @@ static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
 static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
                                      pmd_t *pmdp)
 {
-       if (pmd_write((*pmdp)))
+       if (__pmd_write((*pmdp)))
                pmd_hugepage_update(mm, addr, pmdp, _PAGE_WRITE, 0);
        else if (unlikely(pmd_savedwrite(*pmdp)))
                pmd_hugepage_update(mm, addr, pmdp, 0, _PAGE_PRIVILEGED);