Skip to content

Commit 001e032

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: Convert TCR2_EL2 to config-driven sanitisation
As for other registers, convert the determination of the RES0 bits affecting TCR2_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 a3ed7da commit 001e032

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

arch/arm64/kvm/config.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ struct reg_bits_to_feat_map {
131131
#define FEAT_SPMU ID_AA64DFR1_EL1, SPMU, IMP
132132
#define FEAT_SPE_nVM ID_AA64DFR2_EL1, SPE_nVM, IMP
133133
#define FEAT_STEP2 ID_AA64DFR2_EL1, STEP, IMP
134+
#define FEAT_ASID2 ID_AA64MMFR4_EL1, ASID2, IMP
135+
#define FEAT_MEC ID_AA64MMFR3_EL1, MEC, IMP
136+
#define FEAT_HAFT ID_AA64MMFR1_EL1, HAFDBS, HAFT
134137

135138
static bool not_feat_aa64el3(struct kvm *kvm)
136139
{
@@ -218,6 +221,21 @@ static bool feat_trbe_mpam(struct kvm *kvm)
218221
(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_MPAM));
219222
}
220223

224+
static bool feat_asid2_e2h1(struct kvm *kvm)
225+
{
226+
return kvm_has_feat(kvm, FEAT_ASID2) && !kvm_has_feat(kvm, FEAT_E2H0);
227+
}
228+
229+
static bool feat_d128_e2h1(struct kvm *kvm)
230+
{
231+
return kvm_has_feat(kvm, FEAT_D128) && !kvm_has_feat(kvm, FEAT_E2H0);
232+
}
233+
234+
static bool feat_mec_e2h1(struct kvm *kvm)
235+
{
236+
return kvm_has_feat(kvm, FEAT_MEC) && !kvm_has_feat(kvm, FEAT_E2H0);
237+
}
238+
221239
static bool feat_ebep_pmuv3_ss(struct kvm *kvm)
222240
{
223241
return kvm_has_feat(kvm, FEAT_EBEP) || kvm_has_feat(kvm, FEAT_PMUv3_SS);
@@ -832,6 +850,28 @@ static const struct reg_bits_to_feat_map hcr_feat_map[] = {
832850
NEEDS_FEAT_FIXED(HCR_EL2_E2H, compute_hcr_e2h),
833851
};
834852

853+
static const struct reg_bits_to_feat_map tcr2_el2_feat_map[] = {
854+
NEEDS_FEAT(TCR2_EL2_FNG1 |
855+
TCR2_EL2_FNG0 |
856+
TCR2_EL2_A2,
857+
feat_asid2_e2h1),
858+
NEEDS_FEAT(TCR2_EL2_DisCH1 |
859+
TCR2_EL2_DisCH0 |
860+
TCR2_EL2_D128,
861+
feat_d128_e2h1),
862+
NEEDS_FEAT(TCR2_EL2_AMEC1, feat_mec_e2h1),
863+
NEEDS_FEAT(TCR2_EL2_AMEC0, FEAT_MEC),
864+
NEEDS_FEAT(TCR2_EL2_HAFT, FEAT_HAFT),
865+
NEEDS_FEAT(TCR2_EL2_PTTWI |
866+
TCR2_EL2_PnCH,
867+
FEAT_THE),
868+
NEEDS_FEAT(TCR2_EL2_AIE, FEAT_AIE),
869+
NEEDS_FEAT(TCR2_EL2_POE |
870+
TCR2_EL2_E0POE,
871+
FEAT_S1POE),
872+
NEEDS_FEAT(TCR2_EL2_PIE, FEAT_S1PIE),
873+
};
874+
835875
static void __init check_feat_map(const struct reg_bits_to_feat_map *map,
836876
int map_size, u64 res0, const char *str)
837877
{
@@ -863,6 +903,8 @@ void __init check_feature_map(void)
863903
__HCRX_EL2_RES0, "HCRX_EL2");
864904
check_feat_map(hcr_feat_map, ARRAY_SIZE(hcr_feat_map),
865905
HCR_EL2_RES0, "HCR_EL2");
906+
check_feat_map(tcr2_el2_feat_map, ARRAY_SIZE(tcr2_el2_feat_map),
907+
TCR2_EL2_RES0, "TCR2_EL2");
866908
}
867909

868910
static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_feat_map *map)
@@ -1077,6 +1119,12 @@ void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *r
10771119
*res0 |= HCR_EL2_RES0 | (mask & ~fixed);
10781120
*res1 = HCR_EL2_RES1 | (mask & fixed);
10791121
break;
1122+
case TCR2_EL2:
1123+
*res0 = compute_res0_bits(kvm, tcr2_el2_feat_map,
1124+
ARRAY_SIZE(tcr2_el2_feat_map), 0, 0);
1125+
*res0 |= TCR2_EL2_RES0;
1126+
*res1 = TCR2_EL2_RES1;
1127+
break;
10801128
default:
10811129
WARN_ON_ONCE(1);
10821130
*res0 = *res1 = 0;

arch/arm64/kvm/nested.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,25 +1663,7 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
16631663
set_sysreg_masks(kvm, HFGITR2_EL2, res0, res1);
16641664

16651665
/* TCR2_EL2 */
1666-
res0 = TCR2_EL2_RES0;
1667-
res1 = TCR2_EL2_RES1;
1668-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
1669-
res0 |= (TCR2_EL2_DisCH0 | TCR2_EL2_DisCH1 | TCR2_EL2_D128);
1670-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, MEC, IMP))
1671-
res0 |= TCR2_EL2_AMEC1 | TCR2_EL2_AMEC0;
1672-
if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, HAFDBS, HAFT))
1673-
res0 |= TCR2_EL2_HAFT;
1674-
if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
1675-
res0 |= TCR2_EL2_PTTWI | TCR2_EL2_PnCH;
1676-
if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, AIE, IMP))
1677-
res0 |= TCR2_EL2_AIE;
1678-
if (!kvm_has_s1poe(kvm))
1679-
res0 |= TCR2_EL2_POE | TCR2_EL2_E0POE;
1680-
if (!kvm_has_s1pie(kvm))
1681-
res0 |= TCR2_EL2_PIE;
1682-
if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, VH, IMP))
1683-
res0 |= (TCR2_EL2_E0POE | TCR2_EL2_D128 |
1684-
TCR2_EL2_AMEC1 | TCR2_EL2_DisCH0 | TCR2_EL2_DisCH1);
1666+
get_reg_fixed_bits(kvm, TCR2_EL2, &res0, &res1);
16851667
set_sysreg_masks(kvm, TCR2_EL2, res0, res1);
16861668

16871669
/* SCTLR_EL1 */

0 commit comments

Comments
 (0)