Skip to content

Commit

Permalink
KVM: arm64: Abstract the size of the HYP vectors pre-amble
Browse files Browse the repository at this point in the history
The EL2 vector hardening feature causes KVM to generate vectors for
each type of CPU present in the system. The generated sequences already
do some of the early guest-exit work (i.e. saving registers). To avoid
duplication the generated vectors branch to the original vector just
after the preamble. This size is hard coded.

Adding new instructions to the HYP vector causes strange side effects,
which are difficult to debug as the affected code is patched in at
runtime.

Add KVM_VECTOR_PREAMBLE to tell kvm_patch_vector_branch() how big
the preamble is. The valid_vect macro can then validate this at
build time.

Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
  • Loading branch information
James Morse authored and Marc Zyngier committed Jul 5, 2019
1 parent 2b68a2a commit 3dbf100
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
6 changes: 6 additions & 0 deletions arch/arm64/include/asm/kvm_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
{ARM_EXCEPTION_TRAP, "TRAP" }, \
{ARM_EXCEPTION_HYP_GONE, "HYP_GONE" }

/*
* Size of the HYP vectors preamble. kvm_patch_vector_branch() generates code
* that jumps over this.
*/
#define KVM_VECTOR_PREAMBLE (1 * AARCH64_INSN_SIZE)

#ifndef __ASSEMBLY__

#include <linux/mm.h>
Expand Down
18 changes: 17 additions & 1 deletion arch/arm64/kvm/hyp/hyp-entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,32 @@ ENDPROC(\label)

.align 11

.macro check_preamble_length start, end
/* kvm_patch_vector_branch() generates code that jumps over the preamble. */
.if ((\end-\start) != KVM_VECTOR_PREAMBLE)
.error "KVM vector preamble length mismatch"
.endif
.endm

.macro valid_vect target
.align 7
661:
stp x0, x1, [sp, #-16]!
662:
b \target

check_preamble_length 661b, 662b
.endm

.macro invalid_vect target
.align 7
661:
b \target
662:
ldp x0, x1, [sp], #16
b \target

check_preamble_length 661b, 662b
.endm

ENTRY(__kvm_hyp_vector)
Expand Down Expand Up @@ -271,7 +286,8 @@ ENDPROC(__kvm_hyp_vector)
* movk x0, #((addr >> 32) & 0xffff), lsl #32
* br x0
*
* Where addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + 4.
* Where:
* addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + KVM_VECTOR_PREAMBLE.
* See kvm_patch_vector_branch for details.
*/
alternative_cb kvm_patch_vector_branch
Expand Down
7 changes: 3 additions & 4 deletions arch/arm64/kvm/va_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,10 @@ void kvm_patch_vector_branch(struct alt_instr *alt,
addr |= ((u64)origptr & GENMASK_ULL(10, 7));

/*
* Branch to the second instruction in the vectors in order to
* avoid the initial store on the stack (which we already
* perform in the hardening vectors).
* Branch over the preamble in order to avoid the initial store on
* the stack (which we already perform in the hardening vectors).
*/
addr += AARCH64_INSN_SIZE;
addr += KVM_VECTOR_PREAMBLE;

/* stp x0, x1, [sp, #-16]! */
insn = aarch64_insn_gen_load_store_pair(AARCH64_INSN_REG_0,
Expand Down

0 comments on commit 3dbf100

Please sign in to comment.