aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/pgtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/include/asm/pgtable.h')
-rw-r--r--arch/arm64/include/asm/pgtable.h36
1 files changed, 20 insertions, 16 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 64b133949502..e333a243bfcc 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -24,7 +24,8 @@
24/* 24/*
25 * Software defined PTE bits definition. 25 * Software defined PTE bits definition.
26 */ 26 */
27#define PTE_VALID (_AT(pteval_t, 1) << 0) /* pte_present() check */ 27#define PTE_VALID (_AT(pteval_t, 1) << 0)
28#define PTE_PROT_NONE (_AT(pteval_t, 1) << 1) /* only when !PTE_VALID */
28#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ 29#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
29#define PTE_DIRTY (_AT(pteval_t, 1) << 55) 30#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
30#define PTE_SPECIAL (_AT(pteval_t, 1) << 56) 31#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
@@ -60,9 +61,12 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
60 61
61extern pgprot_t pgprot_default; 62extern pgprot_t pgprot_default;
62 63
63#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) 64#define __pgprot_modify(prot,mask,bits) \
65 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
66
67#define _MOD_PROT(p, b) __pgprot_modify(p, 0, b)
64 68
65#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 69#define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE)
66#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 70#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
67#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) 71#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
68#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 72#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
@@ -72,7 +76,7 @@ extern pgprot_t pgprot_default;
72#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) 76#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
73#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) 77#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
74 78
75#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 79#define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE)
76#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 80#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
77#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 81#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
78#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 82#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
@@ -125,16 +129,15 @@ extern struct page *empty_zero_page;
125/* 129/*
126 * The following only work if pte_present(). Undefined behaviour otherwise. 130 * The following only work if pte_present(). Undefined behaviour otherwise.
127 */ 131 */
128#define pte_present(pte) (pte_val(pte) & PTE_VALID) 132#define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
129#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) 133#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
130#define pte_young(pte) (pte_val(pte) & PTE_AF) 134#define pte_young(pte) (pte_val(pte) & PTE_AF)
131#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) 135#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
132#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) 136#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
133#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) 137#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
134 138
135#define pte_present_exec_user(pte) \ 139#define pte_valid_user(pte) \
136 ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ 140 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
137 (PTE_VALID | PTE_USER))
138 141
139#define PTE_BIT_FUNC(fn,op) \ 142#define PTE_BIT_FUNC(fn,op) \
140static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 143static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
@@ -157,10 +160,13 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
157static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, 160static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
158 pte_t *ptep, pte_t pte) 161 pte_t *ptep, pte_t pte)
159{ 162{
160 if (pte_present_exec_user(pte)) 163 if (pte_valid_user(pte)) {
161 __sync_icache_dcache(pte, addr); 164 if (pte_exec(pte))
162 if (!pte_dirty(pte)) 165 __sync_icache_dcache(pte, addr);
163 pte = pte_wrprotect(pte); 166 if (!pte_dirty(pte))
167 pte = pte_wrprotect(pte);
168 }
169
164 set_pte(ptep, pte); 170 set_pte(ptep, pte);
165} 171}
166 172
@@ -170,9 +176,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
170#define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE) 176#define pte_huge(pte) ((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE)
171#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE)) 177#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE))
172 178
173#define __pgprot_modify(prot,mask,bits) \
174 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
175
176#define __HAVE_ARCH_PTE_SPECIAL 179#define __HAVE_ARCH_PTE_SPECIAL
177 180
178/* 181/*
@@ -264,7 +267,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
264 267
265static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 268static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
266{ 269{
267 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; 270 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
271 PTE_PROT_NONE | PTE_VALID;
268 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 272 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
269 return pte; 273 return pte;
270} 274}