aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-11-21 06:48:16 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-12-22 06:05:34 -0500
commitaf3813d6a5bf8d0f71b23d3ce458fa5f9916c6b7 (patch)
tree701ed00ea1e781ae758318c81b051f23ed9956fa
parent614dd0585f376a25c638abbed9c5fbd21d7baece (diff)
ARM: pgtable: use conventional page table code for identity mappings
Remove some knowledge of our 2-level page table layout from the identity mapping code - we assume that a step size of PGDIR_SIZE will allow us to step over all entries. While this is true today, it won't be true in the near future. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mm/idmap.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 034124d1272d..57299446f787 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -4,33 +4,49 @@
4#include <asm/pgalloc.h> 4#include <asm/pgalloc.h>
5#include <asm/pgtable.h> 5#include <asm/pgtable.h>
6 6
7static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
8 unsigned long prot)
9{
10 pmd_t *pmd = pmd_offset(pgd, addr);
11
12 addr = (addr & PMD_MASK) | prot;
13 pmd[0] = __pmd(addr);
14 addr += SECTION_SIZE;
15 pmd[1] = __pmd(addr);
16 flush_pmd_entry(pmd);
17}
18
7void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) 19void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
8{ 20{
9 unsigned long prot; 21 unsigned long prot, next;
10 22
11 prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE; 23 prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
12 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) 24 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
13 prot |= PMD_BIT4; 25 prot |= PMD_BIT4;
14 26
15 for (addr &= PGDIR_MASK; addr < end;) { 27 pgd += pgd_index(addr);
16 pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr); 28 do {
17 pmd[0] = __pmd(addr | prot); 29 next = pgd_addr_end(addr, end);
18 addr += SECTION_SIZE; 30 idmap_add_pmd(pgd, addr, next, prot);
19 pmd[1] = __pmd(addr | prot); 31 } while (pgd++, addr = next, addr != end);
20 addr += SECTION_SIZE;
21 flush_pmd_entry(pmd);
22 }
23} 32}
24 33
25#ifdef CONFIG_SMP 34#ifdef CONFIG_SMP
35static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end)
36{
37 pmd_t *pmd = pmd_offset(pgd, addr);
38 pmd_clear(pmd);
39}
40
26void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) 41void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
27{ 42{
28 for (addr &= PGDIR_MASK; addr < end; addr += PGDIR_SIZE) { 43 unsigned long next;
29 pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr); 44
30 pmd[0] = __pmd(0); 45 pgd += pgd_index(addr);
31 pmd[1] = __pmd(0); 46 do {
32 clean_pmd_entry(pmd); 47 next = pgd_addr_end(addr, end);
33 } 48 idmap_del_pmd(pgd, addr, next);
49 } while (pgd++, addr = next, addr != end);
34} 50}
35#endif 51#endif
36 52