@@ -77,6 +77,8 @@ struct reg_bits_to_feat_map {
7777#define FEAT_THE ID_AA64PFR1_EL1, THE, IMP
7878#define FEAT_SME ID_AA64PFR1_EL1, SME, IMP
7979#define FEAT_GCS ID_AA64PFR1_EL1, GCS, IMP
80+ #define FEAT_LS64 ID_AA64ISAR1_EL1, LS64, LS64
81+ #define FEAT_LS64_V ID_AA64ISAR1_EL1, LS64, LS64_V
8082#define FEAT_LS64_ACCDATA ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA
8183#define FEAT_RAS ID_AA64PFR0_EL1, RAS, IMP
8284#define FEAT_GICv3 ID_AA64PFR0_EL1, GIC, IMP
@@ -90,6 +92,16 @@ struct reg_bits_to_feat_map {
9092#define FEAT_PAN2 ID_AA64MMFR1_EL1, PAN, PAN2
9193#define FEAT_DPB2 ID_AA64ISAR1_EL1, DPB, DPB2
9294#define FEAT_AMUv1 ID_AA64PFR0_EL1, AMU, IMP
95+ #define FEAT_CMOW ID_AA64MMFR1_EL1, CMOW, IMP
96+ #define FEAT_D128 ID_AA64MMFR3_EL1, D128, IMP
97+ #define FEAT_DoubleFault2 ID_AA64PFR1_EL1, DF2, IMP
98+ #define FEAT_FPMR ID_AA64PFR2_EL1, FPMR, IMP
99+ #define FEAT_MOPS ID_AA64ISAR2_EL1, MOPS, IMP
100+ #define FEAT_NMI ID_AA64PFR1_EL1, NMI, IMP
101+ #define FEAT_SCTLR2 ID_AA64MMFR3_EL1, SCTLRX, IMP
102+ #define FEAT_SYSREG128 ID_AA64ISAR2_EL1, SYSREG_128, IMP
103+ #define FEAT_TCR2 ID_AA64MMFR3_EL1, TCRX, IMP
104+ #define FEAT_XS ID_AA64ISAR1_EL1, XS, IMP
93105
94106static bool feat_rasv1p1 (struct kvm * kvm )
95107{
@@ -110,6 +122,35 @@ static bool feat_pauth(struct kvm *kvm)
110122 return kvm_has_pauth (kvm , PAuth );
111123}
112124
125+ static bool feat_pauth_lr (struct kvm * kvm )
126+ {
127+ return kvm_has_pauth (kvm , PAuth_LR );
128+ }
129+
130+ static bool feat_aderr (struct kvm * kvm )
131+ {
132+ return (kvm_has_feat (kvm , ID_AA64MMFR3_EL1 , ADERR , FEAT_ADERR ) &&
133+ kvm_has_feat (kvm , ID_AA64MMFR3_EL1 , SDERR , FEAT_ADERR ));
134+ }
135+
136+ static bool feat_anerr (struct kvm * kvm )
137+ {
138+ return (kvm_has_feat (kvm , ID_AA64MMFR3_EL1 , ANERR , FEAT_ANERR ) &&
139+ kvm_has_feat (kvm , ID_AA64MMFR3_EL1 , SNERR , FEAT_ANERR ));
140+ }
141+
142+ static bool feat_sme_smps (struct kvm * kvm )
143+ {
144+ /*
145+ * Revists this if KVM ever supports SME -- this really should
146+ * look at the guest's view of SMIDR_EL1. Funnily enough, this
147+ * is not captured in the JSON file, but only as a note in the
148+ * ARM ARM.
149+ */
150+ return (kvm_has_feat (kvm , FEAT_SME ) &&
151+ (read_sysreg_s (SYS_SMIDR_EL1 ) & SMIDR_EL1_SMPS ));
152+ }
153+
113154static const struct reg_bits_to_feat_map hfgrtr_feat_map [] = {
114155 NEEDS_FEAT (HFGRTR_EL2_nAMAIR2_EL1 |
115156 HFGRTR_EL2_nMAIR2_EL1 ,
@@ -494,6 +535,35 @@ static const struct reg_bits_to_feat_map hafgrtr_feat_map[] = {
494535 FEAT_AMUv1 ),
495536};
496537
538+ static const struct reg_bits_to_feat_map hcrx_feat_map [] = {
539+ NEEDS_FEAT (HCRX_EL2_PACMEn , feat_pauth_lr ),
540+ NEEDS_FEAT (HCRX_EL2_EnFPM , FEAT_FPMR ),
541+ NEEDS_FEAT (HCRX_EL2_GCSEn , FEAT_GCS ),
542+ NEEDS_FEAT (HCRX_EL2_EnIDCP128 , FEAT_SYSREG128 ),
543+ NEEDS_FEAT (HCRX_EL2_EnSDERR , feat_aderr ),
544+ NEEDS_FEAT (HCRX_EL2_TMEA , FEAT_DoubleFault2 ),
545+ NEEDS_FEAT (HCRX_EL2_EnSNERR , feat_anerr ),
546+ NEEDS_FEAT (HCRX_EL2_D128En , FEAT_D128 ),
547+ NEEDS_FEAT (HCRX_EL2_PTTWI , FEAT_THE ),
548+ NEEDS_FEAT (HCRX_EL2_SCTLR2En , FEAT_SCTLR2 ),
549+ NEEDS_FEAT (HCRX_EL2_TCR2En , FEAT_TCR2 ),
550+ NEEDS_FEAT (HCRX_EL2_MSCEn |
551+ HCRX_EL2_MCE2 ,
552+ FEAT_MOPS ),
553+ NEEDS_FEAT (HCRX_EL2_CMOW , FEAT_CMOW ),
554+ NEEDS_FEAT (HCRX_EL2_VFNMI |
555+ HCRX_EL2_VINMI |
556+ HCRX_EL2_TALLINT ,
557+ FEAT_NMI ),
558+ NEEDS_FEAT (HCRX_EL2_SMPME , feat_sme_smps ),
559+ NEEDS_FEAT (HCRX_EL2_FGTnXS |
560+ HCRX_EL2_FnXS ,
561+ FEAT_XS ),
562+ NEEDS_FEAT (HCRX_EL2_EnASR , FEAT_LS64_V ),
563+ NEEDS_FEAT (HCRX_EL2_EnALS , FEAT_LS64 ),
564+ NEEDS_FEAT (HCRX_EL2_EnAS0 , FEAT_LS64_ACCDATA ),
565+ };
566+
497567static void __init check_feat_map (const struct reg_bits_to_feat_map * map ,
498568 int map_size , u64 res0 , const char * str )
499569{
@@ -521,6 +591,8 @@ void __init check_feature_map(void)
521591 hdfgwtr_masks .res0 , hdfgwtr_masks .str );
522592 check_feat_map (hafgrtr_feat_map , ARRAY_SIZE (hafgrtr_feat_map ),
523593 hafgrtr_masks .res0 , hafgrtr_masks .str );
594+ check_feat_map (hcrx_feat_map , ARRAY_SIZE (hcrx_feat_map ),
595+ __HCRX_EL2_RES0 , "HCRX_EL2" );
524596}
525597
526598static bool idreg_feat_match (struct kvm * kvm , const struct reg_bits_to_feat_map * map )
@@ -656,6 +728,12 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
656728 * res0 |= hafgrtr_masks .res0 ;
657729 * res1 = HAFGRTR_EL2_RES1 ;
658730 break ;
731+ case HCRX_EL2 :
732+ * res0 = compute_res0_bits (kvm , hcrx_feat_map ,
733+ ARRAY_SIZE (hcrx_feat_map ), 0 , 0 );
734+ * res0 |= __HCRX_EL2_RES0 ;
735+ * res1 = __HCRX_EL2_RES1 ;
736+ break ;
659737 default :
660738 WARN_ON_ONCE (1 );
661739 * res0 = * res1 = 0 ;
0 commit comments