@@ -89,6 +89,7 @@ struct reg_bits_to_feat_map {
8989#define FEAT_RASv2 ID_AA64PFR0_EL1, RAS, V2
9090#define FEAT_GICv3 ID_AA64PFR0_EL1, GIC, IMP
9191#define FEAT_LOR ID_AA64MMFR1_EL1, LO, IMP
92+ #define FEAT_SPEv1p2 ID_AA64DFR0_EL1, PMSVer, V1P2
9293#define FEAT_SPEv1p4 ID_AA64DFR0_EL1, PMSVer, V1P4
9394#define FEAT_SPEv1p5 ID_AA64DFR0_EL1, PMSVer, V1P5
9495#define FEAT_ATS1A ID_AA64ISAR2_EL1, ATS1A, IMP
@@ -148,6 +149,8 @@ struct reg_bits_to_feat_map {
148149#define FEAT_PAN3 ID_AA64MMFR1_EL1, PAN, PAN3
149150#define FEAT_SSBS ID_AA64PFR1_EL1, SSBS, IMP
150151#define FEAT_TIDCP1 ID_AA64MMFR1_EL1, TIDCP1, IMP
152+ #define FEAT_FGT ID_AA64MMFR0_EL1, FGT, IMP
153+ #define FEAT_MTPMU ID_AA64DFR0_EL1, MTPMU, IMP
151154
152155static bool not_feat_aa64el3 (struct kvm * kvm )
153156{
@@ -265,6 +268,27 @@ static bool feat_mte_async(struct kvm *kvm)
265268 return kvm_has_feat (kvm , FEAT_MTE2 ) && kvm_has_feat_enum (kvm , FEAT_MTE_ASYNC );
266269}
267270
271+ #define check_pmu_revision (k , r ) \
272+ ({ \
273+ (kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, r) && \
274+ !kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, IMP_DEF)); \
275+ })
276+
277+ static bool feat_pmuv3p1 (struct kvm * kvm )
278+ {
279+ return check_pmu_revision (kvm , V3P1 );
280+ }
281+
282+ static bool feat_pmuv3p5 (struct kvm * kvm )
283+ {
284+ return check_pmu_revision (kvm , V3P5 );
285+ }
286+
287+ static bool feat_pmuv3p7 (struct kvm * kvm )
288+ {
289+ return check_pmu_revision (kvm , V3P7 );
290+ }
291+
268292static bool compute_hcr_rw (struct kvm * kvm , u64 * bits )
269293{
270294 /* This is purely academic: AArch32 and NV are mutually exclusive */
@@ -970,6 +994,37 @@ static const struct reg_bits_to_feat_map sctlr_el1_feat_map[] = {
970994 FEAT_AA64EL1 ),
971995};
972996
997+ static const struct reg_bits_to_feat_map mdcr_el2_feat_map [] = {
998+ NEEDS_FEAT (MDCR_EL2_EBWE , FEAT_Debugv8p9 ),
999+ NEEDS_FEAT (MDCR_EL2_TDOSA , FEAT_DoubleLock ),
1000+ NEEDS_FEAT (MDCR_EL2_PMEE , FEAT_EBEP ),
1001+ NEEDS_FEAT (MDCR_EL2_TDCC , FEAT_FGT ),
1002+ NEEDS_FEAT (MDCR_EL2_MTPME , FEAT_MTPMU ),
1003+ NEEDS_FEAT (MDCR_EL2_HPME |
1004+ MDCR_EL2_HPMN |
1005+ MDCR_EL2_TPMCR |
1006+ MDCR_EL2_TPM ,
1007+ FEAT_PMUv3 ),
1008+ NEEDS_FEAT (MDCR_EL2_HPMD , feat_pmuv3p1 ),
1009+ NEEDS_FEAT (MDCR_EL2_HCCD |
1010+ MDCR_EL2_HLP ,
1011+ feat_pmuv3p5 ),
1012+ NEEDS_FEAT (MDCR_EL2_HPMFZO , feat_pmuv3p7 ),
1013+ NEEDS_FEAT (MDCR_EL2_PMSSE , FEAT_PMUv3_SS ),
1014+ NEEDS_FEAT (MDCR_EL2_E2PB |
1015+ MDCR_EL2_TPMS ,
1016+ FEAT_SPE ),
1017+ NEEDS_FEAT (MDCR_EL2_HPMFZS , FEAT_SPEv1p2 ),
1018+ NEEDS_FEAT (MDCR_EL2_EnSPM , FEAT_SPMU ),
1019+ NEEDS_FEAT (MDCR_EL2_EnSTEPOP , FEAT_STEP2 ),
1020+ NEEDS_FEAT (MDCR_EL2_E2TB , FEAT_TRBE ),
1021+ NEEDS_FEAT (MDCR_EL2_TTRF , FEAT_TRF ),
1022+ NEEDS_FEAT (MDCR_EL2_TDA |
1023+ MDCR_EL2_TDE |
1024+ MDCR_EL2_TDRA ,
1025+ FEAT_AA64EL1 ),
1026+ };
1027+
9731028static void __init check_feat_map (const struct reg_bits_to_feat_map * map ,
9741029 int map_size , u64 res0 , const char * str )
9751030{
@@ -1005,6 +1060,8 @@ void __init check_feature_map(void)
10051060 TCR2_EL2_RES0 , "TCR2_EL2" );
10061061 check_feat_map (sctlr_el1_feat_map , ARRAY_SIZE (sctlr_el1_feat_map ),
10071062 SCTLR_EL1_RES0 , "SCTLR_EL1" );
1063+ check_feat_map (mdcr_el2_feat_map , ARRAY_SIZE (mdcr_el2_feat_map ),
1064+ MDCR_EL2_RES0 , "MDCR_EL2" );
10081065}
10091066
10101067static bool idreg_feat_match (struct kvm * kvm , const struct reg_bits_to_feat_map * map )
@@ -1231,6 +1288,12 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
12311288 * res0 |= SCTLR_EL1_RES0 ;
12321289 * res1 = SCTLR_EL1_RES1 ;
12331290 break ;
1291+ case MDCR_EL2 :
1292+ * res0 = compute_res0_bits (kvm , mdcr_el2_feat_map ,
1293+ ARRAY_SIZE (mdcr_el2_feat_map ), 0 , 0 );
1294+ * res0 |= MDCR_EL2_RES0 ;
1295+ * res1 = MDCR_EL2_RES1 ;
1296+ break ;
12341297 default :
12351298 WARN_ON_ONCE (1 );
12361299 * res0 = * res1 = 0 ;
0 commit comments