Skip to content

Commit 8d94458

Browse files
author
Marc Zyngier
committed
KVM: arm64: Simplify FIXED_VALUE handling
The FIXED_VALUE qualifier (mostly used for HCR_EL2) is pointlessly complicated, as it tries to piggy-back on the previous RES0 handling while being done in a different phase, on different data. Instead, make it an integral part of the RESx computation, and allow it to directly set RESx bits. This is much easier to understand. It also paves the way for some additional changes to that will allow the full removal of the FIXED_VALUE handling. Reviewed-by: Fuad Tabba <tabba@google.com> Tested-by: Fuad Tabba <tabba@google.com> Link: https://patch.msgid.link/20260202184329.2724080-11-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent fb86207 commit 8d94458

1 file changed

Lines changed: 22 additions & 44 deletions

File tree

arch/arm64/kvm/config.c

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct reg_bits_to_feat_map {
3737
s8 lo_lim;
3838
};
3939
bool (*match)(struct kvm *);
40-
bool (*fval)(struct kvm *, u64 *);
40+
bool (*fval)(struct kvm *, struct resx *);
4141
};
4242
};
4343

@@ -389,14 +389,12 @@ static bool feat_vmid16(struct kvm *kvm)
389389
return kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16);
390390
}
391391

392-
static bool compute_hcr_e2h(struct kvm *kvm, u64 *bits)
392+
static bool compute_hcr_e2h(struct kvm *kvm, struct resx *bits)
393393
{
394-
if (bits) {
395-
if (kvm_has_feat(kvm, FEAT_E2H0))
396-
*bits &= ~HCR_EL2_E2H;
397-
else
398-
*bits |= HCR_EL2_E2H;
399-
}
394+
if (kvm_has_feat(kvm, FEAT_E2H0))
395+
bits->res0 |= HCR_EL2_E2H;
396+
else
397+
bits->res1 |= HCR_EL2_E2H;
400398

401399
return true;
402400
}
@@ -1280,12 +1278,11 @@ static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_feat_map
12801278
}
12811279
}
12821280

1283-
static struct resx __compute_fixed_bits(struct kvm *kvm,
1284-
const struct reg_bits_to_feat_map *map,
1285-
int map_size,
1286-
u64 *fixed_bits,
1287-
unsigned long require,
1288-
unsigned long exclude)
1281+
static struct resx compute_resx_bits(struct kvm *kvm,
1282+
const struct reg_bits_to_feat_map *map,
1283+
int map_size,
1284+
unsigned long require,
1285+
unsigned long exclude)
12891286
{
12901287
struct resx resx = {};
12911288

@@ -1298,14 +1295,18 @@ static struct resx __compute_fixed_bits(struct kvm *kvm,
12981295
if (map[i].flags & exclude)
12991296
continue;
13001297

1301-
if (map[i].flags & CALL_FUNC)
1302-
match = (map[i].flags & FIXED_VALUE) ?
1303-
map[i].fval(kvm, fixed_bits) :
1304-
map[i].match(kvm);
1305-
else
1298+
switch (map[i].flags & (CALL_FUNC | FIXED_VALUE)) {
1299+
case CALL_FUNC | FIXED_VALUE:
1300+
map[i].fval(kvm, &resx);
1301+
continue;
1302+
case CALL_FUNC:
1303+
match = map[i].match(kvm);
1304+
break;
1305+
default:
13061306
match = idreg_feat_match(kvm, &map[i]);
1307+
}
13071308

1308-
if (!match || (map[i].flags & FIXED_VALUE)) {
1309+
if (!match) {
13091310
if (map[i].flags & AS_RES1)
13101311
resx.res1 |= reg_feat_map_bits(&map[i]);
13111312
else
@@ -1316,16 +1317,6 @@ static struct resx __compute_fixed_bits(struct kvm *kvm,
13161317
return resx;
13171318
}
13181319

1319-
static struct resx compute_resx_bits(struct kvm *kvm,
1320-
const struct reg_bits_to_feat_map *map,
1321-
int map_size,
1322-
unsigned long require,
1323-
unsigned long exclude)
1324-
{
1325-
return __compute_fixed_bits(kvm, map, map_size, NULL,
1326-
require, exclude | FIXED_VALUE);
1327-
}
1328-
13291320
static struct resx compute_reg_resx_bits(struct kvm *kvm,
13301321
const struct reg_feat_map_desc *r,
13311322
unsigned long require,
@@ -1366,16 +1357,6 @@ static u64 compute_fgu_bits(struct kvm *kvm, const struct reg_feat_map_desc *r)
13661357
return resx.res0 | resx.res1;
13671358
}
13681359

1369-
static struct resx compute_reg_fixed_bits(struct kvm *kvm,
1370-
const struct reg_feat_map_desc *r,
1371-
u64 *fixed_bits,
1372-
unsigned long require,
1373-
unsigned long exclude)
1374-
{
1375-
return __compute_fixed_bits(kvm, r->bit_feat_map, r->bit_feat_map_sz,
1376-
fixed_bits, require | FIXED_VALUE, exclude);
1377-
}
1378-
13791360
void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt)
13801361
{
13811362
u64 val = 0;
@@ -1415,7 +1396,6 @@ void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt)
14151396

14161397
struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg)
14171398
{
1418-
u64 fixed = 0, mask;
14191399
struct resx resx;
14201400

14211401
switch (reg) {
@@ -1457,10 +1437,8 @@ struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg)
14571437
resx.res1 |= __HCRX_EL2_RES1;
14581438
break;
14591439
case HCR_EL2:
1460-
mask = compute_reg_fixed_bits(kvm, &hcr_desc, &fixed, 0, 0).res0;
14611440
resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0);
1462-
resx.res0 |= (mask & ~fixed);
1463-
resx.res1 |= HCR_EL2_RES1 | (mask & fixed);
1441+
resx.res1 |= HCR_EL2_RES1;
14641442
break;
14651443
case SCTLR2_EL1:
14661444
case SCTLR2_EL2:

0 commit comments

Comments
 (0)