@@ -134,6 +134,20 @@ struct reg_bits_to_feat_map {
134134#define FEAT_ASID2 ID_AA64MMFR4_EL1, ASID2, IMP
135135#define FEAT_MEC ID_AA64MMFR3_EL1, MEC, IMP
136136#define FEAT_HAFT ID_AA64MMFR1_EL1, HAFDBS, HAFT
137+ #define FEAT_BTI ID_AA64PFR1_EL1, BT, IMP
138+ #define FEAT_ExS ID_AA64MMFR0_EL1, EXS, IMP
139+ #define FEAT_IESB ID_AA64MMFR2_EL1, IESB, IMP
140+ #define FEAT_LSE2 ID_AA64MMFR2_EL1, AT, IMP
141+ #define FEAT_LSMAOC ID_AA64MMFR2_EL1, LSM, IMP
142+ #define FEAT_MixedEnd ID_AA64MMFR0_EL1, BIGEND, IMP
143+ #define FEAT_MixedEndEL0 ID_AA64MMFR0_EL1, BIGENDEL0, IMP
144+ #define FEAT_MTE2 ID_AA64PFR1_EL1, MTE, MTE2
145+ #define FEAT_MTE_ASYNC ID_AA64PFR1_EL1, MTE_frac, ASYNC
146+ #define FEAT_MTE_STORE_ONLY ID_AA64PFR2_EL1, MTESTOREONLY, IMP
147+ #define FEAT_PAN ID_AA64MMFR1_EL1, PAN, IMP
148+ #define FEAT_PAN3 ID_AA64MMFR1_EL1, PAN, PAN3
149+ #define FEAT_SSBS ID_AA64PFR1_EL1, SSBS, IMP
150+ #define FEAT_TIDCP1 ID_AA64MMFR1_EL1, TIDCP1, IMP
137151
138152static bool not_feat_aa64el3 (struct kvm * kvm )
139153{
@@ -241,6 +255,16 @@ static bool feat_ebep_pmuv3_ss(struct kvm *kvm)
241255 return kvm_has_feat (kvm , FEAT_EBEP ) || kvm_has_feat (kvm , FEAT_PMUv3_SS );
242256}
243257
258+ static bool feat_mixedendel0 (struct kvm * kvm )
259+ {
260+ return kvm_has_feat (kvm , FEAT_MixedEnd ) || kvm_has_feat (kvm , FEAT_MixedEndEL0 );
261+ }
262+
263+ static bool feat_mte_async (struct kvm * kvm )
264+ {
265+ return kvm_has_feat (kvm , FEAT_MTE2 ) && kvm_has_feat_enum (kvm , FEAT_MTE_ASYNC );
266+ }
267+
244268static bool compute_hcr_rw (struct kvm * kvm , u64 * bits )
245269{
246270 /* This is purely academic: AArch32 and NV are mutually exclusive */
@@ -872,6 +896,80 @@ static const struct reg_bits_to_feat_map tcr2_el2_feat_map[] = {
872896 NEEDS_FEAT (TCR2_EL2_PIE , FEAT_S1PIE ),
873897};
874898
899+ static const struct reg_bits_to_feat_map sctlr_el1_feat_map [] = {
900+ NEEDS_FEAT (SCTLR_EL1_CP15BEN |
901+ SCTLR_EL1_ITD |
902+ SCTLR_EL1_SED ,
903+ FEAT_AA32EL0 ),
904+ NEEDS_FEAT (SCTLR_EL1_BT0 |
905+ SCTLR_EL1_BT1 ,
906+ FEAT_BTI ),
907+ NEEDS_FEAT (SCTLR_EL1_CMOW , FEAT_CMOW ),
908+ NEEDS_FEAT (SCTLR_EL1_TSCXT , feat_csv2_2_csv2_1p2 ),
909+ NEEDS_FEAT (SCTLR_EL1_EIS |
910+ SCTLR_EL1_EOS ,
911+ FEAT_ExS ),
912+ NEEDS_FEAT (SCTLR_EL1_EnFPM , FEAT_FPMR ),
913+ NEEDS_FEAT (SCTLR_EL1_IESB , FEAT_IESB ),
914+ NEEDS_FEAT (SCTLR_EL1_EnALS , FEAT_LS64 ),
915+ NEEDS_FEAT (SCTLR_EL1_EnAS0 , FEAT_LS64_ACCDATA ),
916+ NEEDS_FEAT (SCTLR_EL1_EnASR , FEAT_LS64_V ),
917+ NEEDS_FEAT (SCTLR_EL1_nAA , FEAT_LSE2 ),
918+ NEEDS_FEAT (SCTLR_EL1_LSMAOE |
919+ SCTLR_EL1_nTLSMD ,
920+ FEAT_LSMAOC ),
921+ NEEDS_FEAT (SCTLR_EL1_EE , FEAT_MixedEnd ),
922+ NEEDS_FEAT (SCTLR_EL1_E0E , feat_mixedendel0 ),
923+ NEEDS_FEAT (SCTLR_EL1_MSCEn , FEAT_MOPS ),
924+ NEEDS_FEAT (SCTLR_EL1_ATA0 |
925+ SCTLR_EL1_ATA |
926+ SCTLR_EL1_TCF0 |
927+ SCTLR_EL1_TCF ,
928+ FEAT_MTE2 ),
929+ NEEDS_FEAT (SCTLR_EL1_ITFSB , feat_mte_async ),
930+ NEEDS_FEAT (SCTLR_EL1_TCSO0 |
931+ SCTLR_EL1_TCSO ,
932+ FEAT_MTE_STORE_ONLY ),
933+ NEEDS_FEAT (SCTLR_EL1_NMI |
934+ SCTLR_EL1_SPINTMASK ,
935+ FEAT_NMI ),
936+ NEEDS_FEAT (SCTLR_EL1_SPAN , FEAT_PAN ),
937+ NEEDS_FEAT (SCTLR_EL1_EPAN , FEAT_PAN3 ),
938+ NEEDS_FEAT (SCTLR_EL1_EnDA |
939+ SCTLR_EL1_EnDB |
940+ SCTLR_EL1_EnIA |
941+ SCTLR_EL1_EnIB ,
942+ feat_pauth ),
943+ NEEDS_FEAT (SCTLR_EL1_EnTP2 , FEAT_SME ),
944+ NEEDS_FEAT (SCTLR_EL1_EnRCTX , FEAT_SPECRES ),
945+ NEEDS_FEAT (SCTLR_EL1_DSSBS , FEAT_SSBS ),
946+ NEEDS_FEAT (SCTLR_EL1_TIDCP , FEAT_TIDCP1 ),
947+ NEEDS_FEAT (SCTLR_EL1_TME0 |
948+ SCTLR_EL1_TME |
949+ SCTLR_EL1_TMT0 |
950+ SCTLR_EL1_TMT ,
951+ FEAT_TME ),
952+ NEEDS_FEAT (SCTLR_EL1_TWEDEL |
953+ SCTLR_EL1_TWEDEn ,
954+ FEAT_TWED ),
955+ NEEDS_FEAT (SCTLR_EL1_UCI |
956+ SCTLR_EL1_EE |
957+ SCTLR_EL1_E0E |
958+ SCTLR_EL1_WXN |
959+ SCTLR_EL1_nTWE |
960+ SCTLR_EL1_nTWI |
961+ SCTLR_EL1_UCT |
962+ SCTLR_EL1_DZE |
963+ SCTLR_EL1_I |
964+ SCTLR_EL1_UMA |
965+ SCTLR_EL1_SA0 |
966+ SCTLR_EL1_SA |
967+ SCTLR_EL1_C |
968+ SCTLR_EL1_A |
969+ SCTLR_EL1_M ,
970+ FEAT_AA64EL1 ),
971+ };
972+
875973static void __init check_feat_map (const struct reg_bits_to_feat_map * map ,
876974 int map_size , u64 res0 , const char * str )
877975{
@@ -905,6 +1003,8 @@ void __init check_feature_map(void)
9051003 HCR_EL2_RES0 , "HCR_EL2" );
9061004 check_feat_map (tcr2_el2_feat_map , ARRAY_SIZE (tcr2_el2_feat_map ),
9071005 TCR2_EL2_RES0 , "TCR2_EL2" );
1006+ check_feat_map (sctlr_el1_feat_map , ARRAY_SIZE (sctlr_el1_feat_map ),
1007+ SCTLR_EL1_RES0 , "SCTLR_EL1" );
9081008}
9091009
9101010static bool idreg_feat_match (struct kvm * kvm , const struct reg_bits_to_feat_map * map )
@@ -1125,6 +1225,12 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
11251225 * res0 |= TCR2_EL2_RES0 ;
11261226 * res1 = TCR2_EL2_RES1 ;
11271227 break ;
1228+ case SCTLR_EL1 :
1229+ * res0 = compute_res0_bits (kvm , sctlr_el1_feat_map ,
1230+ ARRAY_SIZE (sctlr_el1_feat_map ), 0 , 0 );
1231+ * res0 |= SCTLR_EL1_RES0 ;
1232+ * res1 = SCTLR_EL1_RES1 ;
1233+ break ;
11281234 default :
11291235 WARN_ON_ONCE (1 );
11301236 * res0 = * res1 = 0 ;
0 commit comments