Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+37 -11
+37 -11
arch/arm64/kvm/config.c
··· 28 28 #define REQUIRES_E2H1 BIT(5) /* Add HCR_EL2.E2H RES1 as a pre-condition */ 29 29 #define RES1_WHEN_E2H0 BIT(6) /* RES1 when E2H=0 and not supported */ 30 30 #define RES1_WHEN_E2H1 BIT(7) /* RES1 when E2H=1 and not supported */ 31 + #define FORCE_RESx BIT(8) /* Unconditional RESx */ 31 32 32 33 unsigned long flags; 33 34 ··· 88 87 .match = (fun), \ 89 88 } 90 89 90 + #define __NEEDS_FEAT_0(m, f, w, ...) \ 91 + { \ 92 + .w = (m), \ 93 + .flags = (f), \ 94 + } 95 + 91 96 #define __NEEDS_FEAT_FLAG(m, f, w, ...) \ 92 97 CONCATENATE(__NEEDS_FEAT_, COUNT_ARGS(__VA_ARGS__))(m, f, w, __VA_ARGS__) 93 98 ··· 112 105 */ 113 106 #define NEEDS_FEAT(m, ...) NEEDS_FEAT_FLAG(m, 0, __VA_ARGS__) 114 107 108 + /* Declare fixed RESx bits */ 109 + #define FORCE_RES0(m) NEEDS_FEAT_FLAG(m, FORCE_RESx) 110 + #define FORCE_RES1(m) NEEDS_FEAT_FLAG(m, FORCE_RESx | AS_RES1) 111 + 115 112 /* 116 - * Declare the dependency between a non-FGT register, a set of 117 - * feature, and the set of individual bits it contains. This generates 118 - * a struct reg_feat_map_desc. 113 + * Declare the dependency between a non-FGT register, a set of features, 114 + * and the set of individual bits it contains. This generates a struct 115 + * reg_feat_map_desc. 119 116 */ 120 117 #define DECLARE_FEAT_MAP(n, r, m, f) \ 121 118 struct reg_feat_map_desc n = { \ ··· 1018 1007 HCR_EL2_TWEDEn, 1019 1008 FEAT_TWED), 1020 1009 NEEDS_FEAT_FIXED(HCR_EL2_E2H, compute_hcr_e2h), 1010 + FORCE_RES0(HCR_EL2_RES0), 1011 + FORCE_RES1(HCR_EL2_RES1), 1021 1012 }; 1022 1013 1023 1014 static const DECLARE_FEAT_MAP(hcr_desc, HCR_EL2, ··· 1040 1027 SCTLR2_EL1_CPTM | 1041 1028 SCTLR2_EL1_CPTM0, 1042 1029 FEAT_CPA2), 1030 + FORCE_RES0(SCTLR2_EL1_RES0), 1031 + FORCE_RES1(SCTLR2_EL1_RES1), 1043 1032 }; 1044 1033 1045 1034 static const DECLARE_FEAT_MAP(sctlr2_desc, SCTLR2_EL1, ··· 1067 1052 TCR2_EL2_E0POE, 1068 1053 FEAT_S1POE), 1069 1054 NEEDS_FEAT(TCR2_EL2_PIE, FEAT_S1PIE), 1055 + FORCE_RES0(TCR2_EL2_RES0), 1056 + FORCE_RES1(TCR2_EL2_RES1), 1070 1057 }; 1071 1058 1072 1059 static const DECLARE_FEAT_MAP(tcr2_el2_desc, TCR2_EL2, ··· 1146 1129 SCTLR_EL1_A | 1147 1130 SCTLR_EL1_M, 1148 1131 FEAT_AA64EL1), 1132 + FORCE_RES0(SCTLR_EL1_RES0), 1133 + FORCE_RES1(SCTLR_EL1_RES1), 1149 1134 }; 1150 1135 1151 1136 static const DECLARE_FEAT_MAP(sctlr_el1_desc, SCTLR_EL1, ··· 1182 1163 MDCR_EL2_TDE | 1183 1164 MDCR_EL2_TDRA, 1184 1165 FEAT_AA64EL1), 1166 + FORCE_RES0(MDCR_EL2_RES0), 1167 + FORCE_RES1(MDCR_EL2_RES1), 1185 1168 }; 1186 1169 1187 1170 static const DECLARE_FEAT_MAP(mdcr_el2_desc, MDCR_EL2, ··· 1222 1201 VTCR_EL2_SL0 | 1223 1202 VTCR_EL2_T0SZ, 1224 1203 FEAT_AA64EL1), 1204 + FORCE_RES0(VTCR_EL2_RES0), 1205 + FORCE_RES1(VTCR_EL2_RES1), 1225 1206 }; 1226 1207 1227 1208 static const DECLARE_FEAT_MAP(vtcr_el2_desc, VTCR_EL2, ··· 1234 1211 { 1235 1212 u64 mask = 0; 1236 1213 1214 + /* 1215 + * Don't account for FORCE_RESx that are architectural, and 1216 + * therefore part of the resx parameter. Other FORCE_RESx bits 1217 + * are implementation choices, and therefore accounted for. 1218 + */ 1237 1219 for (int i = 0; i < map_size; i++) 1238 - mask |= map[i].bits; 1220 + if (!((map[i].flags & FORCE_RESx) && (map[i].bits & resx))) 1221 + mask |= map[i].bits; 1239 1222 1240 1223 if (mask != ~resx) 1241 1224 kvm_err("Undefined %s behaviour, bits %016llx\n", ··· 1313 1284 if (map[i].flags & exclude) 1314 1285 continue; 1315 1286 1316 - switch (map[i].flags & (CALL_FUNC | FIXED_VALUE)) { 1287 + switch (map[i].flags & (FORCE_RESx | CALL_FUNC | FIXED_VALUE)) { 1317 1288 case CALL_FUNC | FIXED_VALUE: 1318 1289 map[i].fval(kvm, &resx); 1319 1290 continue; 1320 1291 case CALL_FUNC: 1321 1292 match = map[i].match(kvm); 1293 + break; 1294 + case FORCE_RESx: 1295 + match = false; 1322 1296 break; 1323 1297 default: 1324 1298 match = idreg_feat_match(kvm, &map[i]); ··· 1466 1434 break; 1467 1435 case HCR_EL2: 1468 1436 resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0); 1469 - resx.res1 |= HCR_EL2_RES1; 1470 1437 break; 1471 1438 case SCTLR2_EL1: 1472 1439 case SCTLR2_EL2: 1473 1440 resx = compute_reg_resx_bits(kvm, &sctlr2_desc, 0, 0); 1474 - resx.res1 |= SCTLR2_EL1_RES1; 1475 1441 break; 1476 1442 case TCR2_EL2: 1477 1443 resx = compute_reg_resx_bits(kvm, &tcr2_el2_desc, 0, 0); 1478 - resx.res1 |= TCR2_EL2_RES1; 1479 1444 break; 1480 1445 case SCTLR_EL1: 1481 1446 resx = compute_reg_resx_bits(kvm, &sctlr_el1_desc, 0, 0); 1482 - resx.res1 |= SCTLR_EL1_RES1; 1483 1447 break; 1484 1448 case MDCR_EL2: 1485 1449 resx = compute_reg_resx_bits(kvm, &mdcr_el2_desc, 0, 0); 1486 - resx.res1 |= MDCR_EL2_RES1; 1487 1450 break; 1488 1451 case VTCR_EL2: 1489 1452 resx = compute_reg_resx_bits(kvm, &vtcr_el2_desc, 0, 0); 1490 - resx.res1 |= VTCR_EL2_RES1; 1491 1453 break; 1492 1454 default: 1493 1455 WARN_ON_ONCE(1);