KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented
authorMarc Zyngier <maz@kernel.org>
Mon, 22 Jan 2024 18:13:43 +0000 (18:13 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Thu, 8 Feb 2024 15:12:45 +0000 (15:12 +0000)
If NV1 isn't supported on a system, make sure we always evaluate
the guest's HCR_EL2.E2H as RES1, irrespective of what the guest
may have written there.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240122181344.258974-10-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/include/asm/kvm_emulate.h
arch/arm64/kvm/sys_regs.c

index b804fe832184466d68f597533858b90a6ffbc781..debc3753d2ef6d946f05c7f80c36dfdd6ddea6ac 100644 (file)
@@ -209,7 +209,8 @@ static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
 
 static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
 {
-       return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
+       return (!cpus_have_final_cap(ARM64_HAS_HCR_NV1) ||
+               (ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H));
 }
 
 static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
index 08a9571fa80919eaad43a22389f28776b53794ac..041b11825578d54452ed0fcb993f135bc6147000 100644 (file)
@@ -2175,6 +2175,16 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
        return true;
 }
 
+static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+       u64 val = r->val;
+
+       if (!cpus_have_final_cap(ARM64_HAS_HCR_NV1))
+               val |= HCR_E2H;
+
+       return __vcpu_sys_reg(vcpu, r->reg) = val;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2666,7 +2676,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        EL2_REG_VNCR(VMPIDR_EL2, reset_unknown, 0),
        EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
        EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
-       EL2_REG_VNCR(HCR_EL2, reset_val, 0),
+       EL2_REG_VNCR(HCR_EL2, reset_hcr, 0),
        EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
        EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
        EL2_REG_VNCR(HSTR_EL2, reset_val, 0),