]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: arm64: nv: Use literal granule size in TLBI range calculation
authorWei-Lin Chang <weilin.chang@arm.com>
Tue, 14 Apr 2026 00:03:33 +0000 (01:03 +0100)
committerMarc Zyngier <maz@kernel.org>
Thu, 28 May 2026 08:59:49 +0000 (09:59 +0100)
TLBI handling derives the invalidation range from guest VTCR_EL2.TG0 in
get_guest_mapping_ttl() and compute_tlb_inval_range(). Switch these to
use a helper that returns the decoded VTCR_EL2.TG0 granule size instead
of decoding it inline.

This keeps the granule size derivation in one place and prepares for
following changes that adjust the effective granule size.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
Link: https://patch.msgid.link/20260414000334.3947257-4-weilin.chang@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/nested.c

index a88e5dfddd2b80fdecb280ed89d013643ba810ed..bc95e43c54dd769a82f8c9c8656958f65b8cc33c 100644 (file)
@@ -394,6 +394,11 @@ static unsigned int vtcr_to_tg0_pgshift(u64 vtcr)
        }
 }
 
+static size_t vtcr_to_tg0_pgsize(u64 vtcr)
+{
+       return BIT(vtcr_to_tg0_pgshift(vtcr));
+}
+
 static void setup_s2_walk(struct kvm_vcpu *vcpu, struct s2_walk_info *wi)
 {
        u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
@@ -516,20 +521,21 @@ static u8 pgshift_level_to_ttl(u16 shift, u8 level)
  */
 static u8 get_guest_mapping_ttl(struct kvm_s2_mmu *mmu, u64 addr)
 {
-       u64 tmp, sz = 0, vtcr = mmu->tlb_vtcr;
+       u64 tmp, sz = 0;
        kvm_pte_t pte;
        u8 ttl, level;
+       size_t tg0_size = vtcr_to_tg0_pgsize(mmu->tlb_vtcr);
 
        lockdep_assert_held_write(&kvm_s2_mmu_to_kvm(mmu)->mmu_lock);
 
-       switch (FIELD_GET(VTCR_EL2_TG0_MASK, vtcr)) {
-       case VTCR_EL2_TG0_4K:
+       switch (tg0_size) {
+       case SZ_4K:
                ttl = (TLBI_TTL_TG_4K << 2);
                break;
-       case VTCR_EL2_TG0_16K:
+       case SZ_16K:
                ttl = (TLBI_TTL_TG_16K << 2);
                break;
-       case VTCR_EL2_TG0_64K:
+       case SZ_64K:
        default:            /* IMPDEF: treat any other value as 64k */
                ttl = (TLBI_TTL_TG_64K << 2);
                break;
@@ -539,19 +545,19 @@ static u8 get_guest_mapping_ttl(struct kvm_s2_mmu *mmu, u64 addr)
 
 again:
        /* Iteratively compute the block sizes for a particular granule size */
-       switch (FIELD_GET(VTCR_EL2_TG0_MASK, vtcr)) {
-       case VTCR_EL2_TG0_4K:
+       switch (tg0_size) {
+       case SZ_4K:
                if      (sz < SZ_4K)    sz = SZ_4K;
                else if (sz < SZ_2M)    sz = SZ_2M;
                else if (sz < SZ_1G)    sz = SZ_1G;
                else                    sz = 0;
                break;
-       case VTCR_EL2_TG0_16K:
+       case SZ_16K:
                if      (sz < SZ_16K)   sz = SZ_16K;
                else if (sz < SZ_32M)   sz = SZ_32M;
                else                    sz = 0;
                break;
-       case VTCR_EL2_TG0_64K:
+       case SZ_64K:
        default:            /* IMPDEF: treat any other value as 64k */
                if      (sz < SZ_64K)   sz = SZ_64K;
                else if (sz < SZ_512M)  sz = SZ_512M;
@@ -602,14 +608,14 @@ unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val)
 
        if (!max_size) {
                /* Compute the maximum extent of the invalidation */
-               switch (FIELD_GET(VTCR_EL2_TG0_MASK, mmu->tlb_vtcr)) {
-               case VTCR_EL2_TG0_4K:
+               switch (vtcr_to_tg0_pgsize(mmu->tlb_vtcr)) {
+               case SZ_4K:
                        max_size = SZ_1G;
                        break;
-               case VTCR_EL2_TG0_16K:
+               case SZ_16K:
                        max_size = SZ_32M;
                        break;
-               case VTCR_EL2_TG0_64K:
+               case SZ_64K:
                default:    /* IMPDEF: treat any other value as 64k */
                        /*
                         * No, we do not support 52bit IPA in nested yet. Once