diff options
Diffstat (limited to 'arch/arm/mm/idmap.c')
-rw-r--r-- | arch/arm/mm/idmap.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c new file mode 100644 index 000000000000..57299446f787 --- /dev/null +++ b/arch/arm/mm/idmap.c | |||
@@ -0,0 +1,67 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | |||
3 | #include <asm/cputype.h> | ||
4 | #include <asm/pgalloc.h> | ||
5 | #include <asm/pgtable.h> | ||
6 | |||
7 | static 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 | |||
19 | void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) | ||
20 | { | ||
21 | unsigned long prot, next; | ||
22 | |||
23 | prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE; | ||
24 | if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) | ||
25 | prot |= PMD_BIT4; | ||
26 | |||
27 | pgd += pgd_index(addr); | ||
28 | do { | ||
29 | next = pgd_addr_end(addr, end); | ||
30 | idmap_add_pmd(pgd, addr, next, prot); | ||
31 | } while (pgd++, addr = next, addr != end); | ||
32 | } | ||
33 | |||
34 | #ifdef CONFIG_SMP | ||
35 | static 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 | |||
41 | void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) | ||
42 | { | ||
43 | unsigned long next; | ||
44 | |||
45 | pgd += pgd_index(addr); | ||
46 | do { | ||
47 | next = pgd_addr_end(addr, end); | ||
48 | idmap_del_pmd(pgd, addr, next); | ||
49 | } while (pgd++, addr = next, addr != end); | ||
50 | } | ||
51 | #endif | ||
52 | |||
53 | /* | ||
54 | * In order to soft-boot, we need to insert a 1:1 mapping in place of | ||
55 | * the user-mode pages. This will then ensure that we have predictable | ||
56 | * results when turning the mmu off | ||
57 | */ | ||
58 | void setup_mm_for_reboot(char mode) | ||
59 | { | ||
60 | /* | ||
61 | * We need to access to user-mode page tables here. For kernel threads | ||
62 | * we don't have any user-mode mappings so we use the context that we | ||
63 | * "borrowed". | ||
64 | */ | ||
65 | identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE); | ||
66 | local_flush_tlb_all(); | ||
67 | } | ||