Skip to content

Commit 938a79d

Browse files
author
Marc Zyngier
committed
KVM: arm64: Validate FGT register descriptions against RES0 masks
In order to point out to the unsuspecting KVM hacker that they are missing something somewhere, validate that the known FGT bits do not intersect with the corresponding RES0 mask, as computed at boot time. THis check is also performed at boot time, ensuring that there is no runtime overhead. Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 63d423a commit 938a79d

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,5 +1611,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
16111611
(kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP))
16121612

16131613
void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt);
1614+
void check_feature_map(void);
16141615

16151616
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/kvm/config.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,35 @@ static const struct reg_bits_to_feat_map hafgrtr_feat_map[] = {
494494
FEAT_AMUv1),
495495
};
496496

497+
static void __init check_feat_map(const struct reg_bits_to_feat_map *map,
498+
int map_size, u64 res0, const char *str)
499+
{
500+
u64 mask = 0;
501+
502+
for (int i = 0; i < map_size; i++)
503+
mask |= map[i].bits;
504+
505+
if (mask != ~res0)
506+
kvm_err("Undefined %s behaviour, bits %016llx\n",
507+
str, mask ^ ~res0);
508+
}
509+
510+
void __init check_feature_map(void)
511+
{
512+
check_feat_map(hfgrtr_feat_map, ARRAY_SIZE(hfgrtr_feat_map),
513+
hfgrtr_masks.res0, hfgrtr_masks.str);
514+
check_feat_map(hfgwtr_feat_map, ARRAY_SIZE(hfgwtr_feat_map),
515+
hfgwtr_masks.res0, hfgwtr_masks.str);
516+
check_feat_map(hfgitr_feat_map, ARRAY_SIZE(hfgitr_feat_map),
517+
hfgitr_masks.res0, hfgitr_masks.str);
518+
check_feat_map(hdfgrtr_feat_map, ARRAY_SIZE(hdfgrtr_feat_map),
519+
hdfgrtr_masks.res0, hdfgrtr_masks.str);
520+
check_feat_map(hdfgwtr_feat_map, ARRAY_SIZE(hdfgwtr_feat_map),
521+
hdfgwtr_masks.res0, hdfgwtr_masks.str);
522+
check_feat_map(hafgrtr_feat_map, ARRAY_SIZE(hafgrtr_feat_map),
523+
hafgrtr_masks.res0, hafgrtr_masks.str);
524+
}
525+
497526
static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_feat_map *map)
498527
{
499528
u64 regval = kvm->arch.id_regs[map->regidx];

arch/arm64/kvm/sys_regs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5208,6 +5208,8 @@ int __init kvm_sys_reg_table_init(void)
52085208

52095209
ret = populate_nv_trap_config();
52105210

5211+
check_feature_map();
5212+
52115213
for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)
52125214
ret = populate_sysreg_config(sys_reg_descs + i, i);
52135215

0 commit comments

Comments
 (0)