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: Quentin Perret <qperret@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
90134ac9ca
commit
755db23420
@ -15,6 +15,7 @@
|
|||||||
#include <asm-generic/export.h>
|
#include <asm-generic/export.h>
|
||||||
|
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
|
#include <asm/asm-bug.h>
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
#include <asm/cputype.h>
|
#include <asm/cputype.h>
|
||||||
#include <asm/debug-monitors.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
|
* provide the system wide safe value from arm64_ftr_reg_ctrel0.sys_val
|
||||||
*/
|
*/
|
||||||
.macro read_ctr, reg
|
.macro read_ctr, reg
|
||||||
|
#ifndef __KVM_NVHE_HYPERVISOR__
|
||||||
alternative_if_not ARM64_MISMATCHED_CACHE_TYPE
|
alternative_if_not ARM64_MISMATCHED_CACHE_TYPE
|
||||||
mrs \reg, ctr_el0 // read CTR
|
mrs \reg, ctr_el0 // read CTR
|
||||||
nop
|
nop
|
||||||
alternative_else
|
alternative_else
|
||||||
ldr_l \reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
|
ldr_l \reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
|
||||||
alternative_endif
|
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
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ __efistub__ctype = _ctype;
|
|||||||
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
|
KVM_NVHE_ALIAS(kvm_patch_vector_branch);
|
||||||
KVM_NVHE_ALIAS(kvm_update_va_mask);
|
KVM_NVHE_ALIAS(kvm_update_va_mask);
|
||||||
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
|
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
|
||||||
|
KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0);
|
||||||
|
|
||||||
/* Global kernel state accessed by nVHE hyp code. */
|
/* Global kernel state accessed by nVHE hyp code. */
|
||||||
KVM_NVHE_ALIAS(kvm_vgic_global_state);
|
KVM_NVHE_ALIAS(kvm_vgic_global_state);
|
||||||
|
@ -288,3 +288,10 @@ void kvm_get_kimage_voffset(struct alt_instr *alt,
|
|||||||
{
|
{
|
||||||
generate_mov_q(kimage_voffset, origptr, updptr, nr_inst);
|
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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user