@@ -17,6 +17,15 @@ enum {
17
17
VCPU_FEATURE_SBI_EXT ,
18
18
};
19
19
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
+
20
29
static bool isa_ext_cant_disable [KVM_RISCV_ISA_EXT_MAX ];
21
30
22
31
bool filter_reg (__u64 reg )
@@ -143,6 +152,38 @@ bool check_reject_set(int err)
143
152
return err == EINVAL ;
144
153
}
145
154
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
+
146
187
void finalize_vcpu (struct kvm_vcpu * vcpu , struct vcpu_reg_list * c )
147
188
{
148
189
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)
172
213
if (!s -> feature )
173
214
continue ;
174
215
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
+
175
223
switch (s -> feature_type ) {
176
224
case VCPU_FEATURE_ISA_EXT :
177
225
feature = RISCV_ISA_EXT_REG (s -> feature );
@@ -186,6 +234,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
186
234
/* Try to enable the desired extension */
187
235
__vcpu_set_reg (vcpu , feature , 1 );
188
236
237
+ skip :
189
238
/* Double check whether the desired extension was enabled */
190
239
__TEST_REQUIRE (__vcpu_has_ext (vcpu , feature ),
191
240
"%s not available, skipping tests" , s -> name );
@@ -410,6 +459,35 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
410
459
return strdup_printf ("%lld /* UNKNOWN */" , reg_off );
411
460
}
412
461
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
+
413
491
#define KVM_ISA_EXT_ARR (ext ) \
414
492
[KVM_RISCV_ISA_EXT_##ext] = "KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_" #ext
415
493
@@ -639,6 +717,9 @@ void print_reg(const char *prefix, __u64 id)
639
717
case KVM_REG_SIZE_U128 :
640
718
reg_size = "KVM_REG_SIZE_U128" ;
641
719
break ;
720
+ case KVM_REG_SIZE_U256 :
721
+ reg_size = "KVM_REG_SIZE_U256" ;
722
+ break ;
642
723
default :
643
724
printf ("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,\n" ,
644
725
(id & KVM_REG_SIZE_MASK ) >> KVM_REG_SIZE_SHIFT , id & ~REG_MASK );
@@ -670,6 +751,10 @@ void print_reg(const char *prefix, __u64 id)
670
751
printf ("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_FP_D | %s,\n" ,
671
752
reg_size , fp_d_id_to_str (prefix , id ));
672
753
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 ;
673
758
case KVM_REG_RISCV_ISA_EXT :
674
759
printf ("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n" ,
675
760
reg_size , isa_ext_id_to_str (prefix , id ));
@@ -874,6 +959,48 @@ static __u64 fp_d_regs[] = {
874
959
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_D ,
875
960
};
876
961
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
+
877
1004
#define SUBLIST_BASE \
878
1005
{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
879
1006
.skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
@@ -898,6 +1025,9 @@ static __u64 fp_d_regs[] = {
898
1025
{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
899
1026
.regs_n = ARRAY_SIZE(fp_d_regs),}
900
1027
1028
+ #define SUBLIST_V \
1029
+ {"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
1030
+
901
1031
#define KVM_ISA_EXT_SIMPLE_CONFIG (ext , extu ) \
902
1032
static __u64 regs_##ext[] = { \
903
1033
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | \
@@ -966,6 +1096,7 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
966
1096
KVM_ISA_EXT_SUBLIST_CONFIG (aia , AIA );
967
1097
KVM_ISA_EXT_SUBLIST_CONFIG (fp_f , FP_F );
968
1098
KVM_ISA_EXT_SUBLIST_CONFIG (fp_d , FP_D );
1099
+ KVM_ISA_EXT_SUBLIST_CONFIG (v , V );
969
1100
KVM_ISA_EXT_SIMPLE_CONFIG (h , H );
970
1101
KVM_ISA_EXT_SIMPLE_CONFIG (smnpm , SMNPM );
971
1102
KVM_ISA_EXT_SUBLIST_CONFIG (smstateen , SMSTATEEN );
@@ -1040,6 +1171,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
1040
1171
& config_fp_f ,
1041
1172
& config_fp_d ,
1042
1173
& config_h ,
1174
+ & config_v ,
1043
1175
& config_smnpm ,
1044
1176
& config_smstateen ,
1045
1177
& config_sscofpmf ,
0 commit comments