summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/hyp-stub.S
diff options
context:
space:
mode:
authorGeoff Levand <geoff@infradead.org>2016-04-27 18:47:03 +0200
committerWill Deacon <will.deacon@arm.com>2016-04-28 13:05:46 +0200
commitad72e59ff2bad55f6b9e7ac1fe5d824831ea2550 (patch)
treeca5eca21b84288153c2ea778da81b9a5420afd95 /arch/arm64/kernel/hyp-stub.S
parentarm64: kvm: Move lr save/restore from do_el2_call into EL1 (diff)
downloadlinux-ad72e59ff2bad55f6b9e7ac1fe5d824831ea2550.tar.xz
linux-ad72e59ff2bad55f6b9e7ac1fe5d824831ea2550.zip
arm64: hyp/kvm: Make hyp-stub extensible
The existing arm64 hcall implementations are limited in that they only allow for two distinct hcalls; with the x0 register either zero or not zero. Also, the API of the hyp-stub exception vector routines and the KVM exception vector routines differ; hyp-stub uses a non-zero value in x0 to implement __hyp_set_vectors, whereas KVM uses it to implement kvm_call_hyp. To allow for additional hcalls to be defined and to make the arm64 hcall API more consistent across exception vector routines, change the hcall implementations to reserve all x0 values below 0xfff for hcalls such as {s,g}et_vectors(). Define two new preprocessor macros HVC_GET_VECTORS, and HVC_SET_VECTORS to be used as hcall type specifiers and convert the existing __hyp_get_vectors() and __hyp_set_vectors() routines to use these new macros when executing an HVC call. Also, change the corresponding hyp-stub and KVM el1_sync exception vector routines to use these new macros. Signed-off-by: Geoff Levand <geoff@infradead.org> [Merged two hcall patches, moved immediate value from esr to x0, use lr as a scratch register, changed limit to 0xfff] Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/hyp-stub.S')
-rw-r--r--arch/arm64/kernel/hyp-stub.S34
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 7eab8acbbbd9..894fb40fb378 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -22,6 +22,7 @@
#include <linux/irqchip/arm-gic-v3.h>
#include <asm/assembler.h>
+#include <asm/kvm_arm.h>
#include <asm/ptrace.h>
#include <asm/virt.h>
@@ -53,15 +54,26 @@ ENDPROC(__hyp_stub_vectors)
.align 11
el1_sync:
- mrs x1, esr_el2
- lsr x1, x1, #26
- cmp x1, #0x16
- b.ne 2f // Not an HVC trap
- cbz x0, 1f
- msr vbar_el2, x0 // Set vbar_el2
- b 2f
-1: mrs x0, vbar_el2 // Return vbar_el2
-2: eret
+ mrs x30, esr_el2
+ lsr x30, x30, #ESR_ELx_EC_SHIFT
+
+ cmp x30, #ESR_ELx_EC_HVC64
+ b.ne 9f // Not an HVC trap
+
+ cmp x0, #HVC_GET_VECTORS
+ b.ne 1f
+ mrs x0, vbar_el2
+ b 9f
+
+1: cmp x0, #HVC_SET_VECTORS
+ b.ne 2f
+ msr vbar_el2, x1
+ b 9f
+
+ /* Unrecognised call type */
+2: mov x0, xzr
+
+9: eret
ENDPROC(el1_sync)
.macro invalid_vector label
@@ -102,7 +114,7 @@ ENDPROC(\label)
ENTRY(__hyp_get_vectors)
str lr, [sp, #-16]!
- mov x0, xzr
+ mov x0, #HVC_GET_VECTORS
hvc #0
ldr lr, [sp], #16
ret
@@ -110,6 +122,8 @@ ENDPROC(__hyp_get_vectors)
ENTRY(__hyp_set_vectors)
str lr, [sp, #-16]!
+ mov x1, x0
+ mov x0, #HVC_SET_VECTORS
hvc #0
ldr lr, [sp], #16
ret