]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: arm64: Add RES1_WHEN_E2Hx constraints as configuration flags
authorMarc Zyngier <maz@kernel.org>
Mon, 2 Feb 2026 18:43:21 +0000 (18:43 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 5 Feb 2026 09:02:12 +0000 (09:02 +0000)
"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 two new constaints that, when the
controlling feature is not present, force the field to RES1 depending
on the value of E2H. Note that RES0 is still implicit,

This allows diverging RESx values depending on the value of E2H,
something that is required by a bunch of SCTLR_EL2 bits.

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

index 84c577672e97a185605653ae0172ca0b7f0ea3ba..7e8e42c1cee4a28f02ab5771ea6bf2a0e164a757 100644 (file)
@@ -26,6 +26,8 @@ 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        RES1_WHEN_E2H0  BIT(6)  /* RES1 when E2H=0 and not supported */
+#define        RES1_WHEN_E2H1  BIT(7)  /* RES1 when E2H=1 and not supported */
 
        unsigned long   flags;
 
@@ -1297,10 +1299,14 @@ static struct resx compute_resx_bits(struct kvm *kvm,
                        match &= !e2h0;
 
                if (!match) {
-                       if (map[i].flags & AS_RES1)
-                               resx.res1 |= reg_feat_map_bits(&map[i]);
+                       u64 bits = reg_feat_map_bits(&map[i]);
+
+                       if ((map[i].flags & AS_RES1)                    ||
+                           (e2h0 && (map[i].flags & RES1_WHEN_E2H0))   ||
+                           (!e2h0 && (map[i].flags & RES1_WHEN_E2H1)))
+                               resx.res1 |= bits;
                        else
-                               resx.res0 |= reg_feat_map_bits(&map[i]);
+                               resx.res0 |= bits;
                }
        }