Skip to content

Commit cd64587

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: Convert MDCR_EL2 to config-driven sanitisation
As for other registers, convert the determination of the RES0 bits affecting MDCR_EL2 to be driven by a table extracted from the 2025-06 JSON drop Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 6bd4a27 commit cd64587

File tree

2 files changed

+64
-34
lines changed

2 files changed

+64
-34
lines changed

arch/arm64/kvm/config.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct reg_bits_to_feat_map {
8989
#define FEAT_RASv2 ID_AA64PFR0_EL1, RAS, V2
9090
#define FEAT_GICv3 ID_AA64PFR0_EL1, GIC, IMP
9191
#define FEAT_LOR ID_AA64MMFR1_EL1, LO, IMP
92+
#define FEAT_SPEv1p2 ID_AA64DFR0_EL1, PMSVer, V1P2
9293
#define FEAT_SPEv1p4 ID_AA64DFR0_EL1, PMSVer, V1P4
9394
#define FEAT_SPEv1p5 ID_AA64DFR0_EL1, PMSVer, V1P5
9495
#define FEAT_ATS1A ID_AA64ISAR2_EL1, ATS1A, IMP
@@ -148,6 +149,8 @@ struct reg_bits_to_feat_map {
148149
#define FEAT_PAN3 ID_AA64MMFR1_EL1, PAN, PAN3
149150
#define FEAT_SSBS ID_AA64PFR1_EL1, SSBS, IMP
150151
#define FEAT_TIDCP1 ID_AA64MMFR1_EL1, TIDCP1, IMP
152+
#define FEAT_FGT ID_AA64MMFR0_EL1, FGT, IMP
153+
#define FEAT_MTPMU ID_AA64DFR0_EL1, MTPMU, IMP
151154

152155
static bool not_feat_aa64el3(struct kvm *kvm)
153156
{
@@ -265,6 +268,27 @@ static bool feat_mte_async(struct kvm *kvm)
265268
return kvm_has_feat(kvm, FEAT_MTE2) && kvm_has_feat_enum(kvm, FEAT_MTE_ASYNC);
266269
}
267270

271+
#define check_pmu_revision(k, r) \
272+
({ \
273+
(kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, r) && \
274+
!kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, IMP_DEF)); \
275+
})
276+
277+
static bool feat_pmuv3p1(struct kvm *kvm)
278+
{
279+
return check_pmu_revision(kvm, V3P1);
280+
}
281+
282+
static bool feat_pmuv3p5(struct kvm *kvm)
283+
{
284+
return check_pmu_revision(kvm, V3P5);
285+
}
286+
287+
static bool feat_pmuv3p7(struct kvm *kvm)
288+
{
289+
return check_pmu_revision(kvm, V3P7);
290+
}
291+
268292
static bool compute_hcr_rw(struct kvm *kvm, u64 *bits)
269293
{
270294
/* This is purely academic: AArch32 and NV are mutually exclusive */
@@ -970,6 +994,37 @@ static const struct reg_bits_to_feat_map sctlr_el1_feat_map[] = {
970994
FEAT_AA64EL1),
971995
};
972996

997+
static const struct reg_bits_to_feat_map mdcr_el2_feat_map[] = {
998+
NEEDS_FEAT(MDCR_EL2_EBWE, FEAT_Debugv8p9),
999+
NEEDS_FEAT(MDCR_EL2_TDOSA, FEAT_DoubleLock),
1000+
NEEDS_FEAT(MDCR_EL2_PMEE, FEAT_EBEP),
1001+
NEEDS_FEAT(MDCR_EL2_TDCC, FEAT_FGT),
1002+
NEEDS_FEAT(MDCR_EL2_MTPME, FEAT_MTPMU),
1003+
NEEDS_FEAT(MDCR_EL2_HPME |
1004+
MDCR_EL2_HPMN |
1005+
MDCR_EL2_TPMCR |
1006+
MDCR_EL2_TPM,
1007+
FEAT_PMUv3),
1008+
NEEDS_FEAT(MDCR_EL2_HPMD, feat_pmuv3p1),
1009+
NEEDS_FEAT(MDCR_EL2_HCCD |
1010+
MDCR_EL2_HLP,
1011+
feat_pmuv3p5),
1012+
NEEDS_FEAT(MDCR_EL2_HPMFZO, feat_pmuv3p7),
1013+
NEEDS_FEAT(MDCR_EL2_PMSSE, FEAT_PMUv3_SS),
1014+
NEEDS_FEAT(MDCR_EL2_E2PB |
1015+
MDCR_EL2_TPMS,
1016+
FEAT_SPE),
1017+
NEEDS_FEAT(MDCR_EL2_HPMFZS, FEAT_SPEv1p2),
1018+
NEEDS_FEAT(MDCR_EL2_EnSPM, FEAT_SPMU),
1019+
NEEDS_FEAT(MDCR_EL2_EnSTEPOP, FEAT_STEP2),
1020+
NEEDS_FEAT(MDCR_EL2_E2TB, FEAT_TRBE),
1021+
NEEDS_FEAT(MDCR_EL2_TTRF, FEAT_TRF),
1022+
NEEDS_FEAT(MDCR_EL2_TDA |
1023+
MDCR_EL2_TDE |
1024+
MDCR_EL2_TDRA,
1025+
FEAT_AA64EL1),
1026+
};
1027+
9731028
static void __init check_feat_map(const struct reg_bits_to_feat_map *map,
9741029
int map_size, u64 res0, const char *str)
9751030
{
@@ -1005,6 +1060,8 @@ void __init check_feature_map(void)
10051060
TCR2_EL2_RES0, "TCR2_EL2");
10061061
check_feat_map(sctlr_el1_feat_map, ARRAY_SIZE(sctlr_el1_feat_map),
10071062
SCTLR_EL1_RES0, "SCTLR_EL1");
1063+
check_feat_map(mdcr_el2_feat_map, ARRAY_SIZE(mdcr_el2_feat_map),
1064+
MDCR_EL2_RES0, "MDCR_EL2");
10081065
}
10091066

10101067
static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_feat_map *map)
@@ -1231,6 +1288,12 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
12311288
*res0 |= SCTLR_EL1_RES0;
12321289
*res1 = SCTLR_EL1_RES1;
12331290
break;
1291+
case MDCR_EL2:
1292+
*res0 = compute_res0_bits(kvm, mdcr_el2_feat_map,
1293+
ARRAY_SIZE(mdcr_el2_feat_map), 0, 0);
1294+
*res0 |= MDCR_EL2_RES0;
1295+
*res1 = MDCR_EL2_RES1;
1296+
break;
12341297
default:
12351298
WARN_ON_ONCE(1);
12361299
*res0 = *res1 = 0;

arch/arm64/kvm/nested.c

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,40 +1671,7 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
16711671
set_sysreg_masks(kvm, SCTLR_EL1, res0, res1);
16721672

16731673
/* MDCR_EL2 */
1674-
res0 = MDCR_EL2_RES0;
1675-
res1 = MDCR_EL2_RES1;
1676-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
1677-
res0 |= (MDCR_EL2_HPMN | MDCR_EL2_TPMCR |
1678-
MDCR_EL2_TPM | MDCR_EL2_HPME);
1679-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP))
1680-
res0 |= MDCR_EL2_E2PB | MDCR_EL2_TPMS;
1681-
if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, SPMU, IMP))
1682-
res0 |= MDCR_EL2_EnSPM;
1683-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P1))
1684-
res0 |= MDCR_EL2_HPMD;
1685-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
1686-
res0 |= MDCR_EL2_TTRF;
1687-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
1688-
res0 |= MDCR_EL2_HCCD | MDCR_EL2_HLP;
1689-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
1690-
res0 |= MDCR_EL2_E2TB;
1691-
if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
1692-
res0 |= MDCR_EL2_TDCC;
1693-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, MTPMU, IMP) ||
1694-
kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
1695-
res0 |= MDCR_EL2_MTPME;
1696-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, V3P7))
1697-
res0 |= MDCR_EL2_HPMFZO;
1698-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSS, IMP))
1699-
res0 |= MDCR_EL2_PMSSE;
1700-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, V1P2))
1701-
res0 |= MDCR_EL2_HPMFZS;
1702-
if (!kvm_has_feat(kvm, ID_AA64DFR1_EL1, EBEP, IMP))
1703-
res0 |= MDCR_EL2_PMEE;
1704-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, V8P9))
1705-
res0 |= MDCR_EL2_EBWE;
1706-
if (!kvm_has_feat(kvm, ID_AA64DFR2_EL1, STEP, IMP))
1707-
res0 |= MDCR_EL2_EnSTEPOP;
1674+
get_reg_fixed_bits(kvm, MDCR_EL2, &res0, &res1);
17081675
set_sysreg_masks(kvm, MDCR_EL2, res0, res1);
17091676

17101677
/* CNTHCTL_EL2 */

0 commit comments

Comments
 (0)