Skip to content

Commit 54e367c

Browse files
author
Marc Zyngier
committed
KVM: arm64: Deduplicate ASID retrieval code
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>
1 parent 29c8b85 commit 54e367c

File tree

3 files changed

+35
-54
lines changed

3 files changed

+35
-54
lines changed

arch/arm64/include/asm/kvm_nested.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ int kvm_vcpu_allocate_vncr_tlb(struct kvm_vcpu *vcpu);
397397
int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu);
398398
void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val);
399399

400+
u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime);
401+
400402
#define vncr_fixmap(c) \
401403
({ \
402404
u32 __c = (c); \

arch/arm64/kvm/at.c

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -540,31 +540,8 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
540540
wr->pa |= va & GENMASK_ULL(va_bottom - 1, 0);
541541

542542
wr->nG = (wi->regime != TR_EL2) && (desc & PTE_NG);
543-
if (wr->nG) {
544-
u64 asid_ttbr, tcr;
545-
546-
switch (wi->regime) {
547-
case TR_EL10:
548-
tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
549-
asid_ttbr = ((tcr & TCR_A1) ?
550-
vcpu_read_sys_reg(vcpu, TTBR1_EL1) :
551-
vcpu_read_sys_reg(vcpu, TTBR0_EL1));
552-
break;
553-
case TR_EL20:
554-
tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
555-
asid_ttbr = ((tcr & TCR_A1) ?
556-
vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
557-
vcpu_read_sys_reg(vcpu, TTBR0_EL2));
558-
break;
559-
default:
560-
BUG();
561-
}
562-
563-
wr->asid = FIELD_GET(TTBR_ASID_MASK, asid_ttbr);
564-
if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
565-
!(tcr & TCR_ASID16))
566-
wr->asid &= GENMASK(7, 0);
567-
}
543+
if (wr->nG)
544+
wr->asid = get_asid_by_regime(vcpu, wi->regime);
568545

569546
return 0;
570547

arch/arm64/kvm/nested.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,33 @@ int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2)
854854
return kvm_inject_nested_sync(vcpu, esr_el2);
855855
}
856856

857+
u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime)
858+
{
859+
enum vcpu_sysreg ttbr_elx;
860+
u64 tcr;
861+
u16 asid;
862+
863+
switch (regime) {
864+
case TR_EL10:
865+
tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
866+
ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL1 : TTBR0_EL1;
867+
break;
868+
case TR_EL20:
869+
tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
870+
ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL2 : TTBR0_EL2;
871+
break;
872+
default:
873+
BUG();
874+
}
875+
876+
asid = FIELD_GET(TTBRx_EL1_ASID, vcpu_read_sys_reg(vcpu, ttbr_elx));
877+
if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
878+
!(tcr & TCR_ASID16))
879+
asid &= GENMASK(7, 0);
880+
881+
return asid;
882+
}
883+
857884
static void invalidate_vncr(struct vncr_tlb *vt)
858885
{
859886
vt->valid = false;
@@ -1333,20 +1360,8 @@ static bool kvm_vncr_tlb_lookup(struct kvm_vcpu *vcpu)
13331360
if (read_vncr_el2(vcpu) != vt->gva)
13341361
return false;
13351362

1336-
if (vt->wr.nG) {
1337-
u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
1338-
u64 ttbr = ((tcr & TCR_A1) ?
1339-
vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
1340-
vcpu_read_sys_reg(vcpu, TTBR0_EL2));
1341-
u16 asid;
1342-
1343-
asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
1344-
if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
1345-
!(tcr & TCR_ASID16))
1346-
asid &= GENMASK(7, 0);
1347-
1348-
return asid == vt->wr.asid;
1349-
}
1363+
if (vt->wr.nG)
1364+
return get_asid_by_regime(vcpu, TR_EL20) == vt->wr.asid;
13501365

13511366
return true;
13521367
}
@@ -1449,21 +1464,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
14491464
if (read_vncr_el2(vcpu) != vt->gva)
14501465
return;
14511466

1452-
if (vt->wr.nG) {
1453-
u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
1454-
u64 ttbr = ((tcr & TCR_A1) ?
1455-
vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
1456-
vcpu_read_sys_reg(vcpu, TTBR0_EL2));
1457-
u16 asid;
1458-
1459-
asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
1460-
if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
1461-
!(tcr & TCR_ASID16))
1462-
asid &= GENMASK(7, 0);
1463-
1464-
if (asid != vt->wr.asid)
1465-
return;
1466-
}
1467+
if (vt->wr.nG && get_asid_by_regime(vcpu, TR_EL20) != vt->wr.asid)
1468+
return;
14671469

14681470
vt->cpu = smp_processor_id();
14691471

0 commit comments

Comments
 (0)