]> www.infradead.org Git - nvme.git/commitdiff
KVM: arm64: Make TCR2_EL1 save/restore dependent on the VM features
authorMarc Zyngier <maz@kernel.org>
Tue, 25 Jun 2024 13:00:39 +0000 (14:00 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Thu, 27 Jun 2024 00:04:25 +0000 (00:04 +0000)
As for other registers, save/restore of TCR2_EL1 should be gated
on the feature being actually present.

In the case of a nVHE hypervisor, it is perfectly fine to leave
the host value in the register, as HCRX_EL2.TCREn==0 imposes that
TCR2_EL1 is treated as 0.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240625130042.259175-4-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h

index 4be6a7fa007082ac008c83422e9bb69b0f5da324..ea2aeeff61db7e6379107cf6ebcc561e1d338a3b 100644 (file)
@@ -55,6 +55,17 @@ static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
        return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
 }
 
+static inline bool ctxt_has_tcrx(struct kvm_cpu_context *ctxt)
+{
+       struct kvm_vcpu *vcpu;
+
+       if (!cpus_have_final_cap(ARM64_HAS_TCR2))
+               return false;
+
+       vcpu = ctxt_to_vcpu(ctxt);
+       return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, TCRX, IMP);
+}
+
 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 {
        ctxt_sys_reg(ctxt, SCTLR_EL1)   = read_sysreg_el1(SYS_SCTLR);
@@ -62,7 +73,7 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
        ctxt_sys_reg(ctxt, TTBR0_EL1)   = read_sysreg_el1(SYS_TTBR0);
        ctxt_sys_reg(ctxt, TTBR1_EL1)   = read_sysreg_el1(SYS_TTBR1);
        ctxt_sys_reg(ctxt, TCR_EL1)     = read_sysreg_el1(SYS_TCR);
-       if (cpus_have_final_cap(ARM64_HAS_TCR2))
+       if (ctxt_has_tcrx(ctxt))
                ctxt_sys_reg(ctxt, TCR2_EL1)    = read_sysreg_el1(SYS_TCR2);
        ctxt_sys_reg(ctxt, ESR_EL1)     = read_sysreg_el1(SYS_ESR);
        ctxt_sys_reg(ctxt, AFSR0_EL1)   = read_sysreg_el1(SYS_AFSR0);
@@ -138,7 +149,7 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
        write_sysreg_el1(ctxt_sys_reg(ctxt, CPACR_EL1), SYS_CPACR);
        write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL1), SYS_TTBR0);
        write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL1), SYS_TTBR1);
-       if (cpus_have_final_cap(ARM64_HAS_TCR2))
+       if (ctxt_has_tcrx(ctxt))
                write_sysreg_el1(ctxt_sys_reg(ctxt, TCR2_EL1),  SYS_TCR2);
        write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL1),   SYS_ESR);
        write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL1), SYS_AFSR0);