]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: arm64: nv: Add trap routing for CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
authorMarc Zyngier <maz@kernel.org>
Tue, 17 Dec 2024 14:23:16 +0000 (14:23 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 2 Jan 2025 19:19:10 +0000 (19:19 +0000)
For completeness, fun, and cerebral meltdown, add the virtualisation
related traps to the counter and timers.

Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20241217142321.763801-9-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/emulate-nested.c

index 1ffbfd1c3cf2ecfa50284f8d4f54a22d06079ed2..03d21044c41f518b457859ac8044c27fbab355ab 100644 (file)
@@ -89,6 +89,9 @@ enum cgt_group_id {
        CGT_HCRX_EnFPM,
        CGT_HCRX_TCR2En,
 
+       CGT_CNTHCTL_EL1TVT,
+       CGT_CNTHCTL_EL1TVCT,
+
        CGT_ICH_HCR_TC,
        CGT_ICH_HCR_TALL0,
        CGT_ICH_HCR_TALL1,
@@ -124,6 +127,8 @@ enum cgt_group_id {
        __COMPLEX_CONDITIONS__,
        CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
        CGT_CNTHCTL_EL1PTEN,
+       CGT_CNTHCTL_EL1NVPCT,
+       CGT_CNTHCTL_EL1NVVCT,
 
        CGT_CPTR_TTA,
        CGT_MDCR_HPMN,
@@ -393,6 +398,18 @@ static const struct trap_bits coarse_trap_bits[] = {
                .mask           = HCRX_EL2_TCR2En,
                .behaviour      = BEHAVE_FORWARD_RW,
        },
+       [CGT_CNTHCTL_EL1TVT] = {
+               .index          = CNTHCTL_EL2,
+               .value          = CNTHCTL_EL1TVT,
+               .mask           = CNTHCTL_EL1TVT,
+               .behaviour      = BEHAVE_FORWARD_RW,
+       },
+       [CGT_CNTHCTL_EL1TVCT] = {
+               .index          = CNTHCTL_EL2,
+               .value          = CNTHCTL_EL1TVCT,
+               .mask           = CNTHCTL_EL1TVCT,
+               .behaviour      = BEHAVE_FORWARD_READ,
+       },
        [CGT_ICH_HCR_TC] = {
                .index          = ICH_HCR_EL2,
                .value          = ICH_HCR_TC,
@@ -487,6 +504,32 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
        return BEHAVE_FORWARD_RW;
 }
 
+static bool is_nested_nv2_guest(struct kvm_vcpu *vcpu)
+{
+       u64 val;
+
+       val = __vcpu_sys_reg(vcpu, HCR_EL2);
+       return ((val & (HCR_E2H | HCR_TGE | HCR_NV2 | HCR_NV1 | HCR_NV)) == (HCR_E2H | HCR_NV2 | HCR_NV));
+}
+
+static enum trap_behaviour check_cnthctl_el1nvpct(struct kvm_vcpu *vcpu)
+{
+       if (!is_nested_nv2_guest(vcpu) ||
+           !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVPCT))
+               return BEHAVE_HANDLE_LOCALLY;
+
+       return BEHAVE_FORWARD_RW;
+}
+
+static enum trap_behaviour check_cnthctl_el1nvvct(struct kvm_vcpu *vcpu)
+{
+       if (!is_nested_nv2_guest(vcpu) ||
+           !(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVVCT))
+               return BEHAVE_HANDLE_LOCALLY;
+
+       return BEHAVE_FORWARD_RW;
+}
+
 static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
 {
        u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
@@ -534,6 +577,8 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
 static const complex_condition_check ccc[] = {
        CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
        CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
+       CCC(CGT_CNTHCTL_EL1NVPCT, check_cnthctl_el1nvpct),
+       CCC(CGT_CNTHCTL_EL1NVVCT, check_cnthctl_el1nvvct),
        CCC(CGT_CPTR_TTA, check_cptr_tta),
        CCC(CGT_MDCR_HPMN, check_mdcr_hpmn),
 };
@@ -850,11 +895,15 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
                      SYS_CNTHP_CVAL_EL2, CGT_HCR_NV),
        SR_RANGE_TRAP(SYS_CNTHV_TVAL_EL2,
                      SYS_CNTHV_CVAL_EL2, CGT_HCR_NV),
-       /* All _EL02, _EL12 registers */
+       /* All _EL02, _EL12 registers up to CNTKCTL_EL12*/
        SR_RANGE_TRAP(sys_reg(3, 5, 0, 0, 0),
                      sys_reg(3, 5, 10, 15, 7), CGT_HCR_NV),
        SR_RANGE_TRAP(sys_reg(3, 5, 12, 0, 0),
-                     sys_reg(3, 5, 14, 15, 7), CGT_HCR_NV),
+                     sys_reg(3, 5, 14, 1, 0), CGT_HCR_NV),
+       SR_TRAP(SYS_CNTP_CTL_EL02,      CGT_CNTHCTL_EL1NVPCT),
+       SR_TRAP(SYS_CNTP_CVAL_EL02,     CGT_CNTHCTL_EL1NVPCT),
+       SR_TRAP(SYS_CNTV_CTL_EL02,      CGT_CNTHCTL_EL1NVVCT),
+       SR_TRAP(SYS_CNTV_CVAL_EL02,     CGT_CNTHCTL_EL1NVVCT),
        SR_TRAP(OP_AT_S1E2R,            CGT_HCR_NV),
        SR_TRAP(OP_AT_S1E2W,            CGT_HCR_NV),
        SR_TRAP(OP_AT_S12E1R,           CGT_HCR_NV),
@@ -1184,6 +1233,11 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
        SR_TRAP(SYS_CNTP_CTL_EL0,       CGT_CNTHCTL_EL1PTEN),
        SR_TRAP(SYS_CNTPCT_EL0,         CGT_CNTHCTL_EL1PCTEN),
        SR_TRAP(SYS_CNTPCTSS_EL0,       CGT_CNTHCTL_EL1PCTEN),
+       SR_TRAP(SYS_CNTV_TVAL_EL0,      CGT_CNTHCTL_EL1TVT),
+       SR_TRAP(SYS_CNTV_CVAL_EL0,      CGT_CNTHCTL_EL1TVT),
+       SR_TRAP(SYS_CNTV_CTL_EL0,       CGT_CNTHCTL_EL1TVT),
+       SR_TRAP(SYS_CNTVCT_EL0,         CGT_CNTHCTL_EL1TVCT),
+       SR_TRAP(SYS_CNTVCTSS_EL0,       CGT_CNTHCTL_EL1TVCT),
        SR_TRAP(SYS_FPMR,               CGT_HCRX_EnFPM),
        /*
         * IMPDEF choice: