Commit 68b824e4 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: Patch kimage_voffset instead of loading the EL1 value



Directly using the kimage_voffset variable is fine for now, but
will become more problematic as we start distrusting EL1.

Instead, patch the kimage_voffset into the HYP text, ensuring
we don't have to load an untrusted value later on.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 7cd0aaaf
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -72,6 +72,28 @@ alternative_cb kvm_update_va_mask
alternative_cb_end
.endm

/*
 * Convert a kernel image address to a PA
 * reg: kernel address to be converted in place
 * tmp: temporary register
 *
 * The actual code generation takes place in kvm_get_kimage_voffset, and
 * the instructions below are only there to reserve the space and
 * perform the register allocation (kvm_get_kimage_voffset uses the
 * specific registers encoded in the instructions).
 */
.macro kimg_pa reg, tmp
alternative_cb kvm_get_kimage_voffset
	movz	\tmp, #0
	movk	\tmp, #0, lsl #16
	movk	\tmp, #0, lsl #32
	movk	\tmp, #0, lsl #48
alternative_cb_end

	/* reg = __pa(reg) */
	sub	\reg, \reg, \tmp
.endm

#else

#include <linux/pgtable.h>
+1 −3
Original line number Diff line number Diff line
@@ -65,13 +65,11 @@ __efistub__ctype = _ctype;
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
KVM_NVHE_ALIAS(kvm_update_va_mask);
KVM_NVHE_ALIAS(kvm_update_kimg_phys_offset);
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);

/* Global kernel state accessed by nVHE hyp code. */
KVM_NVHE_ALIAS(kvm_vgic_global_state);

/* Kernel constant needed to compute idmap addresses. */
KVM_NVHE_ALIAS(kimage_voffset);

/* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
KVM_NVHE_ALIAS(__hyp_panic_string);
KVM_NVHE_ALIAS(panic);
+1 −4
Original line number Diff line number Diff line
@@ -115,10 +115,7 @@ SYM_FUNC_END(__hyp_do_panic)
	 * Preserve x0-x4, which may contain stub parameters.
	 */
	ldr	x5, =__kvm_handle_stub_hvc
	ldr_l	x6, kimage_voffset

	/* x5 = __pa(x5) */
	sub	x5, x5, x6
	kimg_pa x5, x6
	br	x5
.L__vect_end\@:
.if ((.L__vect_end\@ - .L__vect_start\@) > 0x80)
+6 −0
Original line number Diff line number Diff line
@@ -251,3 +251,9 @@ void kvm_update_kimg_phys_offset(struct alt_instr *alt,
{
	generate_mov_q(kimage_voffset + PHYS_OFFSET, origptr, updptr, nr_inst);
}

void kvm_get_kimage_voffset(struct alt_instr *alt,
			    __le32 *origptr, __le32 *updptr, int nr_inst)
{
	generate_mov_q(kimage_voffset, origptr, updptr, nr_inst);
}