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: Simplify FIXED_VALUE handling

The FIXED_VALUE qualifier (mostly used for HCR_EL2) is pointlessly
complicated, as it tries to piggy-back on the previous RES0 handling
while being done in a different phase, on different data.

Instead, make it an integral part of the RESx computation, and allow
it to directly set RESx bits. This is much easier to understand.

It also paves the way for some additional changes to that will allow
the full removal of the FIXED_VALUE handling.

Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Link: https://patch.msgid.link/20260202184329.2724080-11-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>

+22 -44
+22 -44
arch/arm64/kvm/config.c
··· 37 37 s8 lo_lim; 38 38 }; 39 39 bool (*match)(struct kvm *); 40 - bool (*fval)(struct kvm *, u64 *); 40 + bool (*fval)(struct kvm *, struct resx *); 41 41 }; 42 42 }; 43 43 ··· 389 389 return kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16); 390 390 } 391 391 392 - static bool compute_hcr_e2h(struct kvm *kvm, u64 *bits) 392 + static bool compute_hcr_e2h(struct kvm *kvm, struct resx *bits) 393 393 { 394 - if (bits) { 395 - if (kvm_has_feat(kvm, FEAT_E2H0)) 396 - *bits &= ~HCR_EL2_E2H; 397 - else 398 - *bits |= HCR_EL2_E2H; 399 - } 394 + if (kvm_has_feat(kvm, FEAT_E2H0)) 395 + bits->res0 |= HCR_EL2_E2H; 396 + else 397 + bits->res1 |= HCR_EL2_E2H; 400 398 401 399 return true; 402 400 } ··· 1278 1280 } 1279 1281 } 1280 1282 1281 - static struct resx __compute_fixed_bits(struct kvm *kvm, 1282 - const struct reg_bits_to_feat_map *map, 1283 - int map_size, 1284 - u64 *fixed_bits, 1285 - unsigned long require, 1286 - unsigned long exclude) 1283 + static struct resx compute_resx_bits(struct kvm *kvm, 1284 + const struct reg_bits_to_feat_map *map, 1285 + int map_size, 1286 + unsigned long require, 1287 + unsigned long exclude) 1287 1288 { 1288 1289 struct resx resx = {}; 1289 1290 ··· 1295 1298 if (map[i].flags & exclude) 1296 1299 continue; 1297 1300 1298 - if (map[i].flags & CALL_FUNC) 1299 - match = (map[i].flags & FIXED_VALUE) ? 1300 - map[i].fval(kvm, fixed_bits) : 1301 - map[i].match(kvm); 1302 - else 1301 + switch (map[i].flags & (CALL_FUNC | FIXED_VALUE)) { 1302 + case CALL_FUNC | FIXED_VALUE: 1303 + map[i].fval(kvm, &resx); 1304 + continue; 1305 + case CALL_FUNC: 1306 + match = map[i].match(kvm); 1307 + break; 1308 + default: 1303 1309 match = idreg_feat_match(kvm, &map[i]); 1310 + } 1304 1311 1305 - if (!match || (map[i].flags & FIXED_VALUE)) { 1312 + if (!match) { 1306 1313 if (map[i].flags & AS_RES1) 1307 1314 resx.res1 |= reg_feat_map_bits(&map[i]); 1308 1315 else ··· 1315 1314 } 1316 1315 1317 1316 return resx; 1318 - } 1319 - 1320 - static struct resx compute_resx_bits(struct kvm *kvm, 1321 - const struct reg_bits_to_feat_map *map, 1322 - int map_size, 1323 - unsigned long require, 1324 - unsigned long exclude) 1325 - { 1326 - return __compute_fixed_bits(kvm, map, map_size, NULL, 1327 - require, exclude | FIXED_VALUE); 1328 1317 } 1329 1318 1330 1319 static struct resx compute_reg_resx_bits(struct kvm *kvm, ··· 1357 1366 return resx.res0 | resx.res1; 1358 1367 } 1359 1368 1360 - static struct resx compute_reg_fixed_bits(struct kvm *kvm, 1361 - const struct reg_feat_map_desc *r, 1362 - u64 *fixed_bits, 1363 - unsigned long require, 1364 - unsigned long exclude) 1365 - { 1366 - return __compute_fixed_bits(kvm, r->bit_feat_map, r->bit_feat_map_sz, 1367 - fixed_bits, require | FIXED_VALUE, exclude); 1368 - } 1369 - 1370 1369 void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt) 1371 1370 { 1372 1371 u64 val = 0; ··· 1396 1415 1397 1416 struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg) 1398 1417 { 1399 - u64 fixed = 0, mask; 1400 1418 struct resx resx; 1401 1419 1402 1420 switch (reg) { ··· 1437 1457 resx.res1 |= __HCRX_EL2_RES1; 1438 1458 break; 1439 1459 case HCR_EL2: 1440 - mask = compute_reg_fixed_bits(kvm, &hcr_desc, &fixed, 0, 0).res0; 1441 1460 resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0); 1442 - resx.res0 |= (mask & ~fixed); 1443 - resx.res1 |= HCR_EL2_RES1 | (mask & fixed); 1461 + resx.res1 |= HCR_EL2_RES1; 1444 1462 break; 1445 1463 case SCTLR2_EL1: 1446 1464 case SCTLR2_EL2: