mirror of https://gitee.com/openkylin/linux.git
[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:
parent
1b9749e7f1
commit
6626a7076d
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
Loading…
Reference in New Issue