@@ -66,7 +66,6 @@ struct reg_bits_to_feat_map {
6666#define FEAT_BRBE ID_AA64DFR0_EL1, BRBE, IMP
6767#define FEAT_TRC_SR ID_AA64DFR0_EL1, TraceVer, IMP
6868#define FEAT_PMUv3 ID_AA64DFR0_EL1, PMUVer, IMP
69- #define FEAT_PMUv3p9 ID_AA64DFR0_EL1, PMUVer, V3P9
7069#define FEAT_TRBE ID_AA64DFR0_EL1, TraceBuffer, IMP
7170#define FEAT_TRBEv1p1 ID_AA64DFR0_EL1, TraceBuffer, TRBE_V1P1
7271#define FEAT_DoubleLock ID_AA64DFR0_EL1, DoubleLock, IMP
@@ -89,6 +88,7 @@ struct reg_bits_to_feat_map {
8988#define FEAT_RASv2 ID_AA64PFR0_EL1, RAS, V2
9089#define FEAT_GICv3 ID_AA64PFR0_EL1, GIC, IMP
9190#define FEAT_LOR ID_AA64MMFR1_EL1, LO, IMP
91+ #define FEAT_SPEv1p2 ID_AA64DFR0_EL1, PMSVer, V1P2
9292#define FEAT_SPEv1p4 ID_AA64DFR0_EL1, PMSVer, V1P4
9393#define FEAT_SPEv1p5 ID_AA64DFR0_EL1, PMSVer, V1P5
9494#define FEAT_ATS1A ID_AA64ISAR2_EL1, ATS1A, IMP
@@ -133,6 +133,25 @@ struct reg_bits_to_feat_map {
133133#define FEAT_STEP2 ID_AA64DFR2_EL1, STEP, IMP
134134#define FEAT_SYSREG128 ID_AA64ISAR2_EL1, SYSREG_128, IMP
135135#define FEAT_CPA2 ID_AA64ISAR3_EL1, CPA, CPA2
136+ #define FEAT_ASID2 ID_AA64MMFR4_EL1, ASID2, IMP
137+ #define FEAT_MEC ID_AA64MMFR3_EL1, MEC, IMP
138+ #define FEAT_HAFT ID_AA64MMFR1_EL1, HAFDBS, HAFT
139+ #define FEAT_BTI ID_AA64PFR1_EL1, BT, IMP
140+ #define FEAT_ExS ID_AA64MMFR0_EL1, EXS, IMP
141+ #define FEAT_IESB ID_AA64MMFR2_EL1, IESB, IMP
142+ #define FEAT_LSE2 ID_AA64MMFR2_EL1, AT, IMP
143+ #define FEAT_LSMAOC ID_AA64MMFR2_EL1, LSM, IMP
144+ #define FEAT_MixedEnd ID_AA64MMFR0_EL1, BIGEND, IMP
145+ #define FEAT_MixedEndEL0 ID_AA64MMFR0_EL1, BIGENDEL0, IMP
146+ #define FEAT_MTE2 ID_AA64PFR1_EL1, MTE, MTE2
147+ #define FEAT_MTE_ASYNC ID_AA64PFR1_EL1, MTE_frac, ASYNC
148+ #define FEAT_MTE_STORE_ONLY ID_AA64PFR2_EL1, MTESTOREONLY, IMP
149+ #define FEAT_PAN ID_AA64MMFR1_EL1, PAN, IMP
150+ #define FEAT_PAN3 ID_AA64MMFR1_EL1, PAN, PAN3
151+ #define FEAT_SSBS ID_AA64PFR1_EL1, SSBS, IMP
152+ #define FEAT_TIDCP1 ID_AA64MMFR1_EL1, TIDCP1, IMP
153+ #define FEAT_FGT ID_AA64MMFR0_EL1, FGT, IMP
154+ #define FEAT_MTPMU ID_AA64DFR0_EL1, MTPMU, IMP
136155
137156static bool not_feat_aa64el3 (struct kvm * kvm )
138157{
@@ -220,11 +239,62 @@ static bool feat_trbe_mpam(struct kvm *kvm)
220239 (read_sysreg_s (SYS_TRBIDR_EL1 ) & TRBIDR_EL1_MPAM ));
221240}
222241
242+ static bool feat_asid2_e2h1 (struct kvm * kvm )
243+ {
244+ return kvm_has_feat (kvm , FEAT_ASID2 ) && !kvm_has_feat (kvm , FEAT_E2H0 );
245+ }
246+
247+ static bool feat_d128_e2h1 (struct kvm * kvm )
248+ {
249+ return kvm_has_feat (kvm , FEAT_D128 ) && !kvm_has_feat (kvm , FEAT_E2H0 );
250+ }
251+
252+ static bool feat_mec_e2h1 (struct kvm * kvm )
253+ {
254+ return kvm_has_feat (kvm , FEAT_MEC ) && !kvm_has_feat (kvm , FEAT_E2H0 );
255+ }
256+
223257static bool feat_ebep_pmuv3_ss (struct kvm * kvm )
224258{
225259 return kvm_has_feat (kvm , FEAT_EBEP ) || kvm_has_feat (kvm , FEAT_PMUv3_SS );
226260}
227261
262+ static bool feat_mixedendel0 (struct kvm * kvm )
263+ {
264+ return kvm_has_feat (kvm , FEAT_MixedEnd ) || kvm_has_feat (kvm , FEAT_MixedEndEL0 );
265+ }
266+
267+ static bool feat_mte_async (struct kvm * kvm )
268+ {
269+ return kvm_has_feat (kvm , FEAT_MTE2 ) && kvm_has_feat_enum (kvm , FEAT_MTE_ASYNC );
270+ }
271+
272+ #define check_pmu_revision (k , r ) \
273+ ({ \
274+ (kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, r) && \
275+ !kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, IMP_DEF)); \
276+ })
277+
278+ static bool feat_pmuv3p1 (struct kvm * kvm )
279+ {
280+ return check_pmu_revision (kvm , V3P1 );
281+ }
282+
283+ static bool feat_pmuv3p5 (struct kvm * kvm )
284+ {
285+ return check_pmu_revision (kvm , V3P5 );
286+ }
287+
288+ static bool feat_pmuv3p7 (struct kvm * kvm )
289+ {
290+ return check_pmu_revision (kvm , V3P7 );
291+ }
292+
293+ static bool feat_pmuv3p9 (struct kvm * kvm )
294+ {
295+ return check_pmu_revision (kvm , V3P9 );
296+ }
297+
228298static bool compute_hcr_rw (struct kvm * kvm , u64 * bits )
229299{
230300 /* This is purely academic: AArch32 and NV are mutually exclusive */
@@ -683,7 +753,7 @@ static const struct reg_bits_to_feat_map hdfgrtr2_feat_map[] = {
683753 NEEDS_FEAT (HDFGRTR2_EL2_nPMICFILTR_EL0 |
684754 HDFGRTR2_EL2_nPMICNTR_EL0 ,
685755 FEAT_PMUv3_ICNTR ),
686- NEEDS_FEAT (HDFGRTR2_EL2_nPMUACR_EL1 , FEAT_PMUv3p9 ),
756+ NEEDS_FEAT (HDFGRTR2_EL2_nPMUACR_EL1 , feat_pmuv3p9 ),
687757 NEEDS_FEAT (HDFGRTR2_EL2_nPMSSCR_EL1 |
688758 HDFGRTR2_EL2_nPMSSDATA ,
689759 FEAT_PMUv3_SS ),
@@ -715,7 +785,7 @@ static const struct reg_bits_to_feat_map hdfgwtr2_feat_map[] = {
715785 FEAT_PMUv3_ICNTR ),
716786 NEEDS_FEAT (HDFGWTR2_EL2_nPMUACR_EL1 |
717787 HDFGWTR2_EL2_nPMZR_EL0 ,
718- FEAT_PMUv3p9 ),
788+ feat_pmuv3p9 ),
719789 NEEDS_FEAT (HDFGWTR2_EL2_nPMSSCR_EL1 , FEAT_PMUv3_SS ),
720790 NEEDS_FEAT (HDFGWTR2_EL2_nPMIAR_EL1 , FEAT_SEBEP ),
721791 NEEDS_FEAT (HDFGWTR2_EL2_nPMSDSFR_EL1 , feat_spe_fds ),
@@ -851,6 +921,133 @@ static const struct reg_bits_to_feat_map sctlr2_feat_map[] = {
851921 FEAT_CPA2 ),
852922};
853923
924+ static const struct reg_bits_to_feat_map tcr2_el2_feat_map [] = {
925+ NEEDS_FEAT (TCR2_EL2_FNG1 |
926+ TCR2_EL2_FNG0 |
927+ TCR2_EL2_A2 ,
928+ feat_asid2_e2h1 ),
929+ NEEDS_FEAT (TCR2_EL2_DisCH1 |
930+ TCR2_EL2_DisCH0 |
931+ TCR2_EL2_D128 ,
932+ feat_d128_e2h1 ),
933+ NEEDS_FEAT (TCR2_EL2_AMEC1 , feat_mec_e2h1 ),
934+ NEEDS_FEAT (TCR2_EL2_AMEC0 , FEAT_MEC ),
935+ NEEDS_FEAT (TCR2_EL2_HAFT , FEAT_HAFT ),
936+ NEEDS_FEAT (TCR2_EL2_PTTWI |
937+ TCR2_EL2_PnCH ,
938+ FEAT_THE ),
939+ NEEDS_FEAT (TCR2_EL2_AIE , FEAT_AIE ),
940+ NEEDS_FEAT (TCR2_EL2_POE |
941+ TCR2_EL2_E0POE ,
942+ FEAT_S1POE ),
943+ NEEDS_FEAT (TCR2_EL2_PIE , FEAT_S1PIE ),
944+ };
945+
946+ static const struct reg_bits_to_feat_map sctlr_el1_feat_map [] = {
947+ NEEDS_FEAT (SCTLR_EL1_CP15BEN |
948+ SCTLR_EL1_ITD |
949+ SCTLR_EL1_SED ,
950+ FEAT_AA32EL0 ),
951+ NEEDS_FEAT (SCTLR_EL1_BT0 |
952+ SCTLR_EL1_BT1 ,
953+ FEAT_BTI ),
954+ NEEDS_FEAT (SCTLR_EL1_CMOW , FEAT_CMOW ),
955+ NEEDS_FEAT (SCTLR_EL1_TSCXT , feat_csv2_2_csv2_1p2 ),
956+ NEEDS_FEAT (SCTLR_EL1_EIS |
957+ SCTLR_EL1_EOS ,
958+ FEAT_ExS ),
959+ NEEDS_FEAT (SCTLR_EL1_EnFPM , FEAT_FPMR ),
960+ NEEDS_FEAT (SCTLR_EL1_IESB , FEAT_IESB ),
961+ NEEDS_FEAT (SCTLR_EL1_EnALS , FEAT_LS64 ),
962+ NEEDS_FEAT (SCTLR_EL1_EnAS0 , FEAT_LS64_ACCDATA ),
963+ NEEDS_FEAT (SCTLR_EL1_EnASR , FEAT_LS64_V ),
964+ NEEDS_FEAT (SCTLR_EL1_nAA , FEAT_LSE2 ),
965+ NEEDS_FEAT (SCTLR_EL1_LSMAOE |
966+ SCTLR_EL1_nTLSMD ,
967+ FEAT_LSMAOC ),
968+ NEEDS_FEAT (SCTLR_EL1_EE , FEAT_MixedEnd ),
969+ NEEDS_FEAT (SCTLR_EL1_E0E , feat_mixedendel0 ),
970+ NEEDS_FEAT (SCTLR_EL1_MSCEn , FEAT_MOPS ),
971+ NEEDS_FEAT (SCTLR_EL1_ATA0 |
972+ SCTLR_EL1_ATA |
973+ SCTLR_EL1_TCF0 |
974+ SCTLR_EL1_TCF ,
975+ FEAT_MTE2 ),
976+ NEEDS_FEAT (SCTLR_EL1_ITFSB , feat_mte_async ),
977+ NEEDS_FEAT (SCTLR_EL1_TCSO0 |
978+ SCTLR_EL1_TCSO ,
979+ FEAT_MTE_STORE_ONLY ),
980+ NEEDS_FEAT (SCTLR_EL1_NMI |
981+ SCTLR_EL1_SPINTMASK ,
982+ FEAT_NMI ),
983+ NEEDS_FEAT (SCTLR_EL1_SPAN , FEAT_PAN ),
984+ NEEDS_FEAT (SCTLR_EL1_EPAN , FEAT_PAN3 ),
985+ NEEDS_FEAT (SCTLR_EL1_EnDA |
986+ SCTLR_EL1_EnDB |
987+ SCTLR_EL1_EnIA |
988+ SCTLR_EL1_EnIB ,
989+ feat_pauth ),
990+ NEEDS_FEAT (SCTLR_EL1_EnTP2 , FEAT_SME ),
991+ NEEDS_FEAT (SCTLR_EL1_EnRCTX , FEAT_SPECRES ),
992+ NEEDS_FEAT (SCTLR_EL1_DSSBS , FEAT_SSBS ),
993+ NEEDS_FEAT (SCTLR_EL1_TIDCP , FEAT_TIDCP1 ),
994+ NEEDS_FEAT (SCTLR_EL1_TME0 |
995+ SCTLR_EL1_TME |
996+ SCTLR_EL1_TMT0 |
997+ SCTLR_EL1_TMT ,
998+ FEAT_TME ),
999+ NEEDS_FEAT (SCTLR_EL1_TWEDEL |
1000+ SCTLR_EL1_TWEDEn ,
1001+ FEAT_TWED ),
1002+ NEEDS_FEAT (SCTLR_EL1_UCI |
1003+ SCTLR_EL1_EE |
1004+ SCTLR_EL1_E0E |
1005+ SCTLR_EL1_WXN |
1006+ SCTLR_EL1_nTWE |
1007+ SCTLR_EL1_nTWI |
1008+ SCTLR_EL1_UCT |
1009+ SCTLR_EL1_DZE |
1010+ SCTLR_EL1_I |
1011+ SCTLR_EL1_UMA |
1012+ SCTLR_EL1_SA0 |
1013+ SCTLR_EL1_SA |
1014+ SCTLR_EL1_C |
1015+ SCTLR_EL1_A |
1016+ SCTLR_EL1_M ,
1017+ FEAT_AA64EL1 ),
1018+ };
1019+
1020+ static const struct reg_bits_to_feat_map mdcr_el2_feat_map [] = {
1021+ NEEDS_FEAT (MDCR_EL2_EBWE , FEAT_Debugv8p9 ),
1022+ NEEDS_FEAT (MDCR_EL2_TDOSA , FEAT_DoubleLock ),
1023+ NEEDS_FEAT (MDCR_EL2_PMEE , FEAT_EBEP ),
1024+ NEEDS_FEAT (MDCR_EL2_TDCC , FEAT_FGT ),
1025+ NEEDS_FEAT (MDCR_EL2_MTPME , FEAT_MTPMU ),
1026+ NEEDS_FEAT (MDCR_EL2_HPME |
1027+ MDCR_EL2_HPMN |
1028+ MDCR_EL2_TPMCR |
1029+ MDCR_EL2_TPM ,
1030+ FEAT_PMUv3 ),
1031+ NEEDS_FEAT (MDCR_EL2_HPMD , feat_pmuv3p1 ),
1032+ NEEDS_FEAT (MDCR_EL2_HCCD |
1033+ MDCR_EL2_HLP ,
1034+ feat_pmuv3p5 ),
1035+ NEEDS_FEAT (MDCR_EL2_HPMFZO , feat_pmuv3p7 ),
1036+ NEEDS_FEAT (MDCR_EL2_PMSSE , FEAT_PMUv3_SS ),
1037+ NEEDS_FEAT (MDCR_EL2_E2PB |
1038+ MDCR_EL2_TPMS ,
1039+ FEAT_SPE ),
1040+ NEEDS_FEAT (MDCR_EL2_HPMFZS , FEAT_SPEv1p2 ),
1041+ NEEDS_FEAT (MDCR_EL2_EnSPM , FEAT_SPMU ),
1042+ NEEDS_FEAT (MDCR_EL2_EnSTEPOP , FEAT_STEP2 ),
1043+ NEEDS_FEAT (MDCR_EL2_E2TB , FEAT_TRBE ),
1044+ NEEDS_FEAT (MDCR_EL2_TTRF , FEAT_TRF ),
1045+ NEEDS_FEAT (MDCR_EL2_TDA |
1046+ MDCR_EL2_TDE |
1047+ MDCR_EL2_TDRA ,
1048+ FEAT_AA64EL1 ),
1049+ };
1050+
8541051static void __init check_feat_map (const struct reg_bits_to_feat_map * map ,
8551052 int map_size , u64 res0 , const char * str )
8561053{
@@ -884,6 +1081,12 @@ void __init check_feature_map(void)
8841081 HCR_EL2_RES0 , "HCR_EL2" );
8851082 check_feat_map (sctlr2_feat_map , ARRAY_SIZE (sctlr2_feat_map ),
8861083 SCTLR2_EL1_RES0 , "SCTLR2_EL1" );
1084+ check_feat_map (tcr2_el2_feat_map , ARRAY_SIZE (tcr2_el2_feat_map ),
1085+ TCR2_EL2_RES0 , "TCR2_EL2" );
1086+ check_feat_map (sctlr_el1_feat_map , ARRAY_SIZE (sctlr_el1_feat_map ),
1087+ SCTLR_EL1_RES0 , "SCTLR_EL1" );
1088+ check_feat_map (mdcr_el2_feat_map , ARRAY_SIZE (mdcr_el2_feat_map ),
1089+ MDCR_EL2_RES0 , "MDCR_EL2" );
8871090}
8881091
8891092static bool idreg_feat_match (struct kvm * kvm , const struct reg_bits_to_feat_map * map )
@@ -1105,6 +1308,24 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
11051308 * res0 |= SCTLR2_EL1_RES0 ;
11061309 * res1 = SCTLR2_EL1_RES1 ;
11071310 break ;
1311+ case TCR2_EL2 :
1312+ * res0 = compute_res0_bits (kvm , tcr2_el2_feat_map ,
1313+ ARRAY_SIZE (tcr2_el2_feat_map ), 0 , 0 );
1314+ * res0 |= TCR2_EL2_RES0 ;
1315+ * res1 = TCR2_EL2_RES1 ;
1316+ break ;
1317+ case SCTLR_EL1 :
1318+ * res0 = compute_res0_bits (kvm , sctlr_el1_feat_map ,
1319+ ARRAY_SIZE (sctlr_el1_feat_map ), 0 , 0 );
1320+ * res0 |= SCTLR_EL1_RES0 ;
1321+ * res1 = SCTLR_EL1_RES1 ;
1322+ break ;
1323+ case MDCR_EL2 :
1324+ * res0 = compute_res0_bits (kvm , mdcr_el2_feat_map ,
1325+ ARRAY_SIZE (mdcr_el2_feat_map ), 0 , 0 );
1326+ * res0 |= MDCR_EL2_RES0 ;
1327+ * res1 = MDCR_EL2_RES1 ;
1328+ break ;
11081329 default :
11091330 WARN_ON_ONCE (1 );
11101331 * res0 = * res1 = 0 ;
0 commit comments