public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] KVM: arm64: Deduplicate ASID retrieval code
@ 2026-02-25 10:47 Marc Zyngier
  2026-02-25 11:24 ` Jonathan Cameron
  2026-02-25 11:35 ` Joey Gouly
  0 siblings, 2 replies; 3+ messages in thread
From: Marc Zyngier @ 2026-02-25 10:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu

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 transltion 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.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  2 +
 arch/arm64/kvm/at.c                 | 27 +------------
 arch/arm64/kvm/nested.c             | 60 +++++++++++++++--------------
 3 files changed, 35 insertions(+), 54 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 905c658057a43..091544e6af442 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -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);					\
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
index 885bd5bb2f416..6588ea251ed77 100644
--- a/arch/arm64/kvm/at.c
+++ b/arch/arm64/kvm/at.c
@@ -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;
 
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 7f1ea85dc67ab..787776aaf4ad1 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -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();
 
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: arm64: Deduplicate ASID retrieval code
  2026-02-25 10:47 [PATCH] KVM: arm64: Deduplicate ASID retrieval code Marc Zyngier
@ 2026-02-25 11:24 ` Jonathan Cameron
  2026-02-25 11:35 ` Joey Gouly
  1 sibling, 0 replies; 3+ messages in thread
From: Jonathan Cameron @ 2026-02-25 11:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, Joey Gouly, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu

On Wed, 25 Feb 2026 10:47:18 +0000
Marc Zyngier <maz@kernel.org> wrote:

> 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 transltion 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.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Does what it says on the tin.

Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: arm64: Deduplicate ASID retrieval code
  2026-02-25 10:47 [PATCH] KVM: arm64: Deduplicate ASID retrieval code Marc Zyngier
  2026-02-25 11:24 ` Jonathan Cameron
@ 2026-02-25 11:35 ` Joey Gouly
  1 sibling, 0 replies; 3+ messages in thread
From: Joey Gouly @ 2026-02-25 11:35 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu

On Wed, Feb 25, 2026 at 10:47:18AM +0000, Marc Zyngier wrote:
> 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 transltion 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.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Reviewed-by: Joey Gouly <joey.gouly@arm.com>

> ---
>  arch/arm64/include/asm/kvm_nested.h |  2 +
>  arch/arm64/kvm/at.c                 | 27 +------------
>  arch/arm64/kvm/nested.c             | 60 +++++++++++++++--------------
>  3 files changed, 35 insertions(+), 54 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 905c658057a43..091544e6af442 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -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);					\
> diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
> index 885bd5bb2f416..6588ea251ed77 100644
> --- a/arch/arm64/kvm/at.c
> +++ b/arch/arm64/kvm/at.c
> @@ -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;
>  
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 7f1ea85dc67ab..787776aaf4ad1 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -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();
>  
> -- 
> 2.47.3
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-02-25 11:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-25 10:47 [PATCH] KVM: arm64: Deduplicate ASID retrieval code Marc Zyngier
2026-02-25 11:24 ` Jonathan Cameron
2026-02-25 11:35 ` Joey Gouly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox