]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: arm64: nv: Sanitise CNTHCTL_EL2
authorMarc Zyngier <maz@kernel.org>
Tue, 17 Dec 2024 14:23:18 +0000 (14:23 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 2 Jan 2025 19:19:10 +0000 (19:19 +0000)
Inject some sanity in CNTHCTL_EL2, ensuring that we don't handle
more than we advertise to the guest.

Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20241217142321.763801-11-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/nested.c
include/clocksource/arm_arch_timer.h

index e18e9244d17a4f7742729e31481680254617bac8..cf571d41faa89048c18ae7d6d9e9d75d3b8dd82e 100644 (file)
@@ -490,7 +490,6 @@ enum vcpu_sysreg {
        VBAR_EL2,       /* Vector Base Address Register (EL2) */
        RVBAR_EL2,      /* Reset Vector Base Address Register */
        CONTEXTIDR_EL2, /* Context ID Register (EL2) */
-       CNTHCTL_EL2,    /* Counter-timer Hypervisor Control register */
        SP_EL2,         /* EL2 Stack Pointer */
        CNTHP_CTL_EL2,
        CNTHP_CVAL_EL2,
@@ -501,6 +500,7 @@ enum vcpu_sysreg {
        MARKER(__SANITISED_REG_START__),
        TCR2_EL2,       /* Extended Translation Control Register (EL2) */
        MDCR_EL2,       /* Monitor Debug Configuration Register (EL2) */
+       CNTHCTL_EL2,    /* Counter-timer Hypervisor Control register */
 
        /* Any VNCR-capable reg goes after this point */
        MARKER(__VNCR_START__),
index 9b36218b48def495708f49b59e5f9211bd86cc0f..9113c6025d6f3e137a7db3cc213c606f455b92f9 100644 (file)
@@ -1271,6 +1271,21 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
                res0 |= MDCR_EL2_EnSTEPOP;
        set_sysreg_masks(kvm, MDCR_EL2, res0, res1);
 
+       /* CNTHCTL_EL2 */
+       res0 = GENMASK(63, 20);
+       res1 = 0;
+       if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RME, IMP))
+               res0 |= CNTHCTL_CNTPMASK | CNTHCTL_CNTVMASK;
+       if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, CNTPOFF)) {
+               res0 |= CNTHCTL_ECV;
+               if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, ECV, IMP))
+                       res0 |= (CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT |
+                                CNTHCTL_EL1NVPCT | CNTHCTL_EL1NVVCT);
+       }
+       if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, VH, IMP))
+               res0 |= GENMASK(11, 8);
+       set_sysreg_masks(kvm, CNTHCTL_EL2, res0, res1);
+
        return 0;
 }
 
index c62811fb413096b3d6a5dc2755b3678aa6b8afc0..ce6521ad04d12160a40d0d4b7ebd843a6b900a0d 100644 (file)
@@ -26,6 +26,8 @@
 #define CNTHCTL_EL1TVCT                        (1 << 14)
 #define CNTHCTL_EL1NVPCT               (1 << 15)
 #define CNTHCTL_EL1NVVCT               (1 << 16)
+#define CNTHCTL_CNTVMASK               (1 << 18)
+#define CNTHCTL_CNTPMASK               (1 << 19)
 
 enum arch_timer_reg {
        ARCH_TIMER_REG_CTRL,