aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-11-15 19:23:31 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-12-22 06:05:35 -0500
commit9522d7e4cb5e0858122fc55d33a2c07728f0b10d (patch)
tree49438ddcd5217da82cf9ebe79dda8577bc346456
parente926f4495e202500a6265987277fab217e235f08 (diff)
ARM: pgtable: invert L_PTE_EXEC to L_PTE_XN
The hardware page tables use an XN bit 'execute never'. Historically, we've had a Linux 'execute allow' bit, in the positive sense. Get rid of this artifact as future hardware will continue to have the XN sense. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/include/asm/pgtable.h44
-rw-r--r--arch/arm/mm/mmu.c15
-rw-r--r--arch/arm/mm/proc-macros.S6
-rw-r--r--arch/arm/mm/proc-v7.S4
4 files changed, 34 insertions, 35 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 4701a6b758b7..f9b3f4bd7410 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -171,7 +171,7 @@ extern void __pgd_error(const char *file, int line, pgd_t);
171#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6) 171#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
172#define L_PTE_WRITE (_AT(pteval_t, 1) << 7) 172#define L_PTE_WRITE (_AT(pteval_t, 1) << 7)
173#define L_PTE_USER (_AT(pteval_t, 1) << 8) 173#define L_PTE_USER (_AT(pteval_t, 1) << 8)
174#define L_PTE_EXEC (_AT(pteval_t, 1) << 9) 174#define L_PTE_XN (_AT(pteval_t, 1) << 9)
175#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */ 175#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
176 176
177/* 177/*
@@ -205,23 +205,23 @@ extern pgprot_t pgprot_kernel;
205 205
206#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) 206#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
207 207
208#define PAGE_NONE pgprot_user 208#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN)
209#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE) 209#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
210#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 210#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
211#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER) 211#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
212#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 212#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
213#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER) 213#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
214#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 214#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
215#define PAGE_KERNEL pgprot_kernel 215#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
216#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC) 216#define PAGE_KERNEL_EXEC pgprot_kernel
217 217
218#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT) 218#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_XN)
219#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE) 219#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
220#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 220#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
221#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 221#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
222#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 222#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
223#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 223#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
224#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 224#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
225 225
226#define __pgprot_modify(prot,mask,bits) \ 226#define __pgprot_modify(prot,mask,bits) \
227 __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) 227 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
@@ -234,14 +234,14 @@ extern pgprot_t pgprot_kernel;
234 234
235#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE 235#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
236#define pgprot_dmacoherent(prot) \ 236#define pgprot_dmacoherent(prot) \
237 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) 237 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
238#define __HAVE_PHYS_MEM_ACCESS_PROT 238#define __HAVE_PHYS_MEM_ACCESS_PROT
239struct file; 239struct file;
240extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 240extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
241 unsigned long size, pgprot_t vma_prot); 241 unsigned long size, pgprot_t vma_prot);
242#else 242#else
243#define pgprot_dmacoherent(prot) \ 243#define pgprot_dmacoherent(prot) \
244 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) 244 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
245#endif 245#endif
246 246
247#endif /* __ASSEMBLY__ */ 247#endif /* __ASSEMBLY__ */
@@ -383,7 +383,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
383#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) 383#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
384#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) 384#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
385#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 385#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
386#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) 386#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
387#define pte_special(pte) (0) 387#define pte_special(pte) (0)
388 388
389#define pte_present_user(pte) \ 389#define pte_present_user(pte) \
@@ -404,7 +404,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
404 404
405static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 405static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
406{ 406{
407 const pteval_t mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER; 407 const pteval_t mask = L_PTE_XN | L_PTE_WRITE | L_PTE_USER;
408 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 408 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
409 return pte; 409 return pte;
410} 410}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index bd1a11e62f4e..bd5a94b2d610 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -190,7 +190,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
190} 190}
191#endif 191#endif
192 192
193#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE 193#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE|L_PTE_XN
194#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE 194#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
195 195
196static struct mem_type mem_types[] = { 196static struct mem_type mem_types[] = {
@@ -234,20 +234,19 @@ static struct mem_type mem_types[] = {
234 .domain = DOMAIN_KERNEL, 234 .domain = DOMAIN_KERNEL,
235 }, 235 },
236 [MT_LOW_VECTORS] = { 236 [MT_LOW_VECTORS] = {
237 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 237 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
238 L_PTE_EXEC,
239 .prot_l1 = PMD_TYPE_TABLE, 238 .prot_l1 = PMD_TYPE_TABLE,
240 .domain = DOMAIN_USER, 239 .domain = DOMAIN_USER,
241 }, 240 },
242 [MT_HIGH_VECTORS] = { 241 [MT_HIGH_VECTORS] = {
243 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 242 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
244 L_PTE_USER | L_PTE_EXEC, 243 L_PTE_USER,
245 .prot_l1 = PMD_TYPE_TABLE, 244 .prot_l1 = PMD_TYPE_TABLE,
246 .domain = DOMAIN_USER, 245 .domain = DOMAIN_USER,
247 }, 246 },
248 [MT_MEMORY] = { 247 [MT_MEMORY] = {
249 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 248 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
250 L_PTE_WRITE | L_PTE_EXEC, 249 L_PTE_WRITE,
251 .prot_l1 = PMD_TYPE_TABLE, 250 .prot_l1 = PMD_TYPE_TABLE,
252 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, 251 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
253 .domain = DOMAIN_KERNEL, 252 .domain = DOMAIN_KERNEL,
@@ -258,21 +257,21 @@ static struct mem_type mem_types[] = {
258 }, 257 },
259 [MT_MEMORY_NONCACHED] = { 258 [MT_MEMORY_NONCACHED] = {
260 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 259 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
261 L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, 260 L_PTE_WRITE| L_PTE_MT_BUFFERABLE,
262 .prot_l1 = PMD_TYPE_TABLE, 261 .prot_l1 = PMD_TYPE_TABLE,
263 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, 262 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
264 .domain = DOMAIN_KERNEL, 263 .domain = DOMAIN_KERNEL,
265 }, 264 },
266 [MT_MEMORY_DTCM] = { 265 [MT_MEMORY_DTCM] = {
267 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 266 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
268 L_PTE_WRITE, 267 L_PTE_WRITE | L_PTE_XN,
269 .prot_l1 = PMD_TYPE_TABLE, 268 .prot_l1 = PMD_TYPE_TABLE,
270 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, 269 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
271 .domain = DOMAIN_KERNEL, 270 .domain = DOMAIN_KERNEL,
272 }, 271 },
273 [MT_MEMORY_ITCM] = { 272 [MT_MEMORY_ITCM] = {
274 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 273 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
275 L_PTE_WRITE | L_PTE_EXEC, 274 L_PTE_WRITE,
276 .prot_l1 = PMD_TYPE_TABLE, 275 .prot_l1 = PMD_TYPE_TABLE,
277 .domain = DOMAIN_KERNEL, 276 .domain = DOMAIN_KERNEL,
278 }, 277 },
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index cbedf9c46b9d..4a7a9e142e85 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -81,7 +81,7 @@
81#if L_PTE_SHARED != PTE_EXT_SHARED 81#if L_PTE_SHARED != PTE_EXT_SHARED
82#error PTE shared bit mismatch 82#error PTE shared bit mismatch
83#endif 83#endif
84#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ 84#if (L_PTE_XN+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
85 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED 85 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
86#error Invalid Linux PTE bit settings 86#error Invalid Linux PTE bit settings
87#endif 87#endif
@@ -141,8 +141,8 @@
141 tstne r3, #PTE_EXT_APX 141 tstne r3, #PTE_EXT_APX
142 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 142 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
143 143
144 tst r1, #L_PTE_EXEC 144 tst r1, #L_PTE_XN
145 orreq r3, r3, #PTE_EXT_XN 145 orrne r3, r3, #PTE_EXT_XN
146 146
147 orr r3, r3, r2 147 orr r3, r3, r2
148 148
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 89c31a6dae5c..4f5a594aa5fd 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -149,8 +149,8 @@ ENTRY(cpu_v7_set_pte_ext)
149 tstne r3, #PTE_EXT_APX 149 tstne r3, #PTE_EXT_APX
150 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 150 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
151 151
152 tst r1, #L_PTE_EXEC 152 tst r1, #L_PTE_XN
153 orreq r3, r3, #PTE_EXT_XN 153 orrne r3, r3, #PTE_EXT_XN
154 154
155 tst r1, #L_PTE_YOUNG 155 tst r1, #L_PTE_YOUNG
156 tstne r1, #L_PTE_PRESENT 156 tstne r1, #L_PTE_PRESENT