diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:29:37 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:29:37 -0800 |
commit | 6db167dfc013b0e114c81077ac091ba26a69f4ed (patch) | |
tree | 1978b8a2774e0fdb3690065625b0b5eb84475552 /arch/arm/mm/idmap.c | |
parent | 32f9aab8ebd886211a7b3e552753af014c3e5225 (diff) | |
parent | 9cb543124a2d31af42ce61a4c30765ecc8e5f1fa (diff) | |
download | lwn-6db167dfc013b0e114c81077ac091ba26a69f4ed.tar.gz lwn-6db167dfc013b0e114c81077ac091ba26a69f4ed.zip |
Merge branch 'for-linus-2' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM updates (part two) from Russell King:
- breakpoint and perf updates from Will Deacon.
- hypervisor boot mode updates from Will.
- support for Power State Coordination Interface via the Hypervisor
- core ARM support for KVM
* 'for-linus-2' of git://git.linaro.org/people/rmk/linux-arm: (32 commits)
KVM: ARM: Add maintainer entry for KVM/ARM
KVM: ARM: Power State Coordination Interface implementation
KVM: ARM: Handle I/O aborts
KVM: ARM: Handle guest faults in KVM
KVM: ARM: VFP userspace interface
KVM: ARM: Demux CCSIDR in the userspace API
KVM: ARM: User space API for getting/setting co-proc registers
KVM: ARM: Emulation framework and CP15 emulation
KVM: ARM: World-switch implementation
KVM: ARM: Inject IRQs and FIQs from userspace
KVM: ARM: Memory virtualization setup
KVM: ARM: Hypervisor initialization
KVM: ARM: Initial skeleton to compile KVM support
ARM: Section based HYP idmap
ARM: Add page table and page defines needed by KVM
ARM: perf: simplify __hw_perf_event_init err handling
ARM: perf: remove unnecessary checks for idx < 0
ARM: perf: handle armpmu_register failing
ARM: perf: don't pretend to support counting of L1I writes
ARM: perf: remove redundant NULL check on cpu_pmu
...
Diffstat (limited to 'arch/arm/mm/idmap.c')
-rw-r--r-- | arch/arm/mm/idmap.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 99db769307ec..2dffc010cc41 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,4 +1,6 @@ +#include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <asm/cputype.h> #include <asm/idmap.h> @@ -6,6 +8,7 @@ #include <asm/pgtable.h> #include <asm/sections.h> #include <asm/system_info.h> +#include <asm/virt.h> pgd_t *idmap_pgd; @@ -59,11 +62,17 @@ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end, } while (pud++, addr = next, addr != end); } -static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) +static void identity_mapping_add(pgd_t *pgd, const char *text_start, + const char *text_end, unsigned long prot) { - unsigned long prot, next; + unsigned long addr, end; + unsigned long next; + + addr = virt_to_phys(text_start); + end = virt_to_phys(text_end); + + prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; - prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) prot |= PMD_BIT4; @@ -74,28 +83,52 @@ static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long e } while (pgd++, addr = next, addr != end); } +#if defined(CONFIG_ARM_VIRT_EXT) && defined(CONFIG_ARM_LPAE) +pgd_t *hyp_pgd; + +extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; + +static int __init init_static_idmap_hyp(void) +{ + hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); + if (!hyp_pgd) + return -ENOMEM; + + pr_info("Setting up static HYP identity map for 0x%p - 0x%p\n", + __hyp_idmap_text_start, __hyp_idmap_text_end); + identity_mapping_add(hyp_pgd, __hyp_idmap_text_start, + __hyp_idmap_text_end, PMD_SECT_AP1); + + return 0; +} +#else +static int __init init_static_idmap_hyp(void) +{ + return 0; +} +#endif + extern char __idmap_text_start[], __idmap_text_end[]; static int __init init_static_idmap(void) { - phys_addr_t idmap_start, idmap_end; + int ret; idmap_pgd = pgd_alloc(&init_mm); if (!idmap_pgd) return -ENOMEM; - /* 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); + pr_info("Setting up static identity map for 0x%p - 0x%p\n", + __idmap_text_start, __idmap_text_end); + identity_mapping_add(idmap_pgd, __idmap_text_start, + __idmap_text_end, 0); - 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); + ret = init_static_idmap_hyp(); /* Flush L1 for the hardware to see this page table content */ flush_cache_louis(); - return 0; + return ret; } early_initcall(init_static_idmap); |