linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Marc Zyngier <maz@kernel.org>
Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	kvm@vger.kernel.org, Joey Gouly <joey.gouly@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Oliver Upton <oupton@kernel.org>,
	Zenghui Yu <yuzenghui@huawei.com>
Subject: Re: [PATCH 2/4] arm64: Convert VTCR_EL2 to sysreg infratructure
Date: Wed, 3 Dec 2025 11:43:14 +0000	[thread overview]
Message-ID: <aTAiUuc_aK5Bgce0@raptor> (raw)
In-Reply-To: <20251129144525.2609207-3-maz@kernel.org>

Hi Marc,

On Sat, Nov 29, 2025 at 02:45:23PM +0000, Marc Zyngier wrote:
> Our definition of VTCR_EL2 is both partial (tons of fields are
> missing) and totally inconsistent (some constants are shifted,
> some are not). They are also expressed in terms of TCR, which is
> rather inconvenient.
> 
> Replace the ad-hoc definitions with the the generated version.
> This results in a bunch of additional changes to make the code
> with the unshifted nature of generated enumerations.
> 
> The register data was extracted from the BSD licenced AARCHMRS
> (AARCHMRS_OPENSOURCE_A_profile_FAT-2025-09_ASL0).

Looks correct to me:

Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>

Thanks,
Alex

> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 52 +++++++----------------------
>  arch/arm64/include/asm/sysreg.h  |  1 -
>  arch/arm64/kvm/hyp/pgtable.c     |  8 ++---
>  arch/arm64/kvm/nested.c          |  8 ++---
>  arch/arm64/tools/sysreg          | 57 ++++++++++++++++++++++++++++++++
>  5 files changed, 76 insertions(+), 50 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 1da290aeedce7..cd2dc378baee6 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -123,37 +123,7 @@
>  #define TCR_EL2_MASK	(TCR_EL2_TG0_MASK | TCR_EL2_SH0_MASK | \
>  			 TCR_EL2_ORGN0_MASK | TCR_EL2_IRGN0_MASK)
>  
> -/* VTCR_EL2 Registers bits */
> -#define VTCR_EL2_DS		TCR_EL2_DS
> -#define VTCR_EL2_RES1		(1U << 31)
> -#define VTCR_EL2_HD		(1 << 22)
> -#define VTCR_EL2_HA		(1 << 21)
> -#define VTCR_EL2_PS_SHIFT	TCR_EL2_PS_SHIFT
> -#define VTCR_EL2_PS_MASK	TCR_EL2_PS_MASK
> -#define VTCR_EL2_TG0_MASK	TCR_TG0_MASK
> -#define VTCR_EL2_TG0_4K		TCR_TG0_4K
> -#define VTCR_EL2_TG0_16K	TCR_TG0_16K
> -#define VTCR_EL2_TG0_64K	TCR_TG0_64K
> -#define VTCR_EL2_SH0_MASK	TCR_SH0_MASK
> -#define VTCR_EL2_SH0_INNER	TCR_SH0_INNER
> -#define VTCR_EL2_ORGN0_MASK	TCR_ORGN0_MASK
> -#define VTCR_EL2_ORGN0_WBWA	TCR_ORGN0_WBWA
> -#define VTCR_EL2_IRGN0_MASK	TCR_IRGN0_MASK
> -#define VTCR_EL2_IRGN0_WBWA	TCR_IRGN0_WBWA
> -#define VTCR_EL2_SL0_SHIFT	6
> -#define VTCR_EL2_SL0_MASK	(3 << VTCR_EL2_SL0_SHIFT)
> -#define VTCR_EL2_T0SZ_MASK	0x3f
> -#define VTCR_EL2_VS_SHIFT	19
> -#define VTCR_EL2_VS_8BIT	(0 << VTCR_EL2_VS_SHIFT)
> -#define VTCR_EL2_VS_16BIT	(1 << VTCR_EL2_VS_SHIFT)
> -
> -#define VTCR_EL2_T0SZ(x)	TCR_T0SZ(x)
> -
>  /*
> - * We configure the Stage-2 page tables to always restrict the IPA space to be
> - * 40 bits wide (T0SZ = 24).  Systems with a PARange smaller than 40 bits are
> - * not known to exist and will break with this configuration.
> - *
>   * The VTCR_EL2 is configured per VM and is initialised in kvm_init_stage2_mmu.
>   *
>   * Note that when using 4K pages, we concatenate two first level page tables
> @@ -161,9 +131,6 @@
>   *
>   */
>  
> -#define VTCR_EL2_COMMON_BITS	(VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
> -				 VTCR_EL2_IRGN0_WBWA | VTCR_EL2_RES1)
> -
>  /*
>   * VTCR_EL2:SL0 indicates the entry level for Stage2 translation.
>   * Interestingly, it depends on the page size.
> @@ -195,30 +162,35 @@
>   */
>  #ifdef CONFIG_ARM64_64K_PAGES
>  
> -#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_64K
> +#define VTCR_EL2_TGRAN			64K
>  #define VTCR_EL2_TGRAN_SL0_BASE		3UL
>  
>  #elif defined(CONFIG_ARM64_16K_PAGES)
>  
> -#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_16K
> +#define VTCR_EL2_TGRAN			16K
>  #define VTCR_EL2_TGRAN_SL0_BASE		3UL
>  
>  #else	/* 4K */
>  
> -#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_4K
> +#define VTCR_EL2_TGRAN			4K
>  #define VTCR_EL2_TGRAN_SL0_BASE		2UL
>  
>  #endif
>  
>  #define VTCR_EL2_LVLS_TO_SL0(levels)	\
> -	((VTCR_EL2_TGRAN_SL0_BASE - (4 - (levels))) << VTCR_EL2_SL0_SHIFT)
> +	FIELD_PREP(VTCR_EL2_SL0, (VTCR_EL2_TGRAN_SL0_BASE - (4 - (levels))))
>  #define VTCR_EL2_SL0_TO_LVLS(sl0)	\
>  	((sl0) + 4 - VTCR_EL2_TGRAN_SL0_BASE)
>  #define VTCR_EL2_LVLS(vtcr)		\
> -	VTCR_EL2_SL0_TO_LVLS(((vtcr) & VTCR_EL2_SL0_MASK) >> VTCR_EL2_SL0_SHIFT)
> +	VTCR_EL2_SL0_TO_LVLS(FIELD_GET(VTCR_EL2_SL0, (vtcr)))
> +
> +#define VTCR_EL2_FLAGS	(SYS_FIELD_PREP_ENUM(VTCR_EL2, SH0, INNER)	    | \
> +			 SYS_FIELD_PREP_ENUM(VTCR_EL2, ORGN0, WBWA)	    | \
> +			 SYS_FIELD_PREP_ENUM(VTCR_EL2, IRGN0, WBWA)	    | \
> +			 SYS_FIELD_PREP_ENUM(VTCR_EL2, TG0, VTCR_EL2_TGRAN) | \
> +			 VTCR_EL2_RES1)
>  
> -#define VTCR_EL2_FLAGS			(VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN)
> -#define VTCR_EL2_IPA(vtcr)		(64 - ((vtcr) & VTCR_EL2_T0SZ_MASK))
> +#define VTCR_EL2_IPA(vtcr)		(64 - FIELD_GET(VTCR_EL2_T0SZ, (vtcr)))
>  
>  /*
>   * ARM VMSAv8-64 defines an algorithm for finding the translation table
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index c231d2a3e5159..acad7a7621b9e 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -516,7 +516,6 @@
>  #define SYS_TTBR1_EL2			sys_reg(3, 4, 2, 0, 1)
>  #define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
>  #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
> -#define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
>  
>  #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
>  #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 947ac1a951a5b..e0bd6a0172729 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -583,8 +583,8 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
>  	u64 vtcr = VTCR_EL2_FLAGS;
>  	s8 lvls;
>  
> -	vtcr |= kvm_get_parange(mmfr0) << VTCR_EL2_PS_SHIFT;
> -	vtcr |= VTCR_EL2_T0SZ(phys_shift);
> +	vtcr |= FIELD_PREP(VTCR_EL2_PS, kvm_get_parange(mmfr0));
> +	vtcr |= FIELD_PREP(VTCR_EL2_T0SZ, (UL(64) - phys_shift));
>  	/*
>  	 * Use a minimum 2 level page table to prevent splitting
>  	 * host PMD huge pages at stage2.
> @@ -624,9 +624,7 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
>  		vtcr |= VTCR_EL2_DS;
>  
>  	/* Set the vmid bits */
> -	vtcr |= (get_vmid_bits(mmfr1) == 16) ?
> -		VTCR_EL2_VS_16BIT :
> -		VTCR_EL2_VS_8BIT;
> +	vtcr |= (get_vmid_bits(mmfr1) == 16) ? VTCR_EL2_VS : 0;
>  
>  	return vtcr;
>  }
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 911fc99ed99d9..e1ef8930c97b3 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -377,7 +377,7 @@ static void vtcr_to_walk_info(u64 vtcr, struct s2_walk_info *wi)
>  {
>  	wi->t0sz = vtcr & TCR_EL2_T0SZ_MASK;
>  
> -	switch (vtcr & VTCR_EL2_TG0_MASK) {
> +	switch (FIELD_GET(VTCR_EL2_TG0_MASK, vtcr)) {
>  	case VTCR_EL2_TG0_4K:
>  		wi->pgshift = 12;	 break;
>  	case VTCR_EL2_TG0_16K:
> @@ -513,7 +513,7 @@ static u8 get_guest_mapping_ttl(struct kvm_s2_mmu *mmu, u64 addr)
>  
>  	lockdep_assert_held_write(&kvm_s2_mmu_to_kvm(mmu)->mmu_lock);
>  
> -	switch (vtcr & VTCR_EL2_TG0_MASK) {
> +	switch (FIELD_GET(VTCR_EL2_TG0_MASK, vtcr)) {
>  	case VTCR_EL2_TG0_4K:
>  		ttl = (TLBI_TTL_TG_4K << 2);
>  		break;
> @@ -530,7 +530,7 @@ 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 (vtcr & VTCR_EL2_TG0_MASK) {
> +	switch (FIELD_GET(VTCR_EL2_TG0_MASK, vtcr)) {
>  	case VTCR_EL2_TG0_4K:
>  		if	(sz < SZ_4K)	sz = SZ_4K;
>  		else if (sz < SZ_2M)	sz = SZ_2M;
> @@ -593,7 +593,7 @@ unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val)
>  
>  	if (!max_size) {
>  		/* Compute the maximum extent of the invalidation */
> -		switch (mmu->tlb_vtcr & VTCR_EL2_TG0_MASK) {
> +		switch (FIELD_GET(VTCR_EL2_TG0_MASK, mmu->tlb_vtcr)) {
>  		case VTCR_EL2_TG0_4K:
>  			max_size = SZ_1G;
>  			break;
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 9d388f87d9a13..6f43b2ae5993b 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -4400,6 +4400,63 @@ Field	56:12	BADDR
>  Res0	11:0
>  EndSysreg
>  
> +Sysreg	VTCR_EL2	3	4	2	1	2
> +Res0	63:46	
> +Field	45	HDBSS
> +Field	44	HAFT
> +Res0	43:42	
> +Field	41	TL0
> +Field	40	GCSH
> +Res0	39
> +Field	38	D128
> +Field	37	S2POE
> +Field	36	S2PIE
> +Field	35	TL1
> +Field	34	AssuredOnly
> +Field	33	SL2
> +Field	32	DS
> +Res1	31
> +Field	30	NSA
> +Field	29	NSW
> +Field	28	HWU62
> +Field	27	HWU61
> +Field	26	HWU60
> +Field	25	HWU59
> +Res0	24:23
> +Field	22	HD
> +Field	21	HA
> +Res0	20
> +Enum	19	VS
> +	0b0	8BIT
> +	0b1	16BIT
> +EndEnum
> +Field	18:16	PS
> +Enum	15:14	TG0
> +	0b00	4K
> +	0b01	64K
> +	0b10	16K
> +EndEnum
> +Enum	13:12	SH0
> +	0b00	NONE
> +	0b01	OUTER
> +	0b11	INNER
> +EndEnum
> +Enum	11:10	ORGN0
> +	0b00	NC
> +	0b01	WBWA
> +	0b10	WT
> +	0b11	WBnWA
> +EndEnum
> +Enum	9:8	IRGN0
> +	0b00	NC
> +	0b01	WBWA
> +	0b10	WT
> +	0b11	WBnWA
> +EndEnum
> +Field	7:6	SL0
> +Field	5:0	T0SZ
> +EndSysreg
> +
>  Sysreg	GCSCR_EL2	3	4	2	5	0
>  Fields	GCSCR_ELx
>  EndSysreg
> -- 
> 2.47.3
> 


  reply	other threads:[~2025-12-03 11:43 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-29 14:45 [PATCH 0/4] KVM: arm64: VTCR_EL2 conversion to feature dependency framework Marc Zyngier
2025-11-29 14:45 ` [PATCH 1/4] arm64: Convert ID_AA64MMFR0_EL1.TGRAN{4,16,64}_2 to UnsignedEnum Marc Zyngier
2025-11-29 14:45 ` [PATCH 2/4] arm64: Convert VTCR_EL2 to sysreg infratructure Marc Zyngier
2025-12-03 11:43   ` Alexandru Elisei [this message]
2025-11-29 14:45 ` [PATCH 3/4] KVM: arm64: Account for RES1 bits in DECLARE_FEAT_MAP() Marc Zyngier
2025-11-29 14:45 ` [PATCH 4/4] KVM: arm64: Convert VTCR_EL2 to config-driven sanitisation Marc Zyngier
2025-12-03 11:44   ` Alexandru Elisei
2025-12-03 13:00     ` Marc Zyngier
2025-12-03 14:03       ` Alexandru Elisei
2025-12-03 14:58         ` Marc Zyngier
2025-12-03 15:20           ` Alexandru Elisei
2025-12-03 16:17   ` Joey Gouly
2025-12-03 16:43     ` Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aTAiUuc_aK5Bgce0@raptor \
    --to=alexandru.elisei@arm.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=yuzenghui@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).