diff options
Diffstat (limited to 'arch/arm/include')
| -rw-r--r-- | arch/arm/include/asm/idmap.h | 1 | ||||
| -rw-r--r-- | arch/arm/include/asm/kvm_host.h | 47 | ||||
| -rw-r--r-- | arch/arm/include/asm/kvm_mmu.h | 28 |
3 files changed, 55 insertions, 21 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 | ||
| 10 | extern pgd_t *idmap_pgd; | 10 | extern pgd_t *idmap_pgd; |
| 11 | extern pgd_t *hyp_pgd; | ||
| 12 | 11 | ||
| 13 | void setup_mm_for_reboot(void); | 12 | void setup_mm_for_reboot(void); |
| 14 | 13 | ||
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 0c4e643d939e..57cb786a6203 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
| @@ -87,7 +87,7 @@ struct kvm_vcpu_fault_info { | |||
| 87 | u32 hyp_pc; /* PC when exception was taken from Hyp mode */ | 87 | u32 hyp_pc; /* PC when exception was taken from Hyp mode */ |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | typedef struct vfp_hard_struct kvm_kernel_vfp_t; | 90 | typedef struct vfp_hard_struct kvm_cpu_context_t; |
| 91 | 91 | ||
| 92 | struct kvm_vcpu_arch { | 92 | struct kvm_vcpu_arch { |
| 93 | struct kvm_regs regs; | 93 | struct kvm_regs regs; |
| @@ -105,8 +105,10 @@ struct kvm_vcpu_arch { | |||
| 105 | struct kvm_vcpu_fault_info fault; | 105 | struct kvm_vcpu_fault_info fault; |
| 106 | 106 | ||
| 107 | /* Floating point registers (VFP and Advanced SIMD/NEON) */ | 107 | /* Floating point registers (VFP and Advanced SIMD/NEON) */ |
| 108 | kvm_kernel_vfp_t vfp_guest; | 108 | struct vfp_hard_struct vfp_guest; |
| 109 | kvm_kernel_vfp_t *vfp_host; | 109 | |
| 110 | /* Host FP context */ | ||
| 111 | kvm_cpu_context_t *host_cpu_context; | ||
| 110 | 112 | ||
| 111 | /* VGIC state */ | 113 | /* VGIC state */ |
| 112 | struct vgic_cpu vgic_cpu; | 114 | struct vgic_cpu vgic_cpu; |
| @@ -188,23 +190,38 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); | |||
| 188 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, | 190 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, |
| 189 | int exception_index); | 191 | int exception_index); |
| 190 | 192 | ||
| 191 | static inline void __cpu_init_hyp_mode(unsigned long long pgd_ptr, | 193 | static inline void __cpu_init_hyp_mode(unsigned long long boot_pgd_ptr, |
| 194 | unsigned long long pgd_ptr, | ||
| 192 | unsigned long hyp_stack_ptr, | 195 | unsigned long hyp_stack_ptr, |
| 193 | unsigned long vector_ptr) | 196 | unsigned long vector_ptr) |
| 194 | { | 197 | { |
| 195 | unsigned long pgd_low, pgd_high; | ||
| 196 | |||
| 197 | pgd_low = (pgd_ptr & ((1ULL << 32) - 1)); | ||
| 198 | pgd_high = (pgd_ptr >> 32ULL); | ||
| 199 | |||
| 200 | /* | 198 | /* |
| 201 | * Call initialization code, and switch to the full blown | 199 | * Call initialization code, and switch to the full blown HYP |
| 202 | * HYP code. The init code doesn't need to preserve these registers as | 200 | * code. The init code doesn't need to preserve these |
| 203 | * r1-r3 and r12 are already callee save according to the AAPCS. | 201 | * registers as r0-r3 are already callee saved according to |
| 204 | * Note that we slightly misuse the prototype by casing the pgd_low to | 202 | * the AAPCS. |
| 205 | * a void *. | 203 | * Note that we slightly misuse the prototype by casing the |
| 204 | * stack pointer to a void *. | ||
| 205 | * | ||
| 206 | * We don't have enough registers to perform the full init in | ||
| 207 | * one go. Install the boot PGD first, and then install the | ||
| 208 | * runtime PGD, stack pointer and vectors. The PGDs are always | ||
| 209 | * passed as the third argument, in order to be passed into | ||
| 210 | * r2-r3 to the init code (yes, this is compliant with the | ||
| 211 | * PCS!). | ||
| 206 | */ | 212 | */ |
| 207 | kvm_call_hyp((void *)pgd_low, pgd_high, hyp_stack_ptr, vector_ptr); | 213 | |
| 214 | kvm_call_hyp(NULL, 0, boot_pgd_ptr); | ||
| 215 | |||
| 216 | kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr); | ||
| 208 | } | 217 | } |
| 209 | 218 | ||
| 219 | static inline int kvm_arch_dev_ioctl_check_extension(long ext) | ||
| 220 | { | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | int kvm_perf_init(void); | ||
| 225 | int kvm_perf_teardown(void); | ||
| 226 | |||
| 210 | #endif /* __ARM_KVM_HOST_H__ */ | 227 | #endif /* __ARM_KVM_HOST_H__ */ |
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 970f3b5fa109..472ac7091003 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
| @@ -19,21 +19,33 @@ | |||
| 19 | #ifndef __ARM_KVM_MMU_H__ | 19 | #ifndef __ARM_KVM_MMU_H__ |
| 20 | #define __ARM_KVM_MMU_H__ | 20 | #define __ARM_KVM_MMU_H__ |
| 21 | 21 | ||
| 22 | #include <asm/cacheflush.h> | 22 | #include <asm/memory.h> |
| 23 | #include <asm/pgalloc.h> | 23 | #include <asm/page.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 |
| 28 | * the mapping (HTTBR "covers" TTBR1). | 27 | * the mapping (HTTBR "covers" TTBR1). |
| 29 | */ | 28 | */ |
| 30 | #define HYP_PAGE_OFFSET_MASK (~0UL) | 29 | #define HYP_PAGE_OFFSET_MASK UL(~0) |
| 31 | #define HYP_PAGE_OFFSET PAGE_OFFSET | 30 | #define HYP_PAGE_OFFSET PAGE_OFFSET |
| 32 | #define KERN_TO_HYP(kva) (kva) | 31 | #define KERN_TO_HYP(kva) (kva) |
| 33 | 32 | ||
| 33 | /* | ||
| 34 | * Our virtual mapping for the boot-time MMU-enable code. Must be | ||
| 35 | * shared across all the page-tables. Conveniently, we use the vectors | ||
| 36 | * page, where no kernel data will ever be shared with HYP. | ||
| 37 | */ | ||
| 38 | #define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) | ||
| 39 | |||
| 40 | #ifndef __ASSEMBLY__ | ||
| 41 | |||
| 42 | #include <asm/cacheflush.h> | ||
| 43 | #include <asm/pgalloc.h> | ||
| 44 | |||
| 34 | int create_hyp_mappings(void *from, void *to); | 45 | int create_hyp_mappings(void *from, void *to); |
| 35 | int create_hyp_io_mappings(void *from, void *to, phys_addr_t); | 46 | int create_hyp_io_mappings(void *from, void *to, phys_addr_t); |
| 36 | void free_hyp_pmds(void); | 47 | void free_boot_hyp_pgd(void); |
| 48 | void free_hyp_pgds(void); | ||
| 37 | 49 | ||
| 38 | int kvm_alloc_stage2_pgd(struct kvm *kvm); | 50 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
| 39 | void kvm_free_stage2_pgd(struct kvm *kvm); | 51 | void kvm_free_stage2_pgd(struct kvm *kvm); |
| @@ -45,6 +57,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); | |||
| 45 | void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); | 57 | void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); |
| 46 | 58 | ||
| 47 | phys_addr_t kvm_mmu_get_httbr(void); | 59 | phys_addr_t kvm_mmu_get_httbr(void); |
| 60 | phys_addr_t kvm_mmu_get_boot_httbr(void); | ||
| 61 | phys_addr_t kvm_get_idmap_vector(void); | ||
| 48 | int kvm_mmu_init(void); | 62 | int kvm_mmu_init(void); |
| 49 | void kvm_clear_hyp_idmap(void); | 63 | void kvm_clear_hyp_idmap(void); |
| 50 | 64 | ||
| @@ -114,4 +128,8 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) | |||
| 114 | } | 128 | } |
| 115 | } | 129 | } |
| 116 | 130 | ||
| 131 | #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) | ||
| 132 | |||
| 133 | #endif /* !__ASSEMBLY__ */ | ||
| 134 | |||
| 117 | #endif /* __ARM_KVM_MMU_H__ */ | 135 | #endif /* __ARM_KVM_MMU_H__ */ |
