On systems with SME access to the SMPRI_EL1 priority management register is controlled by the nSMPRI_EL1 fine grained trap and TPIDR2_EL0 is controlled by nTPIDR2_EL0. We manage these traps in nVHE mode but do not do so when in VHE mode, add the required management.
Without this these registers could be used as side channels where implemented.
Fixes: 861262ab8627 ("KVM: arm64: Handle SME host state when running guests") Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org --- arch/arm64/kvm/hyp/vhe/switch.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 7acb87eaa092..9dac3a1a85f7 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -63,10 +63,20 @@ static void __activate_traps(struct kvm_vcpu *vcpu) __activate_traps_fpsimd32(vcpu); }
- if (cpus_have_final_cap(ARM64_SME)) + if (cpus_have_final_cap(ARM64_SME)) { write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2, sctlr_el2);
+ sysreg_clear_set_s(SYS_HFGRTR_EL2, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK, + 0); + sysreg_clear_set_s(SYS_HFGWTR_EL2, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK, + 0); + } + write_sysreg(val, cpacr_el1);
write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); @@ -88,9 +98,21 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) */ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
- if (cpus_have_final_cap(ARM64_SME)) + if (cpus_have_final_cap(ARM64_SME)) { + /* + * Enable access to SMPRI_EL1 - we don't need to + * control nTPIDR2_EL0 in VHE mode. + */ + sysreg_clear_set_s(SYS_HFGRTR_EL2, 0, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK); + sysreg_clear_set_s(SYS_HFGWTR_EL2, 0, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK); + write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2, sctlr_el2); + }
write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);