[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>
This commit is contained in:
Russell King 2005-08-10 16:18:35 +01:00 коммит произвёл Russell King
Родитель 1b9749e7f1
Коммит 6626a7076d
3 изменённых файлов: 18 добавлений и 5 удалений

Просмотреть файл

@ -383,6 +383,7 @@ static void __init build_mem_type_table(void)
{ {
struct cachepolicy *cp; struct cachepolicy *cp;
unsigned int cr = get_cr(); unsigned int cr = get_cr();
unsigned int user_pgprot;
int cpu_arch = cpu_architecture(); int cpu_arch = cpu_architecture();
int i; 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. * 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_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_CACHECLEAN].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_pte |= L_PTE_BUFFERABLE;
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; 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) { if (cpu_arch >= CPU_ARCH_ARMv5) {
mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 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++) { for (i = 0; i < 16; i++) {
unsigned long v = pgprot_val(protection_map[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); protection_map[i] = __pgprot(v);
} }

Просмотреть файл

@ -133,7 +133,7 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte) ENTRY(cpu_v6_set_pte)
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
bic r2, r1, #0x00000ff0 bic r2, r1, #0x000007f0
bic r2, r2, #0x00000003 bic r2, r2, #0x00000003
orr r2, r2, #PTE_EXT_AP0 | 2 orr r2, r2, #PTE_EXT_AP0 | 2
@ -142,7 +142,7 @@ ENTRY(cpu_v6_set_pte)
orreq r2, r2, #PTE_EXT_APX orreq r2, r2, #PTE_EXT_APX
tst r1, #L_PTE_USER 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 tstne r2, #PTE_EXT_APX
bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0 bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0

Просмотреть файл

@ -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_WRITE (1 << 5)
#define L_PTE_EXEC (1 << 6) #define L_PTE_EXEC (1 << 6)
#define L_PTE_DIRTY (1 << 7) #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__ #ifndef __ASSEMBLY__