#define PAGE_S2                        __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
 #define PAGE_S2_DEVICE         __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
 
-#define PAGE_NONE              __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
+#define PAGE_NONE              __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
 #define PAGE_SHARED            __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
 #define PAGE_SHARED_EXEC       __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
-#define PAGE_COPY              __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
-#define PAGE_COPY_EXEC         __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
-#define PAGE_READONLY          __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
-#define PAGE_READONLY_EXEC     __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
-#define PAGE_EXECONLY          __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
+#define PAGE_READONLY          __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_READONLY_EXEC     __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
+#define PAGE_EXECONLY          __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
 
 #define __P000  PAGE_NONE
 #define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
+#define __P010  PAGE_READONLY
+#define __P011  PAGE_READONLY
 #define __P100  PAGE_EXECONLY
 #define __P101  PAGE_READONLY_EXEC
-#define __P110  PAGE_COPY_EXEC
-#define __P111  PAGE_COPY_EXEC
+#define __P110  PAGE_READONLY_EXEC
+#define __P111  PAGE_READONLY_EXEC
 
 #define __S000  PAGE_NONE
 #define __S001  PAGE_READONLY
 
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-       return clear_pte_bit(pte, __pgprot(PTE_WRITE));
+       pte = clear_pte_bit(pte, __pgprot(PTE_WRITE));
+       pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
+       return pte;
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)
 {
-       return set_pte_bit(pte, __pgprot(PTE_WRITE));
+       pte = set_pte_bit(pte, __pgprot(PTE_WRITE));
+       pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY));
+       return pte;
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
        return clear_pte_bit(pte, __pgprot(PTE_CONT));
 }
 
-static inline pte_t pte_clear_rdonly(pte_t pte)
-{
-       return clear_pte_bit(pte, __pgprot(PTE_RDONLY));
-}
-
-static inline pte_t pte_set_rdonly(pte_t pte)
-{
-       return set_pte_bit(pte, __pgprot(PTE_RDONLY));
-}
-
 static inline pte_t pte_mkpresent(pte_t pte)
 {
        return set_pte_bit(pte, __pgprot(PTE_VALID));
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t pte)
 {
-       if (pte_present(pte)) {
-               if (pte_sw_dirty(pte) && pte_write(pte))
-                       pte_val(pte) &= ~PTE_RDONLY;
-               else
-                       pte_val(pte) |= PTE_RDONLY;
-               if (pte_user_exec(pte) && !pte_special(pte))
-                       __sync_icache_dcache(pte, addr);
-       }
+       if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
+               __sync_icache_dcache(pte, addr);
 
        /*
         * If the existing pte is valid, check for potential race with
                old_pte = pte;
                /*
                 * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY
-                * clear), set the PTE_DIRTY and PTE_RDONLY bits.
+                * clear), set the PTE_DIRTY bit.
                 */
-               if (pte_hw_dirty(pte)) {
+               if (pte_hw_dirty(pte))
                        pte = pte_mkdirty(pte);
-                       pte = pte_set_rdonly(pte);
-               }
                pte = pte_wrprotect(pte);
                pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
                                               pte_val(old_pte), pte_val(pte));
 
                 * read only (code, rodata). Clear the RDONLY bit from
                 * the temporary mappings we use during restore.
                 */
-               set_pte(dst_pte, pte_clear_rdonly(pte));
+               set_pte(dst_pte, pte_mkwrite(pte));
        } else if (debug_pagealloc_enabled() && !pte_none(pte)) {
                /*
                 * debug_pagealloc will removed the PTE_VALID bit if
                 */
                BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-               set_pte(dst_pte, pte_mkpresent(pte_clear_rdonly(pte)));
+               set_pte(dst_pte, pte_mkpresent(pte_mkwrite(pte)));
        }
 }
 
 
                return 0;
 
        /* only preserve the access flags and write permission */
-       pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
-
-       /* set PTE_RDONLY if actual read-only or clean PTE */
-       if (!pte_write(entry) || !pte_sw_dirty(entry))
-               entry = pte_set_rdonly(entry);
+       pte_val(entry) &= PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY;
 
        /*
         * Setting the flags must be done atomically to avoid racing with the