aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-06-30 13:40:40 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2016-07-03 17:41:27 -0400
commitfd81e6bf3928c14f90a033df164c375d4ce0fd85 (patch)
tree9bf9ac123d247ee0bcc9702b683031a65d21b541 /arch/arm64/include
parentd53d9bc65289dc50b42587313466594e4d611f0f (diff)
arm64: KVM: Refactor kern_hyp_va to deal with multiple offsets
As we move towards a selectable HYP VA range, it is obvious that we don't want to test a variable to find out if we need to use the bottom VA range, the top VA range, or use the address as is (for VHE). Instead, we can expand our current helper to generate the right mask or nop with code patching. We default to using the top VA space, with alternatives to switch to the bottom one or to nop out the instructions. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'arch/arm64/include')
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h11
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h42
2 files changed, 39 insertions, 14 deletions
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 1d81f9abd172..cff510574fae 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -25,17 +25,6 @@
25 25
26#define __hyp_text __section(.hyp.text) notrace 26#define __hyp_text __section(.hyp.text) notrace
27 27
28static inline unsigned long __kern_hyp_va(unsigned long v)
29{
30 asm volatile(ALTERNATIVE("and %0, %0, %1",
31 "nop",
32 ARM64_HAS_VIRT_HOST_EXTN)
33 : "+r" (v) : "i" (HYP_PAGE_OFFSET_MASK));
34 return v;
35}
36
37#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v)))
38
39#define read_sysreg_elx(r,nvh,vh) \ 28#define read_sysreg_elx(r,nvh,vh) \
40 ({ \ 29 ({ \
41 u64 reg; \ 30 u64 reg; \
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 5e543231f615..2970537161d2 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -90,13 +90,33 @@
90/* 90/*
91 * Convert a kernel VA into a HYP VA. 91 * Convert a kernel VA into a HYP VA.
92 * reg: VA to be converted. 92 * reg: VA to be converted.
93 *
94 * This generates the following sequences:
95 * - High mask:
96 * and x0, x0, #HYP_PAGE_OFFSET_HIGH_MASK
97 * nop
98 * - Low mask:
99 * and x0, x0, #HYP_PAGE_OFFSET_HIGH_MASK
100 * and x0, x0, #HYP_PAGE_OFFSET_LOW_MASK
101 * - VHE:
102 * nop
103 * nop
104 *
105 * The "low mask" version works because the mask is a strict subset of
106 * the "high mask", hence performing the first mask for nothing.
107 * Should be completely invisible on any viable CPU.
93 */ 108 */
94.macro kern_hyp_va reg 109.macro kern_hyp_va reg
95alternative_if_not ARM64_HAS_VIRT_HOST_EXTN 110alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
96 and \reg, \reg, #HYP_PAGE_OFFSET_MASK 111 and \reg, \reg, #HYP_PAGE_OFFSET_HIGH_MASK
97alternative_else 112alternative_else
98 nop 113 nop
99alternative_endif 114alternative_endif
115alternative_if_not ARM64_HYP_OFFSET_LOW
116 nop
117alternative_else
118 and \reg, \reg, #HYP_PAGE_OFFSET_LOW_MASK
119alternative_endif
100.endm 120.endm
101 121
102#else 122#else
@@ -107,7 +127,23 @@ alternative_endif
107#include <asm/mmu_context.h> 127#include <asm/mmu_context.h>
108#include <asm/pgtable.h> 128#include <asm/pgtable.h>
109 129
110#define KERN_TO_HYP(kva) ((unsigned long)kva & HYP_PAGE_OFFSET_MASK) 130static inline unsigned long __kern_hyp_va(unsigned long v)
131{
132 asm volatile(ALTERNATIVE("and %0, %0, %1",
133 "nop",
134 ARM64_HAS_VIRT_HOST_EXTN)
135 : "+r" (v)
136 : "i" (HYP_PAGE_OFFSET_HIGH_MASK));
137 asm volatile(ALTERNATIVE("nop",
138 "and %0, %0, %1",
139 ARM64_HYP_OFFSET_LOW)
140 : "+r" (v)
141 : "i" (HYP_PAGE_OFFSET_LOW_MASK));
142 return v;
143}
144
145#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v)))
146#define KERN_TO_HYP(v) kern_hyp_va(v)
111 147
112/* 148/*
113 * We currently only support a 40bit IPA. 149 * We currently only support a 40bit IPA.