diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-06 21:27:54 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-06 21:27:54 +0100 |
commit | 3ee0fc5ca129cbae81c073756febcb1c552af446 (patch) | |
tree | 08f061c1ec9e948df760a0746441bec9f290d774 /arch/arm/mm/idmap.c | |
parent | ARM: 7194/1: OMAP: Fix build after a merge between v3.2-rc4 and ARM restart c... (diff) | |
parent | ARM: SMP: use idmap_pgd for mapping MMU enable during secondary booting (diff) | |
download | linux-3ee0fc5ca129cbae81c073756febcb1c552af446.tar.xz linux-3ee0fc5ca129cbae81c073756febcb1c552af446.zip |
Merge branch 'kexec/idmap' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable
Diffstat (limited to 'arch/arm/mm/idmap.c')
-rw-r--r-- | arch/arm/mm/idmap.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 296ad2eaddb0..660f1bc68f99 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,8 +1,12 @@ #include <linux/kernel.h> #include <asm/cputype.h> +#include <asm/idmap.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> +#include <asm/sections.h> + +pgd_t *idmap_pgd; static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, unsigned long prot) @@ -28,7 +32,7 @@ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, } while (pud++, addr = next, addr != end); } -void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) { unsigned long prot, next; @@ -43,48 +47,41 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) } while (pgd++, addr = next, addr != end); } -#ifdef CONFIG_SMP -static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end) -{ - pmd_t *pmd = pmd_offset(pud, addr); - pmd_clear(pmd); -} +extern char __idmap_text_start[], __idmap_text_end[]; -static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end) +static int __init init_static_idmap(void) { - pud_t *pud = pud_offset(pgd, addr); - unsigned long next; + phys_addr_t idmap_start, idmap_end; - do { - next = pud_addr_end(addr, end); - idmap_del_pmd(pud, addr, next); - } while (pud++, addr = next, addr != end); -} + idmap_pgd = pgd_alloc(&init_mm); + if (!idmap_pgd) + return -ENOMEM; -void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) -{ - unsigned long next; + /* Add an identity mapping for the physical address of the section. */ + idmap_start = virt_to_phys((void *)__idmap_text_start); + idmap_end = virt_to_phys((void *)__idmap_text_end); - pgd += pgd_index(addr); - do { - next = pgd_addr_end(addr, end); - idmap_del_pud(pgd, addr, next); - } while (pgd++, addr = next, addr != end); + pr_info("Setting up static identity map for 0x%llx - 0x%llx\n", + (long long)idmap_start, (long long)idmap_end); + identity_mapping_add(idmap_pgd, idmap_start, idmap_end); + + return 0; } -#endif +early_initcall(init_static_idmap); /* - * In order to soft-boot, we need to insert a 1:1 mapping in place of - * the user-mode pages. This will then ensure that we have predictable - * results when turning the mmu off + * In order to soft-boot, we need to switch to a 1:1 mapping for the + * cpu_reset functions. This will then ensure that we have predictable + * results when turning off the mmu. */ void setup_mm_for_reboot(void) { - /* - * We need to access to user-mode page tables here. For kernel threads - * we don't have any user-mode mappings so we use the context that we - * "borrowed". - */ - identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE); + /* Clean and invalidate L1. */ + flush_cache_all(); + + /* Switch to the identity mapping. */ + cpu_switch_mm(idmap_pgd, &init_mm); + + /* Flush the TLB. */ local_flush_tlb_all(); } |