|
@@ -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);
|