diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm64/include/asm/pgtable.h | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 27c78395ae76..b524dcd17243 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ | 28 | #define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ |
| 29 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) | 29 | #define PTE_DIRTY (_AT(pteval_t, 1) << 55) |
| 30 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) | 30 | #define PTE_SPECIAL (_AT(pteval_t, 1) << 56) |
| 31 | /* bit 57 for PMD_SECT_SPLITTING */ | 31 | #define PTE_WRITE (_AT(pteval_t, 1) << 57) |
| 32 | #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ | 32 | #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| @@ -67,15 +67,15 @@ extern pgprot_t pgprot_default; | |||
| 67 | 67 | ||
| 68 | #define _MOD_PROT(p, b) __pgprot_modify(p, 0, b) | 68 | #define _MOD_PROT(p, b) __pgprot_modify(p, 0, b) |
| 69 | 69 | ||
| 70 | #define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) | 70 | #define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_PXN | PTE_UXN) |
| 71 | #define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | 71 | #define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) |
| 72 | #define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) | 72 | #define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) |
| 73 | #define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 73 | #define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
| 74 | #define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | 74 | #define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) |
| 75 | #define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 75 | #define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
| 76 | #define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | 76 | #define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) |
| 77 | #define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) | 77 | #define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) |
| 78 | #define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) | 78 | #define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY | PTE_WRITE) |
| 79 | 79 | ||
| 80 | #define PAGE_HYP _MOD_PROT(pgprot_default, PTE_HYP) | 80 | #define PAGE_HYP _MOD_PROT(pgprot_default, PTE_HYP) |
| 81 | #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) | 81 | #define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) |
| @@ -83,13 +83,13 @@ extern pgprot_t pgprot_default; | |||
| 83 | #define PAGE_S2 __pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) | 83 | #define PAGE_S2 __pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) |
| 84 | #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN) | 84 | #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN) |
| 85 | 85 | ||
| 86 | #define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) | 86 | #define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) |
| 87 | #define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | 87 | #define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) |
| 88 | #define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) | 88 | #define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) |
| 89 | #define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 89 | #define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
| 90 | #define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | 90 | #define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) |
| 91 | #define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | 91 | #define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) |
| 92 | #define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | 92 | #define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) |
| 93 | 93 | ||
| 94 | #endif /* __ASSEMBLY__ */ | 94 | #endif /* __ASSEMBLY__ */ |
| 95 | 95 | ||
| @@ -140,7 +140,7 @@ extern struct page *empty_zero_page; | |||
| 140 | #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) | 140 | #define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) |
| 141 | #define pte_young(pte) (pte_val(pte) & PTE_AF) | 141 | #define pte_young(pte) (pte_val(pte) & PTE_AF) |
| 142 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) | 142 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) |
| 143 | #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) | 143 | #define pte_write(pte) (pte_val(pte) & PTE_WRITE) |
| 144 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) | 144 | #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) |
| 145 | 145 | ||
| 146 | #define pte_valid_user(pte) \ | 146 | #define pte_valid_user(pte) \ |
| @@ -148,13 +148,13 @@ extern struct page *empty_zero_page; | |||
| 148 | 148 | ||
| 149 | static inline pte_t pte_wrprotect(pte_t pte) | 149 | static inline pte_t pte_wrprotect(pte_t pte) |
| 150 | { | 150 | { |
| 151 | pte_val(pte) |= PTE_RDONLY; | 151 | pte_val(pte) &= ~PTE_WRITE; |
| 152 | return pte; | 152 | return pte; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static inline pte_t pte_mkwrite(pte_t pte) | 155 | static inline pte_t pte_mkwrite(pte_t pte) |
| 156 | { | 156 | { |
| 157 | pte_val(pte) &= ~PTE_RDONLY; | 157 | pte_val(pte) |= PTE_WRITE; |
| 158 | return pte; | 158 | return pte; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| @@ -201,8 +201,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 201 | if (pte_valid_user(pte)) { | 201 | if (pte_valid_user(pte)) { |
| 202 | if (pte_exec(pte)) | 202 | if (pte_exec(pte)) |
| 203 | __sync_icache_dcache(pte, addr); | 203 | __sync_icache_dcache(pte, addr); |
| 204 | if (!pte_dirty(pte)) | 204 | if (pte_dirty(pte) && pte_write(pte)) |
| 205 | pte = pte_wrprotect(pte); | 205 | pte_val(pte) &= ~PTE_RDONLY; |
| 206 | else | ||
| 207 | pte_val(pte) |= PTE_RDONLY; | ||
| 206 | } | 208 | } |
| 207 | 209 | ||
| 208 | set_pte(ptep, pte); | 210 | set_pte(ptep, pte); |
| @@ -376,7 +378,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | |||
| 376 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 378 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 377 | { | 379 | { |
| 378 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | | 380 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | |
| 379 | PTE_PROT_NONE | PTE_VALID; | 381 | PTE_PROT_NONE | PTE_VALID | PTE_WRITE; |
| 380 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); | 382 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); |
| 381 | return pte; | 383 | return pte; |
| 382 | } | 384 | } |
