Skip to content

Commit d2f629a

Browse files
author
Marc Zyngier
committed
KVM: arm64: Move RESx into individual register descriptors
Instead of hacking the RES1 bits at runtime, move them into the register descriptors. This makes it significantly nicer. Reviewed-by: Fuad Tabba <tabba@google.com> Tested-by: Fuad Tabba <tabba@google.com> Link: https://patch.msgid.link/20260202184329.2724080-14-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent d406fcb commit d2f629a

1 file changed

Lines changed: 37 additions & 11 deletions

File tree

arch/arm64/kvm/config.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct reg_bits_to_feat_map {
2828
#define REQUIRES_E2H1 BIT(5) /* Add HCR_EL2.E2H RES1 as a pre-condition */
2929
#define RES1_WHEN_E2H0 BIT(6) /* RES1 when E2H=0 and not supported */
3030
#define RES1_WHEN_E2H1 BIT(7) /* RES1 when E2H=1 and not supported */
31+
#define FORCE_RESx BIT(8) /* Unconditional RESx */
3132

3233
unsigned long flags;
3334

@@ -87,6 +88,12 @@ struct reg_feat_map_desc {
8788
.match = (fun), \
8889
}
8990

91+
#define __NEEDS_FEAT_0(m, f, w, ...) \
92+
{ \
93+
.w = (m), \
94+
.flags = (f), \
95+
}
96+
9097
#define __NEEDS_FEAT_FLAG(m, f, w, ...) \
9198
CONCATENATE(__NEEDS_FEAT_, COUNT_ARGS(__VA_ARGS__))(m, f, w, __VA_ARGS__)
9299

@@ -105,10 +112,14 @@ struct reg_feat_map_desc {
105112
*/
106113
#define NEEDS_FEAT(m, ...) NEEDS_FEAT_FLAG(m, 0, __VA_ARGS__)
107114

115+
/* Declare fixed RESx bits */
116+
#define FORCE_RES0(m) NEEDS_FEAT_FLAG(m, FORCE_RESx)
117+
#define FORCE_RES1(m) NEEDS_FEAT_FLAG(m, FORCE_RESx | AS_RES1)
118+
108119
/*
109-
* Declare the dependency between a non-FGT register, a set of
110-
* feature, and the set of individual bits it contains. This generates
111-
* a struct reg_feat_map_desc.
120+
* Declare the dependency between a non-FGT register, a set of features,
121+
* and the set of individual bits it contains. This generates a struct
122+
* reg_feat_map_desc.
112123
*/
113124
#define DECLARE_FEAT_MAP(n, r, m, f) \
114125
struct reg_feat_map_desc n = { \
@@ -1007,6 +1018,8 @@ static const struct reg_bits_to_feat_map hcr_feat_map[] = {
10071018
HCR_EL2_TWEDEn,
10081019
FEAT_TWED),
10091020
NEEDS_FEAT_FIXED(HCR_EL2_E2H, compute_hcr_e2h),
1021+
FORCE_RES0(HCR_EL2_RES0),
1022+
FORCE_RES1(HCR_EL2_RES1),
10101023
};
10111024

10121025
static const DECLARE_FEAT_MAP(hcr_desc, HCR_EL2,
@@ -1027,6 +1040,8 @@ static const struct reg_bits_to_feat_map sctlr2_feat_map[] = {
10271040
SCTLR2_EL1_CPTM |
10281041
SCTLR2_EL1_CPTM0,
10291042
FEAT_CPA2),
1043+
FORCE_RES0(SCTLR2_EL1_RES0),
1044+
FORCE_RES1(SCTLR2_EL1_RES1),
10301045
};
10311046

10321047
static const DECLARE_FEAT_MAP(sctlr2_desc, SCTLR2_EL1,
@@ -1052,6 +1067,8 @@ static const struct reg_bits_to_feat_map tcr2_el2_feat_map[] = {
10521067
TCR2_EL2_E0POE,
10531068
FEAT_S1POE),
10541069
NEEDS_FEAT(TCR2_EL2_PIE, FEAT_S1PIE),
1070+
FORCE_RES0(TCR2_EL2_RES0),
1071+
FORCE_RES1(TCR2_EL2_RES1),
10551072
};
10561073

10571074
static const DECLARE_FEAT_MAP(tcr2_el2_desc, TCR2_EL2,
@@ -1129,6 +1146,8 @@ static const struct reg_bits_to_feat_map sctlr_el1_feat_map[] = {
11291146
SCTLR_EL1_A |
11301147
SCTLR_EL1_M,
11311148
FEAT_AA64EL1),
1149+
FORCE_RES0(SCTLR_EL1_RES0),
1150+
FORCE_RES1(SCTLR_EL1_RES1),
11321151
};
11331152

11341153
static const DECLARE_FEAT_MAP(sctlr_el1_desc, SCTLR_EL1,
@@ -1163,6 +1182,8 @@ static const struct reg_bits_to_feat_map mdcr_el2_feat_map[] = {
11631182
MDCR_EL2_TDE |
11641183
MDCR_EL2_TDRA,
11651184
FEAT_AA64EL1),
1185+
FORCE_RES0(MDCR_EL2_RES0),
1186+
FORCE_RES1(MDCR_EL2_RES1),
11661187
};
11671188

11681189
static const DECLARE_FEAT_MAP(mdcr_el2_desc, MDCR_EL2,
@@ -1201,6 +1222,8 @@ static const struct reg_bits_to_feat_map vtcr_el2_feat_map[] = {
12011222
VTCR_EL2_SL0 |
12021223
VTCR_EL2_T0SZ,
12031224
FEAT_AA64EL1),
1225+
FORCE_RES0(VTCR_EL2_RES0),
1226+
FORCE_RES1(VTCR_EL2_RES1),
12041227
};
12051228

12061229
static const DECLARE_FEAT_MAP(vtcr_el2_desc, VTCR_EL2,
@@ -1211,8 +1234,14 @@ static void __init check_feat_map(const struct reg_bits_to_feat_map *map,
12111234
{
12121235
u64 mask = 0;
12131236

1237+
/*
1238+
* Don't account for FORCE_RESx that are architectural, and
1239+
* therefore part of the resx parameter. Other FORCE_RESx bits
1240+
* are implementation choices, and therefore accounted for.
1241+
*/
12141242
for (int i = 0; i < map_size; i++)
1215-
mask |= map[i].bits;
1243+
if (!((map[i].flags & FORCE_RESx) && (map[i].bits & resx)))
1244+
mask |= map[i].bits;
12161245

12171246
if (mask != ~resx)
12181247
kvm_err("Undefined %s behaviour, bits %016llx\n",
@@ -1284,13 +1313,16 @@ static struct resx compute_resx_bits(struct kvm *kvm,
12841313
if (map[i].flags & exclude)
12851314
continue;
12861315

1287-
switch (map[i].flags & (CALL_FUNC | FIXED_VALUE)) {
1316+
switch (map[i].flags & (FORCE_RESx | CALL_FUNC | FIXED_VALUE)) {
12881317
case CALL_FUNC | FIXED_VALUE:
12891318
map[i].fval(kvm, &resx);
12901319
continue;
12911320
case CALL_FUNC:
12921321
match = map[i].match(kvm);
12931322
break;
1323+
case FORCE_RESx:
1324+
match = false;
1325+
break;
12941326
default:
12951327
match = idreg_feat_match(kvm, &map[i]);
12961328
}
@@ -1434,28 +1466,22 @@ struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg)
14341466
break;
14351467
case HCR_EL2:
14361468
resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0);
1437-
resx.res1 |= HCR_EL2_RES1;
14381469
break;
14391470
case SCTLR2_EL1:
14401471
case SCTLR2_EL2:
14411472
resx = compute_reg_resx_bits(kvm, &sctlr2_desc, 0, 0);
1442-
resx.res1 |= SCTLR2_EL1_RES1;
14431473
break;
14441474
case TCR2_EL2:
14451475
resx = compute_reg_resx_bits(kvm, &tcr2_el2_desc, 0, 0);
1446-
resx.res1 |= TCR2_EL2_RES1;
14471476
break;
14481477
case SCTLR_EL1:
14491478
resx = compute_reg_resx_bits(kvm, &sctlr_el1_desc, 0, 0);
1450-
resx.res1 |= SCTLR_EL1_RES1;
14511479
break;
14521480
case MDCR_EL2:
14531481
resx = compute_reg_resx_bits(kvm, &mdcr_el2_desc, 0, 0);
1454-
resx.res1 |= MDCR_EL2_RES1;
14551482
break;
14561483
case VTCR_EL2:
14571484
resx = compute_reg_resx_bits(kvm, &vtcr_el2_desc, 0, 0);
1458-
resx.res1 |= VTCR_EL2_RES1;
14591485
break;
14601486
default:
14611487
WARN_ON_ONCE(1);

0 commit comments

Comments
 (0)