@@ -17,6 +17,15 @@ enum {
1717 VCPU_FEATURE_SBI_EXT ,
1818};
1919
20+ enum {
21+ KVM_RISC_V_REG_OFFSET_VSTART = 0 ,
22+ KVM_RISC_V_REG_OFFSET_VL ,
23+ KVM_RISC_V_REG_OFFSET_VTYPE ,
24+ KVM_RISC_V_REG_OFFSET_VCSR ,
25+ KVM_RISC_V_REG_OFFSET_VLENB ,
26+ KVM_RISC_V_REG_OFFSET_MAX ,
27+ };
28+
2029static bool isa_ext_cant_disable [KVM_RISCV_ISA_EXT_MAX ];
2130
2231bool filter_reg (__u64 reg )
@@ -143,6 +152,38 @@ bool check_reject_set(int err)
143152 return err == EINVAL ;
144153}
145154
155+ static int override_vector_reg_size (struct kvm_vcpu * vcpu , struct vcpu_reg_sublist * s ,
156+ uint64_t feature )
157+ {
158+ unsigned long vlenb_reg = 0 ;
159+ int rc ;
160+ u64 reg , size ;
161+
162+ /* Enable V extension so that we can get the vlenb register */
163+ rc = __vcpu_set_reg (vcpu , feature , 1 );
164+ if (rc )
165+ return rc ;
166+
167+ vlenb_reg = vcpu_get_reg (vcpu , s -> regs [KVM_RISC_V_REG_OFFSET_VLENB ]);
168+ if (!vlenb_reg ) {
169+ TEST_FAIL ("Can't compute vector register size from zero vlenb\n" );
170+ return - EPERM ;
171+ }
172+
173+ size = __builtin_ctzl (vlenb_reg );
174+ size <<= KVM_REG_SIZE_SHIFT ;
175+
176+ for (int i = 0 ; i < 32 ; i ++ ) {
177+ reg = KVM_REG_RISCV | KVM_REG_RISCV_VECTOR | size | KVM_REG_RISCV_VECTOR_REG (i );
178+ s -> regs [KVM_RISC_V_REG_OFFSET_MAX + i ] = reg ;
179+ }
180+
181+ /* We should assert if disabling failed here while enabling succeeded before */
182+ vcpu_set_reg (vcpu , feature , 0 );
183+
184+ return 0 ;
185+ }
186+
146187void finalize_vcpu (struct kvm_vcpu * vcpu , struct vcpu_reg_list * c )
147188{
148189 unsigned long isa_ext_state [KVM_RISCV_ISA_EXT_MAX ] = { 0 };
@@ -172,6 +213,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
172213 if (!s -> feature )
173214 continue ;
174215
216+ if (s -> feature == KVM_RISCV_ISA_EXT_V ) {
217+ feature = RISCV_ISA_EXT_REG (s -> feature );
218+ rc = override_vector_reg_size (vcpu , s , feature );
219+ if (rc )
220+ goto skip ;
221+ }
222+
175223 switch (s -> feature_type ) {
176224 case VCPU_FEATURE_ISA_EXT :
177225 feature = RISCV_ISA_EXT_REG (s -> feature );
@@ -186,6 +234,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
186234 /* Try to enable the desired extension */
187235 __vcpu_set_reg (vcpu , feature , 1 );
188236
237+ skip :
189238 /* Double check whether the desired extension was enabled */
190239 __TEST_REQUIRE (__vcpu_has_ext (vcpu , feature ),
191240 "%s not available, skipping tests" , s -> name );
@@ -410,6 +459,35 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
410459 return strdup_printf ("%lld /* UNKNOWN */" , reg_off );
411460}
412461
462+ static const char * vector_id_to_str (const char * prefix , __u64 id )
463+ {
464+ /* reg_off is the offset into struct __riscv_v_ext_state */
465+ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_VECTOR );
466+ int reg_index = 0 ;
467+
468+ assert ((id & KVM_REG_RISCV_TYPE_MASK ) == KVM_REG_RISCV_VECTOR );
469+
470+ if (reg_off >= KVM_REG_RISCV_VECTOR_REG (0 ))
471+ reg_index = reg_off - KVM_REG_RISCV_VECTOR_REG (0 );
472+ switch (reg_off ) {
473+ case KVM_REG_RISCV_VECTOR_REG (0 ) ...
474+ KVM_REG_RISCV_VECTOR_REG (31 ):
475+ return strdup_printf ("KVM_REG_RISCV_VECTOR_REG(%d)" , reg_index );
476+ case KVM_REG_RISCV_VECTOR_CSR_REG (vstart ):
477+ return "KVM_REG_RISCV_VECTOR_CSR_REG(vstart)" ;
478+ case KVM_REG_RISCV_VECTOR_CSR_REG (vl ):
479+ return "KVM_REG_RISCV_VECTOR_CSR_REG(vl)" ;
480+ case KVM_REG_RISCV_VECTOR_CSR_REG (vtype ):
481+ return "KVM_REG_RISCV_VECTOR_CSR_REG(vtype)" ;
482+ case KVM_REG_RISCV_VECTOR_CSR_REG (vcsr ):
483+ return "KVM_REG_RISCV_VECTOR_CSR_REG(vcsr)" ;
484+ case KVM_REG_RISCV_VECTOR_CSR_REG (vlenb ):
485+ return "KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)" ;
486+ }
487+
488+ return strdup_printf ("%lld /* UNKNOWN */" , reg_off );
489+ }
490+
413491#define KVM_ISA_EXT_ARR (ext ) \
414492[KVM_RISCV_ISA_EXT_##ext] = "KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_" #ext
415493
@@ -639,6 +717,9 @@ void print_reg(const char *prefix, __u64 id)
639717 case KVM_REG_SIZE_U128 :
640718 reg_size = "KVM_REG_SIZE_U128" ;
641719 break ;
720+ case KVM_REG_SIZE_U256 :
721+ reg_size = "KVM_REG_SIZE_U256" ;
722+ break ;
642723 default :
643724 printf ("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,\n" ,
644725 (id & KVM_REG_SIZE_MASK ) >> KVM_REG_SIZE_SHIFT , id & ~REG_MASK );
@@ -670,6 +751,10 @@ void print_reg(const char *prefix, __u64 id)
670751 printf ("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_FP_D | %s,\n" ,
671752 reg_size , fp_d_id_to_str (prefix , id ));
672753 break ;
754+ case KVM_REG_RISCV_VECTOR :
755+ printf ("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_VECTOR | %s,\n" ,
756+ reg_size , vector_id_to_str (prefix , id ));
757+ break ;
673758 case KVM_REG_RISCV_ISA_EXT :
674759 printf ("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n" ,
675760 reg_size , isa_ext_id_to_str (prefix , id ));
@@ -874,6 +959,48 @@ static __u64 fp_d_regs[] = {
874959 KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_D ,
875960};
876961
962+ /* Define a default vector registers with length. This will be overwritten at runtime */
963+ static __u64 vector_regs [] = {
964+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG (vstart ),
965+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG (vl ),
966+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG (vtype ),
967+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG (vcsr ),
968+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG (vlenb ),
969+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (0 ),
970+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (1 ),
971+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (2 ),
972+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (3 ),
973+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (4 ),
974+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (5 ),
975+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (6 ),
976+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (7 ),
977+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (8 ),
978+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (9 ),
979+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (10 ),
980+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (11 ),
981+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (12 ),
982+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (13 ),
983+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (14 ),
984+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (15 ),
985+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (16 ),
986+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (17 ),
987+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (18 ),
988+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (19 ),
989+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (20 ),
990+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (21 ),
991+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (22 ),
992+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (23 ),
993+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (24 ),
994+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (25 ),
995+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (26 ),
996+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (27 ),
997+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (28 ),
998+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (29 ),
999+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (30 ),
1000+ KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG (31 ),
1001+ KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_V ,
1002+ };
1003+
8771004#define SUBLIST_BASE \
8781005 {"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
8791006 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
@@ -898,6 +1025,9 @@ static __u64 fp_d_regs[] = {
8981025 {"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
8991026 .regs_n = ARRAY_SIZE(fp_d_regs),}
9001027
1028+ #define SUBLIST_V \
1029+ {"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
1030+
9011031#define KVM_ISA_EXT_SIMPLE_CONFIG (ext , extu ) \
9021032static __u64 regs_##ext[] = { \
9031033 KVM_REG_RISCV | KVM_REG_SIZE_ULONG | \
@@ -966,6 +1096,7 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
9661096KVM_ISA_EXT_SUBLIST_CONFIG (aia , AIA );
9671097KVM_ISA_EXT_SUBLIST_CONFIG (fp_f , FP_F );
9681098KVM_ISA_EXT_SUBLIST_CONFIG (fp_d , FP_D );
1099+ KVM_ISA_EXT_SUBLIST_CONFIG (v , V );
9691100KVM_ISA_EXT_SIMPLE_CONFIG (h , H );
9701101KVM_ISA_EXT_SIMPLE_CONFIG (smnpm , SMNPM );
9711102KVM_ISA_EXT_SUBLIST_CONFIG (smstateen , SMSTATEEN );
@@ -1040,6 +1171,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
10401171 & config_fp_f ,
10411172 & config_fp_d ,
10421173 & config_h ,
1174+ & config_v ,
10431175 & config_smnpm ,
10441176 & config_smstateen ,
10451177 & config_sscofpmf ,
0 commit comments