]> www.infradead.org Git - nvme.git/commitdiff
KVM: arm64: nv: Add trap description for CPTR_EL2
authorMarc Zyngier <maz@kernel.org>
Thu, 20 Jun 2024 16:46:50 +0000 (16:46 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Thu, 20 Jun 2024 19:04:49 +0000 (19:04 +0000)
Add trap description for CPTR_EL2.{TCPAC,TAM,E0POE,TTA}.

TTA is a bit annoying as it changes location depending on E2H.
This forces us to add yet another "complex" trap condition.

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

index 54090967a33567008da56b9fbef6dd6711756a09..96b837fe515624863b777b2d2de804031b1cd386 100644 (file)
@@ -79,6 +79,10 @@ enum cgt_group_id {
        CGT_MDCR_E2TB,
        CGT_MDCR_TDCC,
 
+       CGT_CPACR_E0POE,
+       CGT_CPTR_TAM,
+       CGT_CPTR_TCPAC,
+
        /*
         * Anything after this point is a combination of coarse trap
         * controls, which must all be evaluated to decide what to do.
@@ -106,6 +110,8 @@ enum cgt_group_id {
        CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
        CGT_CNTHCTL_EL1PTEN,
 
+       CGT_CPTR_TTA,
+
        /* Must be last */
        __NR_CGT_GROUP_IDS__
 };
@@ -345,6 +351,24 @@ static const struct trap_bits coarse_trap_bits[] = {
                .mask           = MDCR_EL2_TDCC,
                .behaviour      = BEHAVE_FORWARD_ANY,
        },
+       [CGT_CPACR_E0POE] = {
+               .index          = CPTR_EL2,
+               .value          = CPACR_ELx_E0POE,
+               .mask           = CPACR_ELx_E0POE,
+               .behaviour      = BEHAVE_FORWARD_ANY,
+       },
+       [CGT_CPTR_TAM] = {
+               .index          = CPTR_EL2,
+               .value          = CPTR_EL2_TAM,
+               .mask           = CPTR_EL2_TAM,
+               .behaviour      = BEHAVE_FORWARD_ANY,
+       },
+       [CGT_CPTR_TCPAC] = {
+               .index          = CPTR_EL2,
+               .value          = CPTR_EL2_TCPAC,
+               .mask           = CPTR_EL2_TCPAC,
+               .behaviour      = BEHAVE_FORWARD_ANY,
+       },
 };
 
 #define MCB(id, ...)                                           \
@@ -410,12 +434,26 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
        return BEHAVE_FORWARD_ANY;
 }
 
+static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
+{
+       u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
+
+       if (!vcpu_el2_e2h_is_set(vcpu))
+               val = translate_cptr_el2_to_cpacr_el1(val);
+
+       if (val & CPACR_ELx_TTA)
+               return BEHAVE_FORWARD_ANY;
+
+       return BEHAVE_HANDLE_LOCALLY;
+}
+
 #define CCC(id, fn)                            \
        [id - __COMPLEX_CONDITIONS__] = fn
 
 static const complex_condition_check ccc[] = {
        CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
        CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
+       CCC(CGT_CPTR_TTA, check_cptr_tta),
 };
 
 /*
@@ -1000,6 +1038,59 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
        SR_TRAP(SYS_TRBPTR_EL1,         CGT_MDCR_E2TB),
        SR_TRAP(SYS_TRBSR_EL1,          CGT_MDCR_E2TB),
        SR_TRAP(SYS_TRBTRG_EL1,         CGT_MDCR_E2TB),
+       SR_TRAP(SYS_CPACR_EL1,          CGT_CPTR_TCPAC),
+       SR_TRAP(SYS_AMUSERENR_EL0,      CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCFGR_EL0,         CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCGCR_EL0,         CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCNTENCLR0_EL0,    CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCNTENCLR1_EL0,    CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCNTENSET0_EL0,    CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCNTENSET1_EL0,    CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMCR_EL0,           CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR0_EL0(0),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR0_EL0(1),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR0_EL0(2),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR0_EL0(3),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(0),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(1),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(2),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(3),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(4),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(5),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(6),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(7),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(8),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(9),   CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(10),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(11),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(12),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(13),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(14),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVCNTR1_EL0(15),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER0_EL0(0),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER0_EL0(1),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER0_EL0(2),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER0_EL0(3),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(0),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(1),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(2),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(3),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(4),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(5),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(6),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(7),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(8),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(9),  CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(10), CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(11), CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(12), CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(13), CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(14), CGT_CPTR_TAM),
+       SR_TRAP(SYS_AMEVTYPER1_EL0(15), CGT_CPTR_TAM),
+       SR_TRAP(SYS_POR_EL0,            CGT_CPACR_E0POE),
+       /* op0=2, op1=1, and CRn<0b1000 */
+       SR_RANGE_TRAP(sys_reg(2, 1, 0, 0, 0),
+                     sys_reg(2, 1, 7, 15, 7), CGT_CPTR_TTA),
        SR_TRAP(SYS_CNTP_TVAL_EL0,      CGT_CNTHCTL_EL1PTEN),
        SR_TRAP(SYS_CNTP_CVAL_EL0,      CGT_CNTHCTL_EL1PTEN),
        SR_TRAP(SYS_CNTP_CTL_EL0,       CGT_CNTHCTL_EL1PTEN),