[PATCH 12/20] KVM: arm64: Add RESx_WHEN_E2Hx constraints as configuration flags
Marc Zyngier
maz at kernel.org
Mon Jan 26 04:16:46 PST 2026
"Thanks" to VHE, SCTLR_EL2 radically changes shape depending on the
value of HCR_EL2.E2H, as a lot of the bits that didn't have much
meaning with E2H=0 start impacting EL0 with E2H=1.
This has a direct impact on the RESx behaviour of these bits, and
we need a way to express them.
For this purpose, introduce a set of 4 new constaints that, when
the controlling feature is not present, force the RESx value to
be either 0 or 1 depending on the value of E2H.
This allows diverging RESx values depending on the value of E2H,
something that is required by a bunch of SCTLR_EL2 bits.
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
arch/arm64/kvm/config.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
index 1990cebc77c66..7063fffc22799 100644
--- a/arch/arm64/kvm/config.c
+++ b/arch/arm64/kvm/config.c
@@ -26,6 +26,10 @@ struct reg_bits_to_feat_map {
#define MASKS_POINTER BIT(3) /* Pointer to fgt_masks struct instead of bits */
#define AS_RES1 BIT(4) /* RES1 when not supported */
#define REQUIRES_E2H1 BIT(5) /* Add HCR_EL2.E2H RES1 as a pre-condition */
+#define RES0_WHEN_E2H0 BIT(6) /* RES0 when E2H=0 and not supported */
+#define RES0_WHEN_E2H1 BIT(7) /* RES0 when E2H=1 and not supported */
+#define RES1_WHEN_E2H0 BIT(8) /* RES1 when E2H=0 and not supported */
+#define RES1_WHEN_E2H1 BIT(9) /* RES1 when E2H=1 and not supported */
unsigned long flags;
@@ -1298,10 +1302,24 @@ struct resx compute_resx_bits(struct kvm *kvm,
match &= !e2h0;
if (!match) {
+ u64 bits = reg_feat_map_bits(&map[i]);
+
+ if (e2h0) {
+ if (map[i].flags & RES1_WHEN_E2H0)
+ resx.res1 |= bits;
+ else if (map[i].flags & RES0_WHEN_E2H0)
+ resx.res0 |= bits;
+ } else {
+ if (map[i].flags & RES1_WHEN_E2H1)
+ resx.res1 |= bits;
+ else if (map[i].flags & RES0_WHEN_E2H1)
+ resx.res0 |= bits;
+ }
+
if (map[i].flags & AS_RES1)
- resx.res1 |= reg_feat_map_bits(&map[i]);
- else
- resx.res0 |= reg_feat_map_bits(&map[i]);
+ resx.res1 |= bits;
+ else if (!(resx.res1 & bits))
+ resx.res0 |= bits;
}
}
--
2.47.3
More information about the linux-arm-kernel
mailing list