Commit 755db234 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: Generate final CTR_EL0 value when running in Protected mode



In protected mode, late CPUs are not allowed to boot (enforced by
the PSCI relay). We can thus specialise the read_ctr macro to
always return a pre-computed, sanitised value. Special care is
taken to prevent the use of this custome version outside of
the protected mode.

Reviewed-by: default avatarQuentin Perret <qperret@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 90134ac9
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <asm-generic/export.h>

#include <asm/asm-offsets.h>
#include <asm/asm-bug.h>
#include <asm/cpufeature.h>
#include <asm/cputype.h>
#include <asm/debug-monitors.h>
@@ -270,12 +271,24 @@ alternative_endif
 * provide the system wide safe value from arm64_ftr_reg_ctrel0.sys_val
 */
	.macro	read_ctr, reg
#ifndef __KVM_NVHE_HYPERVISOR__
alternative_if_not ARM64_MISMATCHED_CACHE_TYPE
	mrs	\reg, ctr_el0			// read CTR
	nop
alternative_else
	ldr_l	\reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
alternative_endif
#else
alternative_if_not ARM64_KVM_PROTECTED_MODE
	ASM_BUG()
alternative_else_nop_endif
alternative_cb kvm_compute_final_ctr_el0
	movz	\reg, #0
	movk	\reg, #0, lsl #16
	movk	\reg, #0, lsl #32
	movk	\reg, #0, lsl #48
alternative_cb_end
#endif
	.endm


+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ __efistub__ctype = _ctype;
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
KVM_NVHE_ALIAS(kvm_update_va_mask);
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0);

/* Global kernel state accessed by nVHE hyp code. */
KVM_NVHE_ALIAS(kvm_vgic_global_state);
+7 −0
Original line number Diff line number Diff line
@@ -288,3 +288,10 @@ void kvm_get_kimage_voffset(struct alt_instr *alt,
{
	generate_mov_q(kimage_voffset, origptr, updptr, nr_inst);
}

void kvm_compute_final_ctr_el0(struct alt_instr *alt,
			       __le32 *origptr, __le32 *updptr, int nr_inst)
{
	generate_mov_q(read_sanitised_ftr_reg(SYS_CTR_EL0),
		       origptr, updptr, nr_inst);
}