]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
KVM: arm64: Deduplicate ASID retrieval code
authorMarc Zyngier <maz@kernel.org>
Wed, 25 Feb 2026 10:47:18 +0000 (10:47 +0000)
committerMarc Zyngier <maz@kernel.org>
Wed, 25 Feb 2026 12:19:33 +0000 (12:19 +0000)
We currently have three versions of the ASID retrieval code, one
in the S1 walker, and two in the VNCR handling (although the last
two are limited to the EL2&0 translation regime).

Make this code common, and take this opportunity to also simplify
the code a bit while switching over to the TTBRx_EL1_ASID macro.

Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20260225104718.14209-1-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_nested.h
arch/arm64/kvm/at.c
arch/arm64/kvm/nested.c

index 905c658057a4319e25f7168ef34849d1c5c5ccb8..091544e6af442e0362e69fecd8ce35312b4aee65 100644 (file)
@@ -397,6 +397,8 @@ int kvm_vcpu_allocate_vncr_tlb(struct kvm_vcpu *vcpu);
 int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu);
 void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val);
 
+u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime);
+
 #define vncr_fixmap(c)                                         \
        ({                                                      \
                u32 __c = (c);                                  \
index 885bd5bb2f416652e9e43df7af4fea5b9470aa2a..6588ea251ed777bc74025ff7260c13410a0a5419 100644 (file)
@@ -540,31 +540,8 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
        wr->pa |= va & GENMASK_ULL(va_bottom - 1, 0);
 
        wr->nG = (wi->regime != TR_EL2) && (desc & PTE_NG);
-       if (wr->nG) {
-               u64 asid_ttbr, tcr;
-
-               switch (wi->regime) {
-               case TR_EL10:
-                       tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
-                       asid_ttbr = ((tcr & TCR_A1) ?
-                                    vcpu_read_sys_reg(vcpu, TTBR1_EL1) :
-                                    vcpu_read_sys_reg(vcpu, TTBR0_EL1));
-                       break;
-               case TR_EL20:
-                       tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
-                       asid_ttbr = ((tcr & TCR_A1) ?
-                                    vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
-                                    vcpu_read_sys_reg(vcpu, TTBR0_EL2));
-                       break;
-               default:
-                       BUG();
-               }
-
-               wr->asid = FIELD_GET(TTBR_ASID_MASK, asid_ttbr);
-               if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
-                   !(tcr & TCR_ASID16))
-                       wr->asid &= GENMASK(7, 0);
-       }
+       if (wr->nG)
+               wr->asid = get_asid_by_regime(vcpu, wi->regime);
 
        return 0;
 
index 7f1ea85dc67ab9cf73bc402d06d27334110ed18e..787776aaf4ad1721d0972e77fbdbd06014bc1a3d 100644 (file)
@@ -854,6 +854,33 @@ int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2)
        return kvm_inject_nested_sync(vcpu, esr_el2);
 }
 
+u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime)
+{
+       enum vcpu_sysreg ttbr_elx;
+       u64 tcr;
+       u16 asid;
+
+       switch (regime) {
+       case TR_EL10:
+               tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
+               ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL1 : TTBR0_EL1;
+               break;
+       case TR_EL20:
+               tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+               ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL2 : TTBR0_EL2;
+               break;
+       default:
+               BUG();
+       }
+
+       asid = FIELD_GET(TTBRx_EL1_ASID, vcpu_read_sys_reg(vcpu, ttbr_elx));
+       if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
+           !(tcr & TCR_ASID16))
+               asid &= GENMASK(7, 0);
+
+       return asid;
+}
+
 static void invalidate_vncr(struct vncr_tlb *vt)
 {
        vt->valid = false;
@@ -1333,20 +1360,8 @@ static bool kvm_vncr_tlb_lookup(struct kvm_vcpu *vcpu)
        if (read_vncr_el2(vcpu) != vt->gva)
                return false;
 
-       if (vt->wr.nG) {
-               u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
-               u64 ttbr = ((tcr & TCR_A1) ?
-                           vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
-                           vcpu_read_sys_reg(vcpu, TTBR0_EL2));
-               u16 asid;
-
-               asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
-               if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
-                   !(tcr & TCR_ASID16))
-                       asid &= GENMASK(7, 0);
-
-               return asid == vt->wr.asid;
-       }
+       if (vt->wr.nG)
+               return get_asid_by_regime(vcpu, TR_EL20) == vt->wr.asid;
 
        return true;
 }
@@ -1449,21 +1464,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
        if (read_vncr_el2(vcpu) != vt->gva)
                return;
 
-       if (vt->wr.nG) {
-               u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
-               u64 ttbr = ((tcr & TCR_A1) ?
-                           vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
-                           vcpu_read_sys_reg(vcpu, TTBR0_EL2));
-               u16 asid;
-
-               asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
-               if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
-                   !(tcr & TCR_ASID16))
-                       asid &= GENMASK(7, 0);
-
-               if (asid != vt->wr.asid)
-                       return;
-       }
+       if (vt->wr.nG && get_asid_by_regime(vcpu, TR_EL20) != vt->wr.asid)
+               return;
 
        vt->cpu = smp_processor_id();