summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-08-10 16:18:35 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-08-10 16:18:35 +0100
commit6626a7076d39f0a18156cdd97d4e2cbef91ad701 (patch)
tree13909ea6ae009b9b418cf3302baebe1baaa0dbd4 /arch
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mm/mm-armv.c17
-rw-r--r--arch/arm/mm/proc-v6.S4
2 files changed, 16 insertions, 5 deletions
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index e33fe4229d0..3c655c54e23 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)
{
struct cachepolicy *cp;
unsigned int cr = get_cr();
+ unsigned int user_pgprot;
int cpu_arch = cpu_architecture();
int i;
@@ -408,6 +409,9 @@ static void __init build_mem_type_table(void)
}
}
+ cp = &cache_policies[cachepolicy];
+ user_pgprot = cp->pte;
+
/*
* ARMv6 and above have extended page tables.
*/
@@ -426,11 +430,18 @@ static void __init build_mem_type_table(void)
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ /*
+ * Mark the device area as "shared device"
+ */
mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
- }
- cp = &cache_policies[cachepolicy];
+ /*
+ * User pages need to be mapped with the ASID
+ * (iow, non-global)
+ */
+ user_pgprot |= L_PTE_ASID;
+ }
if (cpu_arch >= CPU_ARCH_ARMv5) {
mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
@@ -448,7 +459,7 @@ static void __init build_mem_type_table(void)
for (i = 0; i < 16; i++) {
unsigned long v = pgprot_val(protection_map[i]);
- v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte;
+ v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
protection_map[i] = __pgprot(v);
}
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 75e65522c8d..3429ddcf65d 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -133,7 +133,7 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte)
str r1, [r0], #-2048 @ linux version
- bic r2, r1, #0x00000ff0
+ bic r2, r1, #0x000007f0
bic r2, r2, #0x00000003
orr r2, r2, #PTE_EXT_AP0 | 2
@@ -142,7 +142,7 @@ ENTRY(cpu_v6_set_pte)
orreq r2, r2, #PTE_EXT_APX
tst r1, #L_PTE_USER
- orrne r2, r2, #PTE_EXT_AP1 | PTE_EXT_NG
+ orrne r2, r2, #PTE_EXT_AP1
tstne r2, #PTE_EXT_APX
bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0