Skip to content

Commit

Permalink
[ARM] Control v6 'global' bit via Linux PTE entries
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King authored and Russell King committed Aug 10, 2005
1 parent 1b9749e commit 6626a70
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
17 changes: 14 additions & 3 deletions arch/arm/mm/mm-armv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.
*/
Expand All @@ -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;
Expand All @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions arch/arm/mm/proc-v6.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
2 changes: 2 additions & 0 deletions include/asm-arm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
#define L_PTE_WRITE (1 << 5)
#define L_PTE_EXEC (1 << 6)
#define L_PTE_DIRTY (1 << 7)
#define L_PTE_SHARED (1 << 10) /* shared between CPUs (v6) */
#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */

#ifndef __ASSEMBLY__

Expand Down

0 comments on commit 6626a70

Please sign in to comment.