Skip to content

Commit ad72e59

Browse files
glevandwildea01
authored andcommitted
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>
1 parent 00a44cd commit ad72e59

File tree

4 files changed

+44
-14
lines changed

4 files changed

+44
-14
lines changed

arch/arm64/include/asm/virt.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@
1818
#ifndef __ASM__VIRT_H
1919
#define __ASM__VIRT_H
2020

21+
/*
22+
* The arm64 hcall implementation uses x0 to specify the hcall type. A value
23+
* less than 0xfff indicates a special hcall, such as get/set vector.
24+
* Any other value is used as a pointer to the function to call.
25+
*/
26+
27+
/* HVC_GET_VECTORS - Return the value of the vbar_el2 register. */
28+
#define HVC_GET_VECTORS 0
29+
30+
/*
31+
* HVC_SET_VECTORS - Set the value of the vbar_el2 register.
32+
*
33+
* @x1: Physical address of the new vector table.
34+
*/
35+
#define HVC_SET_VECTORS 1
36+
2137
#define BOOT_CPU_MODE_EL1 (0xe11)
2238
#define BOOT_CPU_MODE_EL2 (0xe12)
2339

arch/arm64/kernel/hyp-stub.S

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/irqchip/arm-gic-v3.h>
2323

2424
#include <asm/assembler.h>
25+
#include <asm/kvm_arm.h>
2526
#include <asm/ptrace.h>
2627
#include <asm/virt.h>
2728

@@ -53,15 +54,26 @@ ENDPROC(__hyp_stub_vectors)
5354
.align 11
5455

5556
el1_sync:
56-
mrs x1, esr_el2
57-
lsr x1, x1, #26
58-
cmp x1, #0x16
59-
b.ne 2f // Not an HVC trap
60-
cbz x0, 1f
61-
msr vbar_el2, x0 // Set vbar_el2
62-
b 2f
63-
1: mrs x0, vbar_el2 // Return vbar_el2
64-
2: eret
57+
mrs x30, esr_el2
58+
lsr x30, x30, #ESR_ELx_EC_SHIFT
59+
60+
cmp x30, #ESR_ELx_EC_HVC64
61+
b.ne 9f // Not an HVC trap
62+
63+
cmp x0, #HVC_GET_VECTORS
64+
b.ne 1f
65+
mrs x0, vbar_el2
66+
b 9f
67+
68+
1: cmp x0, #HVC_SET_VECTORS
69+
b.ne 2f
70+
msr vbar_el2, x1
71+
b 9f
72+
73+
/* Unrecognised call type */
74+
2: mov x0, xzr
75+
76+
9: eret
6577
ENDPROC(el1_sync)
6678

6779
.macro invalid_vector label
@@ -102,14 +114,16 @@ ENDPROC(\label)
102114

103115
ENTRY(__hyp_get_vectors)
104116
str lr, [sp, #-16]!
105-
mov x0, xzr
117+
mov x0, #HVC_GET_VECTORS
106118
hvc #0
107119
ldr lr, [sp], #16
108120
ret
109121
ENDPROC(__hyp_get_vectors)
110122

111123
ENTRY(__hyp_set_vectors)
112124
str lr, [sp, #-16]!
125+
mov x1, x0
126+
mov x0, #HVC_SET_VECTORS
113127
hvc #0
114128
ldr lr, [sp], #16
115129
ret

arch/arm64/kvm/hyp.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
* in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are
3636
* passed in x0.
3737
*
38-
* A function pointer with a value of 0 has a special meaning, and is
39-
* used to implement __hyp_get_vectors in the same way as in
38+
* A function pointer with a value less than 0xfff has a special meaning,
39+
* and is used to implement __hyp_get_vectors in the same way as in
4040
* arch/arm64/kernel/hyp_stub.S.
4141
* HVC behaves as a 'bl' call and will clobber lr.
4242
*/

arch/arm64/kvm/hyp/hyp-entry.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ alternative_endif
8282
/* Here, we're pretty sure the host called HVC. */
8383
restore_x0_to_x3
8484

85-
/* Check for __hyp_get_vectors */
86-
cbnz x0, 1f
85+
cmp x0, #HVC_GET_VECTORS
86+
b.ne 1f
8787
mrs x0, vbar_el2
8888
b 2f
8989

0 commit comments

Comments
 (0)