diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-08-10 11:18:35 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-08-10 11:18:35 -0400 |
commit | 6626a7076d39f0a18156cdd97d4e2cbef91ad701 (patch) | |
tree | 13909ea6ae009b9b418cf3302baebe1baaa0dbd4 /arch/arm/mm/mm-armv.c | |
parent | 1b9749e7f15bf2db19f5d201f88401c7517910b7 (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/arm/mm/mm-armv.c')
-rw-r--r-- | arch/arm/mm/mm-armv.c | 17 |
1 files changed, 14 insertions, 3 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 | ||