aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorChristoffer Dall <c.dall@virtualopensystems.com>2013-01-20 18:28:07 -0500
committerChristoffer Dall <c.dall@virtualopensystems.com>2013-01-23 13:29:11 -0500
commitd5d8184d35c990b1324d9b30bcd0e4e8aa08f56d (patch)
tree7559fbc98d2b347f89f926b39715d3bf3cfbb719 /arch/arm/include
parent342cd0ab0e6ca3fe7c88a78890352748b8e894a9 (diff)
KVM: ARM: Memory virtualization setup
This commit introduces the framework for guest memory management through the use of 2nd stage translation. Each VM has a pointer to a level-1 table (the pgd field in struct kvm_arch) which is used for the 2nd stage translations. Entries are added when handling guest faults (later patch) and the table itself can be allocated and freed through the following functions implemented in arch/arm/kvm/arm_mmu.c: - kvm_alloc_stage2_pgd(struct kvm *kvm); - kvm_free_stage2_pgd(struct kvm *kvm); Each entry in TLBs and caches are tagged with a VMID identifier in addition to ASIDs. The VMIDs are assigned consecutively to VMs in the order that VMs are executed, and caches and tlbs are invalidated when the VMID space has been used to allow for more than 255 simultaenously running guests. The 2nd stage pgd is allocated in kvm_arch_init_vm(). The table is freed in kvm_arch_destroy_vm(). Both functions are called from the main KVM code. We pre-allocate page table memory to be able to synchronize using a spinlock and be called under rcu_read_lock from the MMU notifiers. We steal the mmu_memory_cache implementation from x86 and adapt for our specific usage. We support MMU notifiers (thanks to Marc Zyngier) through kvm_unmap_hva and kvm_set_spte_hva. Finally, define kvm_phys_addr_ioremap() to map a device at a guest IPA, which is used by VGIC support to map the virtual CPU interface registers to the guest. This support is added by Marc Zyngier. Reviewed-by: Will Deacon <will.deacon@arm.com> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/kvm_asm.h2
-rw-r--r--arch/arm/include/asm/kvm_host.h18
-rw-r--r--arch/arm/include/asm/kvm_mmu.h9
3 files changed, 29 insertions, 0 deletions
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 81324e2eb3f9..f6652f6c5d84 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -57,6 +57,7 @@
57#define ARM_EXCEPTION_HVC 7 57#define ARM_EXCEPTION_HVC 7
58 58
59#ifndef __ASSEMBLY__ 59#ifndef __ASSEMBLY__
60struct kvm;
60struct kvm_vcpu; 61struct kvm_vcpu;
61 62
62extern char __kvm_hyp_init[]; 63extern char __kvm_hyp_init[];
@@ -71,6 +72,7 @@ extern char __kvm_hyp_code_start[];
71extern char __kvm_hyp_code_end[]; 72extern char __kvm_hyp_code_end[];
72 73
73extern void __kvm_flush_vm_context(void); 74extern void __kvm_flush_vm_context(void);
75extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
74 76
75extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); 77extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
76#endif 78#endif
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 067ef2898c26..3636c7ea4eb2 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -112,4 +112,22 @@ struct kvm_one_reg;
112int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); 112int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
113int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); 113int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
114u64 kvm_call_hyp(void *hypfn, ...); 114u64 kvm_call_hyp(void *hypfn, ...);
115
116#define KVM_ARCH_WANT_MMU_NOTIFIER
117struct kvm;
118int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
119int kvm_unmap_hva_range(struct kvm *kvm,
120 unsigned long start, unsigned long end);
121void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
122
123/* We do not have shadow page tables, hence the empty hooks */
124static inline int kvm_age_hva(struct kvm *kvm, unsigned long hva)
125{
126 return 0;
127}
128
129static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
130{
131 return 0;
132}
115#endif /* __ARM_KVM_HOST_H__ */ 133#endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index e8679b317b0f..499e7b0925ff 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -23,6 +23,15 @@ int create_hyp_mappings(void *from, void *to);
23int create_hyp_io_mappings(void *from, void *to, phys_addr_t); 23int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
24void free_hyp_pmds(void); 24void free_hyp_pmds(void);
25 25
26int kvm_alloc_stage2_pgd(struct kvm *kvm);
27void kvm_free_stage2_pgd(struct kvm *kvm);
28int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
29 phys_addr_t pa, unsigned long size);
30
31int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
32
33void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
34
26phys_addr_t kvm_mmu_get_httbr(void); 35phys_addr_t kvm_mmu_get_httbr(void);
27int kvm_mmu_init(void); 36int kvm_mmu_init(void);
28void kvm_clear_hyp_idmap(void); 37void kvm_clear_hyp_idmap(void);