aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-08-10 11:18:35 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-08-10 11:18:35 -0400
commit6626a7076d39f0a18156cdd97d4e2cbef91ad701 (patch)
tree13909ea6ae009b9b418cf3302baebe1baaa0dbd4
parent1b9749e7f15bf2db19f5d201f88401c7517910b7 (diff)
[ARM] Control v6 'global' bit via Linux PTE entries
Unfortunately, we can't use the "user" bit in the page tables to control whether a page table entry is "global" or "asid" specific, since the vector page is mapped as "user" accessible but is not process specific. Therefore, give direct control of the ARMv6 "nG" (not global) bit to the mm layers. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mm/mm-armv.c17
-rw-r--r--arch/arm/mm/proc-v6.S4
-rw-r--r--include/asm-arm/pgtable.h2
3 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index e33fe4229d05..3c655c54e231 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -383,6 +383,7 @@ static void __init build_mem_type_table(void)
383{ 383{
384 struct cachepolicy *cp; 384 struct cachepolicy *cp;
385 unsigned int cr = get_cr(); 385 unsigned int cr = get_cr();
386 unsigned int user_pgprot;
386 int cpu_arch = cpu_architecture(); 387 int cpu_arch = cpu_architecture();
387 int i; 388 int i;
388 389
@@ -408,6 +409,9 @@ static void __init build_mem_type_table(void)
408 } 409 }
409 } 410 }
410 411
412 cp = &cache_policies[cachepolicy];
413 user_pgprot = cp->pte;
414
411 /* 415 /*
412 * ARMv6 and above have extended page tables. 416 * ARMv6 and above have extended page tables.
413 */ 417 */
@@ -426,11 +430,18 @@ static void __init build_mem_type_table(void)
426 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 430 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
427 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 431 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
428 432
433 /*
434 * Mark the device area as "shared device"
435 */
429 mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; 436 mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
430 mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; 437 mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
431 }
432 438
433 cp = &cache_policies[cachepolicy]; 439 /*
440 * User pages need to be mapped with the ASID
441 * (iow, non-global)
442 */
443 user_pgprot |= L_PTE_ASID;
444 }
434 445
435 if (cpu_arch >= CPU_ARCH_ARMv5) { 446 if (cpu_arch >= CPU_ARCH_ARMv5) {
436 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 447 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
@@ -448,7 +459,7 @@ static void __init build_mem_type_table(void)
448 459
449 for (i = 0; i < 16; i++) { 460 for (i = 0; i < 16; i++) {
450 unsigned long v = pgprot_val(protection_map[i]); 461 unsigned long v = pgprot_val(protection_map[i]);
451 v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte; 462 v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
452 protection_map[i] = __pgprot(v); 463 protection_map[i] = __pgprot(v);
453 } 464 }
454 465
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 75e65522c8d2..3429ddcf65d1 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -133,7 +133,7 @@ ENTRY(cpu_v6_switch_mm)
133ENTRY(cpu_v6_set_pte) 133ENTRY(cpu_v6_set_pte)
134 str r1, [r0], #-2048 @ linux version 134 str r1, [r0], #-2048 @ linux version
135 135
136 bic r2, r1, #0x00000ff0 136 bic r2, r1, #0x000007f0
137 bic r2, r2, #0x00000003 137 bic r2, r2, #0x00000003
138 orr r2, r2, #PTE_EXT_AP0 | 2 138 orr r2, r2, #PTE_EXT_AP0 | 2
139 139
@@ -142,7 +142,7 @@ ENTRY(cpu_v6_set_pte)
142 orreq r2, r2, #PTE_EXT_APX 142 orreq r2, r2, #PTE_EXT_APX
143 143
144 tst r1, #L_PTE_USER 144 tst r1, #L_PTE_USER
145 orrne r2, r2, #PTE_EXT_AP1 | PTE_EXT_NG 145 orrne r2, r2, #PTE_EXT_AP1
146 tstne r2, #PTE_EXT_APX 146 tstne r2, #PTE_EXT_APX
147 bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0 147 bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
148 148
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 8bd4c0faf230..478c49b56e18 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -230,6 +230,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
230#define L_PTE_WRITE (1 << 5) 230#define L_PTE_WRITE (1 << 5)
231#define L_PTE_EXEC (1 << 6) 231#define L_PTE_EXEC (1 << 6)
232#define L_PTE_DIRTY (1 << 7) 232#define L_PTE_DIRTY (1 << 7)
233#define L_PTE_SHARED (1 << 10) /* shared between CPUs (v6) */
234#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */
233 235
234#ifndef __ASSEMBLY__ 236#ifndef __ASSEMBLY__
235 237