diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-11-21 06:41:57 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-22 06:05:33 -0500 |
commit | 614dd0585f376a25c638abbed9c5fbd21d7baece (patch) | |
tree | 9bd2c8bb3523632901e3ddc3f9b1eba24e7671ab /arch/arm/mm/idmap.c | |
parent | 26bbf0b57a0848932f725076bcb1245ca696e8d3 (diff) |
ARM: pgtable: collect up identity mapping functions
We have two places where we create identity mappings - one when we bring
secondary CPUs online, and one where we setup some mappings for soft-
reboot. Combine these two into a single implementation. Also collect
the identity mapping deletion function.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/idmap.c')
-rw-r--r-- | arch/arm/mm/idmap.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c new file mode 100644 index 000000000000..034124d1272d --- /dev/null +++ b/arch/arm/mm/idmap.c | |||
@@ -0,0 +1,51 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | |||
3 | #include <asm/cputype.h> | ||
4 | #include <asm/pgalloc.h> | ||
5 | #include <asm/pgtable.h> | ||
6 | |||
7 | void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) | ||
8 | { | ||
9 | unsigned long prot; | ||
10 | |||
11 | prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE; | ||
12 | if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) | ||
13 | prot |= PMD_BIT4; | ||
14 | |||
15 | for (addr &= PGDIR_MASK; addr < end;) { | ||
16 | pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr); | ||
17 | pmd[0] = __pmd(addr | prot); | ||
18 | addr += SECTION_SIZE; | ||
19 | pmd[1] = __pmd(addr | prot); | ||
20 | addr += SECTION_SIZE; | ||
21 | flush_pmd_entry(pmd); | ||
22 | } | ||
23 | } | ||
24 | |||
25 | #ifdef CONFIG_SMP | ||
26 | void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) | ||
27 | { | ||
28 | for (addr &= PGDIR_MASK; addr < end; addr += PGDIR_SIZE) { | ||
29 | pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr); | ||
30 | pmd[0] = __pmd(0); | ||
31 | pmd[1] = __pmd(0); | ||
32 | clean_pmd_entry(pmd); | ||
33 | } | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | /* | ||
38 | * In order to soft-boot, we need to insert a 1:1 mapping in place of | ||
39 | * the user-mode pages. This will then ensure that we have predictable | ||
40 | * results when turning the mmu off | ||
41 | */ | ||
42 | void setup_mm_for_reboot(char mode) | ||
43 | { | ||
44 | /* | ||
45 | * We need to access to user-mode page tables here. For kernel threads | ||
46 | * we don't have any user-mode mappings so we use the context that we | ||
47 | * "borrowed". | ||
48 | */ | ||
49 | identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE); | ||
50 | local_flush_tlb_all(); | ||
51 | } | ||