Add VTCR_EL2 register fields as per the latest ARM ARM DDI 0487 7.B in
tools sysreg format and drop the existing macros from the header
(arch/arm64/include/asm/kvm_arm.h). While here also drop an explicit
sysreg definction SYS_VTCR_EL2 from sysreg.h header.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Mark Brown <broonie@kernel.org>
Cc: kvmarm@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm64/include/asm/kvm_arm.h | 32 +++---------------
arch/arm64/include/asm/sysreg.h | 1 -
arch/arm64/kvm/hyp/pgtable.c | 6 ++--
arch/arm64/kvm/nested.c | 2 +-
arch/arm64/tools/sysreg | 57 ++++++++++++++++++++++++++++++++
5 files changed, 66 insertions(+), 32 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 8994cddef182..5abe3536f1d2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -110,31 +110,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_EL1_TG0_MASK
-#define VTCR_EL2_TG0_4K (TCR_EL1_TG0_4K << TCR_EL1_TG0_SHIFT)
-#define VTCR_EL2_TG0_16K (TCR_EL1_TG0_16K << TCR_EL1_TG0_SHIFT)
-#define VTCR_EL2_TG0_64K (TCR_EL1_TG0_64K << TCR_EL1_TG0_SHIFT)
-#define VTCR_EL2_SH0_MASK TCR_EL1_SH0_MASK
-#define VTCR_EL2_SH0_INNER (TCR_EL1_SH0_INNER << TCR_EL1_SH0_SHIFT)
-#define VTCR_EL2_ORGN0_MASK TCR_EL1_ORGN0_MASK
-#define VTCR_EL2_ORGN0_WBWA (TCR_EL1_ORGN0_WBWA << TCR_EL1_ORGN0_SHIFT)
-#define VTCR_EL2_IRGN0_MASK TCR_EL1_IRGN0_MASK
-#define VTCR_EL2_IRGN0_WBWA (TCR_EL1_IRGN0_WBWA << TCR_EL1_IRGN0_SHIFT)
-#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)
+#define VTCR_T0SZ(x) ((UL(64) - (x)) << VTCR_EL2_T0SZ_SHIFT)
/*
* We configure the Stage-2 page tables to always restrict the IPA space to be
@@ -148,8 +124,10 @@
*
*/
-#define VTCR_EL2_COMMON_BITS (VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
- VTCR_EL2_IRGN0_WBWA | VTCR_EL2_RES1)
+#define VTCR_EL2_COMMON_BITS ((VTCR_EL2_SH0_INNER << VTCR_EL2_SH0_SHIFT) | \
+ (VTCR_EL2_ORGN0_WBWA << VTCR_EL2_ORGN0_SHIFT) | \
+ (VTCR_EL2_IRGN0_WBWA << VTCR_EL2_IRGN0_SHIFT) | \
+ (VTCR_EL2_RES1))
/*
* VTCR_EL2:SL0 indicates the entry level for Stage2 translation.
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 112d5d0acb50..ea0a7e5a8628 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -524,7 +524,6 @@
#define SYS_TTBR0_EL2 sys_reg(3, 4, 2, 0, 0)
#define SYS_TTBR1_EL2 sys_reg(3, 4, 2, 0, 1)
#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 c351b4abd5db..c1607b5b7cbf 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -584,7 +584,7 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
s8 lvls;
vtcr |= kvm_get_parange(mmfr0) << VTCR_EL2_PS_SHIFT;
- vtcr |= VTCR_EL2_T0SZ(phys_shift);
+ vtcr |= VTCR_T0SZ(phys_shift);
/*
* Use a minimum 2 level page table to prevent splitting
* host PMD huge pages at stage2.
@@ -625,8 +625,8 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
/* Set the vmid bits */
vtcr |= (get_vmid_bits(mmfr1) == 16) ?
- VTCR_EL2_VS_16BIT :
- VTCR_EL2_VS_8BIT;
+ SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 16BIT) :
+ SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 8BIT);
return vtcr;
}
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 7b1802a4072e..34d8d192d5c2 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -336,7 +336,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 (SYS_FIELD_GET(VTCR_EL2, TG0, vtcr)) {
case VTCR_EL2_TG0_4K:
wi->pgshift = 12; break;
case VTCR_EL2_TG0_16K:
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index d2b40105eb41..f5a0a304f844 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -4910,6 +4910,63 @@ Field 1 PIE
Field 0 PnCH
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
+UnsignedEnum 19 VS
+ 0b0 8BIT
+ 0b1 16BIT
+EndEnum
+Field 18:16 PS
+UnsignedEnum 15:14 TG0
+ 0b00 4K
+ 0b01 64K
+ 0b10 16K
+EndEnum
+UnsignedEnum 13:12 SH0
+ 0b00 NONE
+ 0b10 OUTER
+ 0b11 INNER
+EndEnum
+UnsignedEnum 11:10 ORGN0
+ 0b00 NC
+ 0b01 WBWA
+ 0b10 WT
+ 0b11 WBnWA
+EndEnum
+UnsignedEnum 9:8 IRGN0
+ 0b00 NC
+ 0b01 WBWA
+ 0b10 WT
+ 0b11 WBnWA
+EndEnum
+Field 7:6 SL0
+Field 5:0 T0SZ
+EndSysreg
+
SysregFields MAIR2_ELx
Field 63:56 Attr7
Field 55:48 Attr6
--
2.25.1
On Mon, Aug 18, 2025 at 10:27:59AM +0530, Anshuman Khandual wrote: > diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg > index d2b40105eb41..f5a0a304f844 100644 > --- a/arch/arm64/tools/sysreg > +++ b/arch/arm64/tools/sysreg > @@ -4910,6 +4910,63 @@ Field 1 PIE > Field 0 PnCH > 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 > +UnsignedEnum 19 VS > + 0b0 8BIT > + 0b1 16BIT > +EndEnum You left TCR_EL1.AS as a single-bit 'Field', so please do the same here for consistency. I don't think there's much gained by making this any sort of enum. > +Field 18:16 PS > +UnsignedEnum 15:14 TG0 > + 0b00 4K > + 0b01 64K > + 0b10 16K > +EndEnum As with other patches, this is not ordered. Please use Enum. Likewise for the other cases below. Mark. > +UnsignedEnum 13:12 SH0 > + 0b00 NONE > + 0b10 OUTER > + 0b11 INNER > +EndEnum > +UnsignedEnum 11:10 ORGN0 > + 0b00 NC > + 0b01 WBWA > + 0b10 WT > + 0b11 WBnWA > +EndEnum > +UnsignedEnum 9:8 IRGN0 > + 0b00 NC > + 0b01 WBWA > + 0b10 WT > + 0b11 WBnWA > +EndEnum > +Field 7:6 SL0 > +Field 5:0 T0SZ > +EndSysreg > + > SysregFields MAIR2_ELx > Field 63:56 Attr7 > Field 55:48 Attr6 > -- > 2.25.1 > >
On 18/08/25 2:52 PM, Mark Rutland wrote:
> On Mon, Aug 18, 2025 at 10:27:59AM +0530, Anshuman Khandual wrote:
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index d2b40105eb41..f5a0a304f844 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -4910,6 +4910,63 @@ Field 1 PIE
>> Field 0 PnCH
>> 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
>> +UnsignedEnum 19 VS
>> + 0b0 8BIT
>> + 0b1 16BIT
>> +EndEnum
>
> You left TCR_EL1.AS as a single-bit 'Field', so please do the same here
> for consistency. I don't think there's much gained by making this any
> sort of enum.
But actually there is an use case in kvm_get_vtcr().
/* Set the vmid bits */
vtcr |= (get_vmid_bits(mmfr1) == 16) ?
SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 16BIT) :
SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 8BIT);
>
>> +Field 18:16 PS
>> +UnsignedEnum 15:14 TG0
>> + 0b00 4K
>> + 0b01 64K
>> + 0b10 16K
>> +EndEnum
>
> As with other patches, this is not ordered. Please use Enum.
>
> Likewise for the other cases below.
Sure, will do the changes.
>
> Mark.
>
>> +UnsignedEnum 13:12 SH0
>> + 0b00 NONE
>> + 0b10 OUTER
>> + 0b11 INNER
>> +EndEnum
>> +UnsignedEnum 11:10 ORGN0
>> + 0b00 NC
>> + 0b01 WBWA
>> + 0b10 WT
>> + 0b11 WBnWA
>> +EndEnum
>> +UnsignedEnum 9:8 IRGN0
>> + 0b00 NC
>> + 0b01 WBWA
>> + 0b10 WT
>> + 0b11 WBnWA
>> +EndEnum
>> +Field 7:6 SL0
>> +Field 5:0 T0SZ
>> +EndSysreg
>> +
>> SysregFields MAIR2_ELx
>> Field 63:56 Attr7
>> Field 55:48 Attr6
>> --
>> 2.25.1
>>
>>
On Tue, 19 Aug 2025 05:24:29 +0100, Anshuman Khandual <anshuman.khandual@arm.com> wrote: > > > > On 18/08/25 2:52 PM, Mark Rutland wrote: > > On Mon, Aug 18, 2025 at 10:27:59AM +0530, Anshuman Khandual wrote: > >> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg > >> index d2b40105eb41..f5a0a304f844 100644 > >> --- a/arch/arm64/tools/sysreg > >> +++ b/arch/arm64/tools/sysreg > >> @@ -4910,6 +4910,63 @@ Field 1 PIE > >> Field 0 PnCH > >> 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 > >> +UnsignedEnum 19 VS > >> + 0b0 8BIT > >> + 0b1 16BIT > >> +EndEnum > > > > You left TCR_EL1.AS as a single-bit 'Field', so please do the same here > > for consistency. I don't think there's much gained by making this any > > sort of enum. > > But actually there is an use case in kvm_get_vtcr(). > > /* Set the vmid bits */ > vtcr |= (get_vmid_bits(mmfr1) == 16) ? > SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 16BIT) : > SYS_FIELD_PREP_ENUM(VTCR_EL2, VS, 8BIT); > Here you go (untested): diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index c351b4abd5db..49266efc8bab 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -623,10 +623,7 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift) if (kvm_lpa2_is_enabled()) vtcr |= VTCR_EL2_DS; - /* Set the vmid bits */ - vtcr |= (get_vmid_bits(mmfr1) == 16) ? - VTCR_EL2_VS_16BIT : - VTCR_EL2_VS_8BIT; + vtcr |= FIELD_PREP(BIT(VTCR_EL2_VS_SHIFT), (get_vmid_bits(mmfr1) == 16)); return vtcr; } M. -- Jazz isn't dead. It just smells funny.
© 2016 - 2026 Red Hat, Inc.