Skip to content

Commit 1cd2b08

Browse files
jingzhangosoupton
authored andcommitted
KVM: arm64: selftests: Handle feature fields with nonzero minimum value correctly
There are some feature fields with nonzero minimum valid value. Make sure get_safe_value() won't return invalid field values for them. Also fix a bug that wrongly uses the feature bits type as the feature bits sign causing all fields as signed in the get_safe_value() and get_invalid_value(). Fixes: 54a9ea7 ("KVM: arm64: selftests: Test for setting ID register from usersapce") Reported-by: Zenghui Yu <[email protected]> Reported-by: Itaru Kitayama <[email protected]> Tested-by: Itaru Kitayama <[email protected]> Signed-off-by: Jing Zhang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 6613476 commit 1cd2b08

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

tools/testing/selftests/kvm/aarch64/set_id_regs.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ struct reg_ftr_bits {
3232
enum ftr_type type;
3333
uint8_t shift;
3434
uint64_t mask;
35+
/*
36+
* For FTR_EXACT, safe_val is used as the exact safe value.
37+
* For FTR_LOWER_SAFE, safe_val is used as the minimal safe value.
38+
*/
3539
int64_t safe_val;
3640
};
3741

@@ -65,13 +69,13 @@ struct test_feature_reg {
6569

6670
static const struct reg_ftr_bits ftr_id_aa64dfr0_el1[] = {
6771
S_REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, PMUVer, 0),
68-
REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, DebugVer, 0),
72+
REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, DebugVer, ID_AA64DFR0_EL1_DebugVer_IMP),
6973
REG_FTR_END,
7074
};
7175

7276
static const struct reg_ftr_bits ftr_id_dfr0_el1[] = {
73-
S_REG_FTR_BITS(FTR_LOWER_SAFE, ID_DFR0_EL1, PerfMon, 0),
74-
REG_FTR_BITS(FTR_LOWER_SAFE, ID_DFR0_EL1, CopDbg, 0),
77+
S_REG_FTR_BITS(FTR_LOWER_SAFE, ID_DFR0_EL1, PerfMon, ID_DFR0_EL1_PerfMon_PMUv3),
78+
REG_FTR_BITS(FTR_LOWER_SAFE, ID_DFR0_EL1, CopDbg, ID_DFR0_EL1_CopDbg_Armv8),
7579
REG_FTR_END,
7680
};
7781

@@ -224,13 +228,13 @@ uint64_t get_safe_value(const struct reg_ftr_bits *ftr_bits, uint64_t ftr)
224228
{
225229
uint64_t ftr_max = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
226230

227-
if (ftr_bits->type == FTR_UNSIGNED) {
231+
if (ftr_bits->sign == FTR_UNSIGNED) {
228232
switch (ftr_bits->type) {
229233
case FTR_EXACT:
230234
ftr = ftr_bits->safe_val;
231235
break;
232236
case FTR_LOWER_SAFE:
233-
if (ftr > 0)
237+
if (ftr > ftr_bits->safe_val)
234238
ftr--;
235239
break;
236240
case FTR_HIGHER_SAFE:
@@ -252,7 +256,7 @@ uint64_t get_safe_value(const struct reg_ftr_bits *ftr_bits, uint64_t ftr)
252256
ftr = ftr_bits->safe_val;
253257
break;
254258
case FTR_LOWER_SAFE:
255-
if (ftr > 0)
259+
if (ftr > ftr_bits->safe_val)
256260
ftr--;
257261
break;
258262
case FTR_HIGHER_SAFE:
@@ -276,7 +280,7 @@ uint64_t get_invalid_value(const struct reg_ftr_bits *ftr_bits, uint64_t ftr)
276280
{
277281
uint64_t ftr_max = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
278282

279-
if (ftr_bits->type == FTR_UNSIGNED) {
283+
if (ftr_bits->sign == FTR_UNSIGNED) {
280284
switch (ftr_bits->type) {
281285
case FTR_EXACT:
282286
ftr = max((uint64_t)ftr_bits->safe_val + 1, ftr + 1);

0 commit comments

Comments
 (0)