aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2013-04-12 14:12:03 -0400
committerChristoffer Dall <cdall@cs.columbia.edu>2013-04-29 01:23:08 -0400
commit2fb410596ca917fe6419be61ee5bc1782b17d947 (patch)
tree9b17527736eb0d7936c9d720721d946768ab5361 /arch
parent3562c76dcb9ce84853c835eec12a911bf3a8e2da (diff)
ARM: KVM: move to a KVM provided HYP idmap
After the HYP page table rework, it is pretty easy to let the KVM code provide its own idmap, rather than expecting the kernel to provide it. It takes actually less code to do so. Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/idmap.h1
-rw-r--r--arch/arm/include/asm/kvm_mmu.h1
-rw-r--r--arch/arm/kvm/mmu.c24
-rw-r--r--arch/arm/mm/idmap.c32
4 files changed, 24 insertions, 34 deletions
diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h
index 1a66f907e5cc..bf863edb517d 100644
--- a/arch/arm/include/asm/idmap.h
+++ b/arch/arm/include/asm/idmap.h
@@ -8,7 +8,6 @@
8#define __idmap __section(.idmap.text) noinline notrace 8#define __idmap __section(.idmap.text) noinline notrace
9 9
10extern pgd_t *idmap_pgd; 10extern pgd_t *idmap_pgd;
11extern pgd_t *hyp_pgd;
12 11
13void setup_mm_for_reboot(void); 12void setup_mm_for_reboot(void);
14 13
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 970f3b5fa109..3c71a1d4b7a3 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -21,7 +21,6 @@
21 21
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <asm/pgalloc.h> 23#include <asm/pgalloc.h>
24#include <asm/idmap.h>
25 24
26/* 25/*
27 * We directly use the kernel VA for the HYP, as we can directly share 26 * We directly use the kernel VA for the HYP, as we can directly share
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 96d61daa23ba..bfc59279de1b 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -32,6 +32,7 @@
32 32
33extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; 33extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
34 34
35static pgd_t *hyp_pgd;
35static DEFINE_MUTEX(kvm_hyp_pgd_mutex); 36static DEFINE_MUTEX(kvm_hyp_pgd_mutex);
36 37
37static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) 38static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
@@ -715,12 +716,33 @@ phys_addr_t kvm_mmu_get_httbr(void)
715 716
716int kvm_mmu_init(void) 717int kvm_mmu_init(void)
717{ 718{
719 unsigned long hyp_idmap_start = virt_to_phys(__hyp_idmap_text_start);
720 unsigned long hyp_idmap_end = virt_to_phys(__hyp_idmap_text_end);
721 int err;
722
723 hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
718 if (!hyp_pgd) { 724 if (!hyp_pgd) {
719 kvm_err("Hyp mode PGD not allocated\n"); 725 kvm_err("Hyp mode PGD not allocated\n");
720 return -ENOMEM; 726 err = -ENOMEM;
727 goto out;
728 }
729
730 /* Create the idmap in the boot page tables */
731 err = __create_hyp_mappings(boot_hyp_pgd,
732 hyp_idmap_start, hyp_idmap_end,
733 __phys_to_pfn(hyp_idmap_start),
734 PAGE_HYP);
735
736 if (err) {
737 kvm_err("Failed to idmap %lx-%lx\n",
738 hyp_idmap_start, hyp_idmap_end);
739 goto out;
721 } 740 }
722 741
723 return 0; 742 return 0;
743out:
744 kfree(hyp_pgd);
745 return err;
724} 746}
725 747
726/** 748/**
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 5ee505c937d1..83cb3ac27095 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -8,7 +8,6 @@
8#include <asm/pgtable.h> 8#include <asm/pgtable.h>
9#include <asm/sections.h> 9#include <asm/sections.h>
10#include <asm/system_info.h> 10#include <asm/system_info.h>
11#include <asm/virt.h>
12 11
13pgd_t *idmap_pgd; 12pgd_t *idmap_pgd;
14 13
@@ -83,37 +82,10 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
83 } while (pgd++, addr = next, addr != end); 82 } while (pgd++, addr = next, addr != end);
84} 83}
85 84
86#if defined(CONFIG_ARM_VIRT_EXT) && defined(CONFIG_ARM_LPAE)
87pgd_t *hyp_pgd;
88
89extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
90
91static int __init init_static_idmap_hyp(void)
92{
93 hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
94 if (!hyp_pgd)
95 return -ENOMEM;
96
97 pr_info("Setting up static HYP identity map for 0x%p - 0x%p\n",
98 __hyp_idmap_text_start, __hyp_idmap_text_end);
99 identity_mapping_add(hyp_pgd, __hyp_idmap_text_start,
100 __hyp_idmap_text_end, PMD_SECT_AP1);
101
102 return 0;
103}
104#else
105static int __init init_static_idmap_hyp(void)
106{
107 return 0;
108}
109#endif
110
111extern char __idmap_text_start[], __idmap_text_end[]; 85extern char __idmap_text_start[], __idmap_text_end[];
112 86
113static int __init init_static_idmap(void) 87static int __init init_static_idmap(void)
114{ 88{
115 int ret;
116
117 idmap_pgd = pgd_alloc(&init_mm); 89 idmap_pgd = pgd_alloc(&init_mm);
118 if (!idmap_pgd) 90 if (!idmap_pgd)
119 return -ENOMEM; 91 return -ENOMEM;
@@ -123,12 +95,10 @@ static int __init init_static_idmap(void)
123 identity_mapping_add(idmap_pgd, __idmap_text_start, 95 identity_mapping_add(idmap_pgd, __idmap_text_start,
124 __idmap_text_end, 0); 96 __idmap_text_end, 0);
125 97
126 ret = init_static_idmap_hyp();
127
128 /* Flush L1 for the hardware to see this page table content */ 98 /* Flush L1 for the hardware to see this page table content */
129 flush_cache_louis(); 99 flush_cache_louis();
130 100
131 return ret; 101 return 0;
132} 102}
133early_initcall(init_static_idmap); 103early_initcall(init_static_idmap);
134 104