* [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
2026-08-25 21:18 [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
@ 2026-08-25 21:18 ` Itaru Kitayama
2026-09-04 8:38 ` Fuad Tabba
2026-08-25 21:18 ` [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes Itaru Kitayama
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Itaru Kitayama @ 2026-08-25 21:18 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Itaru Kitayama, Takayuki Okamoto
Add p4d_index() for when 5-level paging required, i.e., V52 guest mode
IDs. With the index helper function, _virt_pg_map() handles 5-level
paging case, and aarch64_vcpu_setup() now is aware of the new V52 guest
mode IDs.
Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
---
.../selftests/kvm/include/arm64/processor.h | 2 +
tools/testing/selftests/kvm/lib/arm64/processor.c | 87 ++++++++++++++++++++--
2 files changed, 84 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/arm64/processor.h b/tools/testing/selftests/kvm/include/arm64/processor.h
index b8a902ba8573..a6fd7a9b379e 100644
--- a/tools/testing/selftests/kvm/include/arm64/processor.h
+++ b/tools/testing/selftests/kvm/include/arm64/processor.h
@@ -113,6 +113,7 @@
#define PTE_VALID BIT(0)
#define PGD_TYPE_TABLE BIT(1)
+#define P4D_TYPE_TABLE BIT(1)
#define PUD_TYPE_TABLE BIT(1)
#define PMD_TYPE_TABLE BIT(1)
#define PTE_TYPE_PAGE BIT(1)
@@ -167,6 +168,7 @@ enum {
(v) == VECTOR_SYNC_LOWER_64 || \
(v) == VECTOR_SYNC_LOWER_32)
+u32 aarch64_get_supported_va_size(void);
void aarch64_get_supported_page_sizes(u32 ipa, u32 *ipa4k,
u32 *ipa16k, u32 *ipa64k);
diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
index 01325bf4d36f..9108e14a9b5b 100644
--- a/tools/testing/selftests/kvm/lib/arm64/processor.c
+++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
@@ -29,13 +29,25 @@ static u64 pgd_index(struct kvm_vm *vm, gva_t gva)
return (gva >> shift) & mask;
}
+static u64 p4d_index(struct kvm_vm *vm, gva_t gva)
+{
+ unsigned int shift = 3 * (vm->page_shift - 3) + vm->page_shift;
+ u64 mask = (1UL << (vm->page_shift - 3)) - 1;
+
+ TEST_ASSERT(vm->mmu.pgtable_levels == 5,
+ "Mode %d does not have 5 page table levels", vm->mode);
+
+ return (gva >> shift) & mask;
+}
+
static u64 pud_index(struct kvm_vm *vm, gva_t gva)
{
unsigned int shift = 2 * (vm->page_shift - 3) + vm->page_shift;
u64 mask = (1UL << (vm->page_shift - 3)) - 1;
- TEST_ASSERT(vm->mmu.pgtable_levels == 4,
- "Mode %d does not have 4 page table levels", vm->mode);
+ TEST_ASSERT(vm->mmu.pgtable_levels >= 4,
+ "Mode %d does not have at least 4 page table levels",
+ vm->mode);
return (gva >> shift) & mask;
}
@@ -147,6 +159,12 @@ static void _virt_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
PGD_TYPE_TABLE | PTE_VALID);
switch (vm->mmu.pgtable_levels) {
+ case 5:
+ ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + p4d_index(vm, gva) * 8;
+ if (!*ptep)
+ *ptep = addr_pte(vm, vm_alloc_page_table(vm),
+ P4D_TYPE_TABLE | PTE_VALID);
+ /* fall through */
case 4:
ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pud_index(vm, gva) * 8;
if (!*ptep)
@@ -163,7 +181,7 @@ static void _virt_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pte_index(vm, gva) * 8;
break;
default:
- TEST_FAIL("Page table levels must be 2, 3, or 4");
+ TEST_FAIL("Page table levels must be 2, 3, 4, or 5");
}
pg_attr = PTE_AF | PTE_ATTRINDX(attr_idx) | PTE_TYPE_PAGE | PTE_VALID;
@@ -182,18 +200,35 @@ void virt_arch_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa)
u64 *virt_get_pte_hva_at_level(struct kvm_vm *vm, gva_t gva, int level)
{
+ int start_level = 4 - vm->mmu.pgtable_levels;
u64 *ptep;
+ TEST_ASSERT(level >= start_level && level <= 3,
+ "Invalid translation level %d, valid range is %d-3",
+ level, start_level);
+
if (!vm->mmu.pgd_created)
goto unmapped_gva;
ptep = addr_gpa2hva(vm, vm->mmu.pgd) + pgd_index(vm, gva) * 8;
if (!ptep)
goto unmapped_gva;
- if (level == 0)
+ /*
+ * Stage-1 translation starts at level -1 for a five-level page
+ * table, and at levels 0, 1, or 2 for four-, three-, or two-level
+ * page tables, respectively.
+ */
+ if (level == start_level)
return ptep;
switch (vm->mmu.pgtable_levels) {
+ case 5:
+ ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + p4d_index(vm, gva) * 8;
+ if (!ptep)
+ goto unmapped_gva;
+ if (level == 0)
+ break;
+ /* fall through */
case 4:
ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pud_index(vm, gva) * 8;
if (!ptep)
@@ -214,7 +249,7 @@ u64 *virt_get_pte_hva_at_level(struct kvm_vm *vm, gva_t gva, int level)
goto unmapped_gva;
break;
default:
- TEST_FAIL("Page table levels must be 2, 3, or 4");
+ TEST_FAIL("Page table levels must be 2, 3, 4, or 5");
}
return ptep;
@@ -321,12 +356,14 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
case VM_MODE_PXXVYY_4K:
TEST_FAIL("AArch64 does not support 4K sized pages "
"with ANY-bit physical address ranges");
+ case VM_MODE_P52V52_64K:
case VM_MODE_P52V48_64K:
case VM_MODE_P48V48_64K:
case VM_MODE_P40V48_64K:
case VM_MODE_P36V48_64K:
tcr_el1 |= TCR_TG0_64K;
break;
+ case VM_MODE_P52V52_16K:
case VM_MODE_P52V48_16K:
case VM_MODE_P48V48_16K:
case VM_MODE_P40V48_16K:
@@ -334,6 +371,7 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
case VM_MODE_P36V47_16K:
tcr_el1 |= TCR_TG0_16K;
break;
+ case VM_MODE_P52V52_4K:
case VM_MODE_P52V48_4K:
case VM_MODE_P48V48_4K:
case VM_MODE_P40V48_4K:
@@ -348,6 +386,9 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
/* Configure output size */
switch (vm->mode) {
+ case VM_MODE_P52V52_4K:
+ case VM_MODE_P52V52_16K:
+ case VM_MODE_P52V52_64K:
case VM_MODE_P52V48_4K:
case VM_MODE_P52V48_16K:
case VM_MODE_P52V48_64K:
@@ -578,6 +619,42 @@ static u32 max_ipa_for_page_size(u32 vm_ipa, u32 gran,
return min(vm_ipa, 48U);
}
+u32 aarch64_get_supported_va_size(void)
+{
+ struct kvm_vcpu_init preferred_init = {};
+ int kvm_fd, vm_fd, vcpu_fd, err;
+ u64 val;
+ u32 va_range;
+ struct kvm_one_reg reg = {
+ .id = KVM_ARM64_SYS_REG(SYS_ID_AA64MMFR2_EL1),
+ .addr = (u64)&val,
+ };
+
+ kvm_fd = open_kvm_dev_path_or_exit();
+ vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
+ TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
+
+ vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
+ TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
+
+ err = ioctl(vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
+ TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_PREFERRED_TARGET, err));
+
+ err = ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &preferred_init);
+ TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_VCPU_INIT, err));
+
+ err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
+ TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, err));
+
+ va_range = FIELD_GET(ID_AA64MMFR2_EL1_VARange, val);
+
+ close(vcpu_fd);
+ close(vm_fd);
+ close(kvm_fd);
+
+ return va_range >= ID_AA64MMFR2_EL1_VARange_52 ? 52 : 48;
+}
+
void aarch64_get_supported_page_sizes(u32 ipa, u32 *ipa4k,
u32 *ipa16k, u32 *ipa64k)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
2026-08-25 21:18 ` [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table Itaru Kitayama
@ 2026-09-04 8:38 ` Fuad Tabba
2026-09-08 1:44 ` Itaru Kitayama
0 siblings, 1 reply; 13+ messages in thread
From: Fuad Tabba @ 2026-09-04 8:38 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Itaru,
The usual subject prefix in the tree is "KVM: arm64: selftests:", for
this patch and the next one.
On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
>
> Add p4d_index() for when 5-level paging required, i.e., V52 guest mode
> IDs. With the index helper function, _virt_pg_map() handles 5-level
Only VM_MODE_P52V52_4K has five levels. The 16K and 64K V52 modes get
four and three, so this is for the 4K granule rather than for V52
modes as a class.
...
> u64 *virt_get_pte_hva_at_level(struct kvm_vm *vm, gva_t gva, int level)
> {
> + int start_level = 4 - vm->mmu.pgtable_levels;
> u64 *ptep;
>
> + TEST_ASSERT(level >= start_level && level <= 3,
> + "Invalid translation level %d, valid range is %d-3",
> + level, start_level);
> +
> if (!vm->mmu.pgd_created)
> goto unmapped_gva;
>
> ptep = addr_gpa2hva(vm, vm->mmu.pgd) + pgd_index(vm, gva) * 8;
> if (!ptep)
> goto unmapped_gva;
> - if (level == 0)
> + /*
> + * Stage-1 translation starts at level -1 for a five-level page
> + * table, and at levels 0, 1, or 2 for four-, three-, or two-level
> + * page tables, respectively.
> + */
> + if (level == start_level)
This changes what level means for the existing three-level modes:
level 0 used to return the top-level entry and now trips the assert,
level 1 used to return the leaf and now returns the top level. No
caller in tree asks for either of those two levels, and the new
numbering matches the architecture.
...
> @@ -321,12 +356,14 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
> case VM_MODE_PXXVYY_4K:
> TEST_FAIL("AArch64 does not support 4K sized pages "
> "with ANY-bit physical address ranges");
> + case VM_MODE_P52V52_64K:
These VM_MODE_ enumerators arrive in patch 2, so this patch does not
build on its own:
lib/arm64/processor.c:359:7: error: use of undeclared identifier
'VM_MODE_P52V52_64K'; did you mean 'VM_MODE_P52V48_64K'?
lib/arm64/processor.c:360:7: error: duplicate case value 'VM_MODE_P52V48_64K'
There are other build errors from the same cause. Could you move the
enum values and their vm_guest_mode_string()/vm_guest_mode_params[]
entries into this patch, or a new one altogether?
> case VM_MODE_P52V48_64K:
> case VM_MODE_P48V48_64K:
> case VM_MODE_P40V48_64K:
> case VM_MODE_P36V48_64K:
> tcr_el1 |= TCR_TG0_64K;
> break;
> + case VM_MODE_P52V52_16K:
> case VM_MODE_P52V48_16K:
> case VM_MODE_P48V48_16K:
> case VM_MODE_P40V48_16K:
> @@ -334,6 +371,7 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
> case VM_MODE_P36V47_16K:
> tcr_el1 |= TCR_TG0_16K;
> break;
> + case VM_MODE_P52V52_4K:
> case VM_MODE_P52V48_4K:
> case VM_MODE_P48V48_4K:
> case VM_MODE_P40V48_4K:
> @@ -348,6 +386,9 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
>
> /* Configure output size */
> switch (vm->mode) {
> + case VM_MODE_P52V52_4K:
> + case VM_MODE_P52V52_16K:
> + case VM_MODE_P52V52_64K:
> case VM_MODE_P52V48_4K:
> case VM_MODE_P52V48_16K:
> case VM_MODE_P52V48_64K:
> @@ -578,6 +619,42 @@ static u32 max_ipa_for_page_size(u32 vm_ipa, u32 gran,
> return min(vm_ipa, 48U);
> }
>
> +u32 aarch64_get_supported_va_size(void)
This repeats aarch64_get_supported_page_sizes() below it and builds a
second probe VM one line after the first. Could it take a u32 *va
out-param, so both ID registers come off the one vCPU?
VARange is the 52-bit VA indicator for the 64K granule only, so a bare
52 or 48 reads as granule-independent. The caller in patch 2 only uses
it for 64K, so nothing is wrong today.
Cheers,
/fuad
> +{
> + struct kvm_vcpu_init preferred_init = {};
> + int kvm_fd, vm_fd, vcpu_fd, err;
> + u64 val;
> + u32 va_range;
> + struct kvm_one_reg reg = {
> + .id = KVM_ARM64_SYS_REG(SYS_ID_AA64MMFR2_EL1),
> + .addr = (u64)&val,
> + };
> +
> + kvm_fd = open_kvm_dev_path_or_exit();
> + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
> + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
> +
> + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
> + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
> +
> + err = ioctl(vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
> + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_PREFERRED_TARGET, err));
> +
> + err = ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &preferred_init);
> + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_VCPU_INIT, err));
> +
> + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
> + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, err));
> +
> + va_range = FIELD_GET(ID_AA64MMFR2_EL1_VARange, val);
> +
> + close(vcpu_fd);
> + close(vm_fd);
> + close(kvm_fd);
> +
> + return va_range >= ID_AA64MMFR2_EL1_VARange_52 ? 52 : 48;
> +}
> +
> void aarch64_get_supported_page_sizes(u32 ipa, u32 *ipa4k,
> u32 *ipa16k, u32 *ipa64k)
> {
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
2026-09-04 8:38 ` Fuad Tabba
@ 2026-09-08 1:44 ` Itaru Kitayama
2026-09-08 8:08 ` Fuad Tabba
0 siblings, 1 reply; 13+ messages in thread
From: Itaru Kitayama @ 2026-09-08 1:44 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Fuad,
On Fri, Sep 04, 2026 at 09:38:39AM +0100, Fuad Tabba wrote:
> Hi Itaru,
>
> The usual subject prefix in the tree is "KVM: arm64: selftests:", for
> this patch and the next one.
Sure. Fix in v2.
> On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
> >
> > Add p4d_index() for when 5-level paging required, i.e., V52 guest mode
> > IDs. With the index helper function, _virt_pg_map() handles 5-level
>
> Only VM_MODE_P52V52_4K has five levels. The 16K and 64K V52 modes get
> four and three, so this is for the 4K granule rather than for V52
> modes as a class.
Yes, understood. Will update the commit log.
>
> ...
>
> > u64 *virt_get_pte_hva_at_level(struct kvm_vm *vm, gva_t gva, int level)
> > {
> > + int start_level = 4 - vm->mmu.pgtable_levels;
> > u64 *ptep;
> >
> > + TEST_ASSERT(level >= start_level && level <= 3,
> > + "Invalid translation level %d, valid range is %d-3",
> > + level, start_level);
> > +
> > if (!vm->mmu.pgd_created)
> > goto unmapped_gva;
> >
> > ptep = addr_gpa2hva(vm, vm->mmu.pgd) + pgd_index(vm, gva) * 8;
> > if (!ptep)
> > goto unmapped_gva;
> > - if (level == 0)
> > + /*
> > + * Stage-1 translation starts at level -1 for a five-level page
> > + * table, and at levels 0, 1, or 2 for four-, three-, or two-level
> > + * page tables, respectively.
> > + */
> > + if (level == start_level)
>
>
> This changes what level means for the existing three-level modes:
> level 0 used to return the top-level entry and now trips the assert,
> level 1 used to return the leaf and now returns the top level. No
> caller in tree asks for either of those two levels, and the new
> numbering matches the architecture.
Yes, as you checked this change won't break current tests, so if you
have better comments I will replace it with yours.
>
> ...
>
> > @@ -321,12 +356,14 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
> > case VM_MODE_PXXVYY_4K:
> > TEST_FAIL("AArch64 does not support 4K sized pages "
> > "with ANY-bit physical address ranges");
> > + case VM_MODE_P52V52_64K:
>
> These VM_MODE_ enumerators arrive in patch 2, so this patch does not
> build on its own:
>
> lib/arm64/processor.c:359:7: error: use of undeclared identifier
> 'VM_MODE_P52V52_64K'; did you mean 'VM_MODE_P52V48_64K'?
> lib/arm64/processor.c:360:7: error: duplicate case value 'VM_MODE_P52V48_64K'
>
> There are other build errors from the same cause. Could you move the
> enum values and their vm_guest_mode_string()/vm_guest_mode_params[]
> entries into this patch, or a new one altogether?
Yes, I have rearranged the series to avoid this.
>
> > case VM_MODE_P52V48_64K:
> > case VM_MODE_P48V48_64K:
> > case VM_MODE_P40V48_64K:
> > case VM_MODE_P36V48_64K:
> > tcr_el1 |= TCR_TG0_64K;
> > break;
> > + case VM_MODE_P52V52_16K:
> > case VM_MODE_P52V48_16K:
> > case VM_MODE_P48V48_16K:
> > case VM_MODE_P40V48_16K:
> > @@ -334,6 +371,7 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
> > case VM_MODE_P36V47_16K:
> > tcr_el1 |= TCR_TG0_16K;
> > break;
> > + case VM_MODE_P52V52_4K:
> > case VM_MODE_P52V48_4K:
> > case VM_MODE_P48V48_4K:
> > case VM_MODE_P40V48_4K:
> > @@ -348,6 +386,9 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
> >
> > /* Configure output size */
> > switch (vm->mode) {
> > + case VM_MODE_P52V52_4K:
> > + case VM_MODE_P52V52_16K:
> > + case VM_MODE_P52V52_64K:
> > case VM_MODE_P52V48_4K:
> > case VM_MODE_P52V48_16K:
> > case VM_MODE_P52V48_64K:
> > @@ -578,6 +619,42 @@ static u32 max_ipa_for_page_size(u32 vm_ipa, u32 gran,
> > return min(vm_ipa, 48U);
> > }
> >
> > +u32 aarch64_get_supported_va_size(void)
>
> This repeats aarch64_get_supported_page_sizes() below it and builds a
> second probe VM one line after the first. Could it take a u32 *va
> out-param, so both ID registers come off the one vCPU?
>
> VARange is the 52-bit VA indicator for the 64K granule only, so a bare
> 52 or 48 reads as granule-independent. The caller in patch 2 only uses
> it for 64K, so nothing is wrong today.
Yes, I've dropped the _va_size() function and instead, expanded a bit
as you suggested the aarch64_get_supported_page_sizes() to check if vcpu
can address upto 52-bit VA space or not (48-bit max).
Thanks,
Itaru.
>
> Cheers,
> /fuad
>
>
> > +{
> > + struct kvm_vcpu_init preferred_init = {};
> > + int kvm_fd, vm_fd, vcpu_fd, err;
> > + u64 val;
> > + u32 va_range;
> > + struct kvm_one_reg reg = {
> > + .id = KVM_ARM64_SYS_REG(SYS_ID_AA64MMFR2_EL1),
> > + .addr = (u64)&val,
> > + };
> > +
> > + kvm_fd = open_kvm_dev_path_or_exit();
> > + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
> > + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
> > +
> > + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
> > + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
> > +
> > + err = ioctl(vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
> > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_PREFERRED_TARGET, err));
> > +
> > + err = ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &preferred_init);
> > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_VCPU_INIT, err));
> > +
> > + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
> > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, err));
> > +
> > + va_range = FIELD_GET(ID_AA64MMFR2_EL1_VARange, val);
> > +
> > + close(vcpu_fd);
> > + close(vm_fd);
> > + close(kvm_fd);
> > +
> > + return va_range >= ID_AA64MMFR2_EL1_VARange_52 ? 52 : 48;
> > +}
> > +
> > void aarch64_get_supported_page_sizes(u32 ipa, u32 *ipa4k,
> > u32 *ipa16k, u32 *ipa64k)
> > {
> >
> > --
> > 2.43.0
> >
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
2026-09-08 1:44 ` Itaru Kitayama
@ 2026-09-08 8:08 ` Fuad Tabba
0 siblings, 0 replies; 13+ messages in thread
From: Fuad Tabba @ 2026-09-08 8:08 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Itaru,
On Tue, 8 Sept 2026 at 02:44, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
...
> > This changes what level means for the existing three-level modes:
> > level 0 used to return the top-level entry and now trips the assert,
> > level 1 used to return the leaf and now returns the top level. No
> > caller in tree asks for either of those two levels, and the new
> > numbering matches the architecture.
>
> Yes, as you checked this change won't break current tests, so if you
> have better comments I will replace it with yours.
The code comment reads fine. What's worth adding is a commit-message
note on the behavior change:
For 3-level (64K) modes this renumbers the levels to match the
architecture: level 0 is no longer valid, level 1 is the top entry.
No in-tree caller passes those levels.
...
> Yes, I've dropped the _va_size() function and instead, expanded a bit
> as you suggested the aarch64_get_supported_page_sizes() to check if vcpu
> can address upto 52-bit VA space or not (48-bit max).
Sounds good. One thing for v2: 52-bit VA support is per-granule, so a
single 52-vs-48 result won't hold across granules.
ID_AA64MMFR2_EL1.VARange is the 64K indicator. 4K and 16K get 52-bit
VA from LPA2.
Cheers,
/fuad
> Thanks,
> Itaru.
> >
> > Cheers,
> > /fuad
> >
> >
> > > +{
> > > + struct kvm_vcpu_init preferred_init = {};
> > > + int kvm_fd, vm_fd, vcpu_fd, err;
> > > + u64 val;
> > > + u32 va_range;
> > > + struct kvm_one_reg reg = {
> > > + .id = KVM_ARM64_SYS_REG(SYS_ID_AA64MMFR2_EL1),
> > > + .addr = (u64)&val,
> > > + };
> > > +
> > > + kvm_fd = open_kvm_dev_path_or_exit();
> > > + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
> > > + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
> > > +
> > > + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
> > > + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
> > > +
> > > + err = ioctl(vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
> > > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_PREFERRED_TARGET, err));
> > > +
> > > + err = ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &preferred_init);
> > > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_VCPU_INIT, err));
> > > +
> > > + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
> > > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, err));
> > > +
> > > + va_range = FIELD_GET(ID_AA64MMFR2_EL1_VARange, val);
> > > +
> > > + close(vcpu_fd);
> > > + close(vm_fd);
> > > + close(kvm_fd);
> > > +
> > > + return va_range >= ID_AA64MMFR2_EL1_VARange_52 ? 52 : 48;
> > > +}
> > > +
> > > void aarch64_get_supported_page_sizes(u32 ipa, u32 *ipa4k,
> > > u32 *ipa16k, u32 *ipa64k)
> > > {
> > >
> > > --
> > > 2.43.0
> > >
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes
2026-08-25 21:18 [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
2026-08-25 21:18 ` [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table Itaru Kitayama
@ 2026-08-25 21:18 ` Itaru Kitayama
2026-09-04 8:45 ` Fuad Tabba
2026-09-04 2:55 ` [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
2026-09-04 8:14 ` Fuad Tabba
3 siblings, 1 reply; 13+ messages in thread
From: Itaru Kitayama @ 2026-08-25 21:18 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Itaru Kitayama, Takayuki Okamoto
Add P52V52 guest mode IDs for the 4K, 16K and 64K translation
granules, along with their mode descriptions and parameters.
Advertise the 4KB and 16KB modes when the corresponding granule supports
a 52-bit IPA, implying FEAT_LPA2 support. For the 64K mode, also require
52-bit VA support.
This makes the 52-bit VA configurations available to KVM selftests now
that the arm64 page-table code supports 5-level stage-1 translation.
Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
---
tools/testing/selftests/kvm/include/kvm_util.h | 3 +++
tools/testing/selftests/kvm/lib/arm64/processor.c | 2 +-
tools/testing/selftests/kvm/lib/guest_modes.c | 5 +++++
tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++++++++++
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 04a910164a29..9040281c0992 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -184,6 +184,9 @@ enum vm_guest_mode {
VM_MODE_P52V48_4K,
VM_MODE_P52V48_16K,
VM_MODE_P52V48_64K,
+ VM_MODE_P52V52_4K,
+ VM_MODE_P52V52_16K,
+ VM_MODE_P52V52_64K,
VM_MODE_P48V48_4K,
VM_MODE_P48V48_16K,
VM_MODE_P48V48_64K,
diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
index 9108e14a9b5b..bcdf670c9eb8 100644
--- a/tools/testing/selftests/kvm/lib/arm64/processor.c
+++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
@@ -46,7 +46,7 @@ static u64 pud_index(struct kvm_vm *vm, gva_t gva)
u64 mask = (1UL << (vm->page_shift - 3)) - 1;
TEST_ASSERT(vm->mmu.pgtable_levels >= 4,
- "Mode %d does not have at least 4 page table levels",
+ "Mode %d does not have >= 4 page table levels",
vm->mode);
return (gva >> shift) & mask;
diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
index 7a96c43b5704..4f121e2987e9 100644
--- a/tools/testing/selftests/kvm/lib/guest_modes.c
+++ b/tools/testing/selftests/kvm/lib/guest_modes.c
@@ -21,10 +21,15 @@ void guest_modes_append_default(void)
{
unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
u32 ipa4k, ipa16k, ipa64k;
+ u32 va;
int i;
aarch64_get_supported_page_sizes(limit, &ipa4k, &ipa16k, &ipa64k);
+ va = aarch64_get_supported_va_size();
+ guest_mode_append(VM_MODE_P52V52_4K, ipa4k >= 52);
+ guest_mode_append(VM_MODE_P52V52_16K, ipa16k >= 52);
+ guest_mode_append(VM_MODE_P52V52_64K, ipa64k >= 52 && va >= 52);
guest_mode_append(VM_MODE_P52V48_4K, ipa4k >= 52);
guest_mode_append(VM_MODE_P52V48_16K, ipa16k >= 52);
guest_mode_append(VM_MODE_P52V48_64K, ipa64k >= 52);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 195f3fdae1e3..3fbc5b0d75ff 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -195,6 +195,9 @@ const char *vm_guest_mode_string(u32 i)
[VM_MODE_P52V48_4K] = "PA-bits:52, VA-bits:48, 4K pages",
[VM_MODE_P52V48_16K] = "PA-bits:52, VA-bits:48, 16K pages",
[VM_MODE_P52V48_64K] = "PA-bits:52, VA-bits:48, 64K pages",
+ [VM_MODE_P52V52_4K] = "PA-bits:52, VA-bits:52, 4K pages",
+ [VM_MODE_P52V52_16K] = "PA-bits:52, VA-bits:52, 16K pages",
+ [VM_MODE_P52V52_64K] = "PA-bits:52, VA-bits:52, 64K pages",
[VM_MODE_P48V48_4K] = "PA-bits:48, VA-bits:48, 4K pages",
[VM_MODE_P48V48_16K] = "PA-bits:48, VA-bits:48, 16K pages",
[VM_MODE_P48V48_64K] = "PA-bits:48, VA-bits:48, 64K pages",
@@ -231,6 +234,9 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
[VM_MODE_P52V48_4K] = { 52, 48, 0x1000, 12 },
[VM_MODE_P52V48_16K] = { 52, 48, 0x4000, 14 },
[VM_MODE_P52V48_64K] = { 52, 48, 0x10000, 16 },
+ [VM_MODE_P52V52_4K] = { 52, 52, 0x1000, 12 },
+ [VM_MODE_P52V52_16K] = { 52, 52, 0x4000, 14 },
+ [VM_MODE_P52V52_64K] = { 52, 52, 0x10000, 16 },
[VM_MODE_P48V48_4K] = { 48, 48, 0x1000, 12 },
[VM_MODE_P48V48_16K] = { 48, 48, 0x4000, 14 },
[VM_MODE_P48V48_64K] = { 48, 48, 0x10000, 16 },
@@ -298,10 +304,14 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
/* Setup mode specific traits. */
switch (vm->mode) {
+ case VM_MODE_P52V52_4K:
+ vm->mmu.pgtable_levels = 5;
+ break;
case VM_MODE_P52V48_4K:
vm->mmu.pgtable_levels = 4;
break;
case VM_MODE_P52V48_64K:
+ case VM_MODE_P52V52_64K:
vm->mmu.pgtable_levels = 3;
break;
case VM_MODE_P48V48_4K:
@@ -322,6 +332,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
case VM_MODE_P48V48_16K:
case VM_MODE_P40V48_16K:
case VM_MODE_P36V48_16K:
+ case VM_MODE_P52V52_16K:
vm->mmu.pgtable_levels = 4;
break;
case VM_MODE_P47V47_16K:
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes
2026-08-25 21:18 ` [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes Itaru Kitayama
@ 2026-09-04 8:45 ` Fuad Tabba
2026-09-07 21:24 ` Itaru Kitayama
0 siblings, 1 reply; 13+ messages in thread
From: Fuad Tabba @ 2026-09-04 8:45 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Itaru,
On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
...
> diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
> index 9108e14a9b5b..bcdf670c9eb8 100644
> --- a/tools/testing/selftests/kvm/lib/arm64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
> @@ -46,7 +46,7 @@ static u64 pud_index(struct kvm_vm *vm, gva_t gva)
> u64 mask = (1UL << (vm->page_shift - 3)) - 1;
>
> TEST_ASSERT(vm->mmu.pgtable_levels >= 4,
> - "Mode %d does not have at least 4 page table levels",
> + "Mode %d does not have >= 4 page table levels",
Patch 1 added this string one commit earlier. Could it go in with the
final wording there?
...
> @@ -298,10 +304,14 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
>
> /* Setup mode specific traits. */
> switch (vm->mode) {
> + case VM_MODE_P52V52_4K:
> + vm->mmu.pgtable_levels = 5;
> + break;
This is now the deepest mode, so page_fault_test.c's sizing is stale:
* VM_MODE_P48V48_4K is the mode with most PT pages; let's use
* twice that just in case.
pt_size = 26 * guest_page_size;
The margin still covers it. Could pt_size come from vm->mmu.pgtable_levels?
Cheers,
/fuad
> case VM_MODE_P52V48_4K:
> vm->mmu.pgtable_levels = 4;
> break;
> case VM_MODE_P52V48_64K:
> + case VM_MODE_P52V52_64K:
> vm->mmu.pgtable_levels = 3;
> break;
> case VM_MODE_P48V48_4K:
> @@ -322,6 +332,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> case VM_MODE_P48V48_16K:
> case VM_MODE_P40V48_16K:
> case VM_MODE_P36V48_16K:
> + case VM_MODE_P52V52_16K:
> vm->mmu.pgtable_levels = 4;
> break;
> case VM_MODE_P47V47_16K:
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes
2026-09-04 8:45 ` Fuad Tabba
@ 2026-09-07 21:24 ` Itaru Kitayama
2026-09-08 8:08 ` Fuad Tabba
0 siblings, 1 reply; 13+ messages in thread
From: Itaru Kitayama @ 2026-09-07 21:24 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Fuad,
On Fri, Sep 04, 2026 at 09:45:30AM +0100, Fuad Tabba wrote:
> Hi Itaru,
>
> On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
> ...
> > diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
> > index 9108e14a9b5b..bcdf670c9eb8 100644
> > --- a/tools/testing/selftests/kvm/lib/arm64/processor.c
> > +++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
> > @@ -46,7 +46,7 @@ static u64 pud_index(struct kvm_vm *vm, gva_t gva)
> > u64 mask = (1UL << (vm->page_shift - 3)) - 1;
> >
> > TEST_ASSERT(vm->mmu.pgtable_levels >= 4,
> > - "Mode %d does not have at least 4 page table levels",
> > + "Mode %d does not have >= 4 page table levels",
>
> Patch 1 added this string one commit earlier. Could it go in with the
> final wording there?
Surely, will fix in v2.
>
> ...
>
> > @@ -298,10 +304,14 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> >
> > /* Setup mode specific traits. */
> > switch (vm->mode) {
> > + case VM_MODE_P52V52_4K:
> > + vm->mmu.pgtable_levels = 5;
> > + break;
>
> This is now the deepest mode, so page_fault_test.c's sizing is stale:
>
> * VM_MODE_P48V48_4K is the mode with most PT pages; let's use
> * twice that just in case.
> pt_size = 26 * guest_page_size;
>
> The margin still covers it. Could pt_size come from vm->mmu.pgtable_levels?
I'm not the author of the page_fault_test.c for arm64, but so I'm
guessing here; per the comment in the test, I dont think total number of
levels determines pt_size, rather by the addresses prepared for the
test.
This stress test does not require high virtual addresses, though should
we update the comment while at it?
Thanks,
Itaru.
>
> Cheers,
> /fuad
>
>
> > case VM_MODE_P52V48_4K:
> > vm->mmu.pgtable_levels = 4;
> > break;
> > case VM_MODE_P52V48_64K:
> > + case VM_MODE_P52V52_64K:
> > vm->mmu.pgtable_levels = 3;
> > break;
> > case VM_MODE_P48V48_4K:
> > @@ -322,6 +332,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> > case VM_MODE_P48V48_16K:
> > case VM_MODE_P40V48_16K:
> > case VM_MODE_P36V48_16K:
> > + case VM_MODE_P52V52_16K:
> > vm->mmu.pgtable_levels = 4;
> > break;
> > case VM_MODE_P47V47_16K:
> >
> > --
> > 2.43.0
> >
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes
2026-09-07 21:24 ` Itaru Kitayama
@ 2026-09-08 8:08 ` Fuad Tabba
0 siblings, 0 replies; 13+ messages in thread
From: Fuad Tabba @ 2026-09-08 8:08 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
On Mon, 7 Sept 2026 at 22:24, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
>
> Hi Fuad,
> On Fri, Sep 04, 2026 at 09:45:30AM +0100, Fuad Tabba wrote:
> > Hi Itaru,
> >
> > On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
> > ...
> > > diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
> > > index 9108e14a9b5b..bcdf670c9eb8 100644
> > > --- a/tools/testing/selftests/kvm/lib/arm64/processor.c
> > > +++ b/tools/testing/selftests/kvm/lib/arm64/processor.c
> > > @@ -46,7 +46,7 @@ static u64 pud_index(struct kvm_vm *vm, gva_t gva)
> > > u64 mask = (1UL << (vm->page_shift - 3)) - 1;
> > >
> > > TEST_ASSERT(vm->mmu.pgtable_levels >= 4,
> > > - "Mode %d does not have at least 4 page table levels",
> > > + "Mode %d does not have >= 4 page table levels",
> >
> > Patch 1 added this string one commit earlier. Could it go in with the
> > final wording there?
>
> Surely, will fix in v2.
>
> >
> > ...
> >
> > > @@ -298,10 +304,14 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> > >
> > > /* Setup mode specific traits. */
> > > switch (vm->mode) {
> > > + case VM_MODE_P52V52_4K:
> > > + vm->mmu.pgtable_levels = 5;
> > > + break;
> >
> > This is now the deepest mode, so page_fault_test.c's sizing is stale:
> >
> > * VM_MODE_P48V48_4K is the mode with most PT pages; let's use
> > * twice that just in case.
> > pt_size = 26 * guest_page_size;
> >
> > The margin still covers it. Could pt_size come from vm->mmu.pgtable_levels?
>
> I'm not the author of the page_fault_test.c for arm64, but so I'm
> guessing here; per the comment in the test, I dont think total number of
> levels determines pt_size, rather by the addresses prepared for the
> test.
>
> This stress test does not require high virtual addresses, though should
> we update the comment while at it?
You're right, pgtable_levels alone wouldn't capture it: what sizes
pt_size is the granule and how much the test maps, not the depth.
So just updating the comment is enough: name VM_MODE_P52V52_4K as the
deepest mode. At 5 levels it's the deepest any 4K mode uses, so the 2x
margin holds and the constant won't need revisiting.
Cheers,
/fuad
>
> Thanks,
> Itaru.
>
> >
> > Cheers,
> > /fuad
> >
> >
> > > case VM_MODE_P52V48_4K:
> > > vm->mmu.pgtable_levels = 4;
> > > break;
> > > case VM_MODE_P52V48_64K:
> > > + case VM_MODE_P52V52_64K:
> > > vm->mmu.pgtable_levels = 3;
> > > break;
> > > case VM_MODE_P48V48_4K:
> > > @@ -322,6 +332,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> > > case VM_MODE_P48V48_16K:
> > > case VM_MODE_P40V48_16K:
> > > case VM_MODE_P36V48_16K:
> > > + case VM_MODE_P52V52_16K:
> > > vm->mmu.pgtable_levels = 4;
> > > break;
> > > case VM_MODE_P47V47_16K:
> > >
> > > --
> > > 2.43.0
> > >
> >
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/2] 52-bit VA guest mode ID support
2026-08-25 21:18 [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
2026-08-25 21:18 ` [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table Itaru Kitayama
2026-08-25 21:18 ` [PATCH 2/2] KVM: selftests: arm64: Add 52-bit VA guest modes Itaru Kitayama
@ 2026-09-04 2:55 ` Itaru Kitayama
2026-09-04 8:14 ` Fuad Tabba
3 siblings, 0 replies; 13+ messages in thread
From: Itaru Kitayama @ 2026-09-04 2:55 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Fuad Tabba, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
On Wed, Aug 26, 2026 at 06:18:33AM +0900, Itaru Kitayama wrote:
> This patch series extends the arm64 KVM selftest framework
> to support 52-bit guest virtual address (VA) modes in addition to
> the existing 52-bit physical address (PA) configurations.
> The motivation is to enable validation of LPA2 guest memory-management
> behaviour in configurations that use a 52-bit VA space.
> While the selftest framework already supports testing 52-bit PA
> configurations, it lacks the ability to exercise guests running with
> 52-bit virtual addresses, leaving part of the LPA2 functionality untested.
> To address this, the series introduces new guest modes for 52-bit VA
> operation, adds five-level page table support where required, and
> performs runtime detection of host 52-bit VA capability so that
> LPA2-enabled guest VA tests are executed only on supported systems.
>
> Testing:
>
> Built and tested on arm64.
> Verified on QEMU with a V52-capable guest configuration.
> Confirmed correct operation of high virtual address mappings by
> exercising guest memory accesses in the 52-bit VA range.
>
> Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
> Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
I'd appreciate any comments on this series.
Thanks,
Itaru.
> ---
> Itaru Kitayama (2):
> KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
> KVM: selftests: arm64: Add 52-bit VA guest modes
>
> .../selftests/kvm/include/arm64/processor.h | 2 +
> tools/testing/selftests/kvm/include/kvm_util.h | 3 +
> tools/testing/selftests/kvm/lib/arm64/processor.c | 87 ++++++++++++++++++++--
> tools/testing/selftests/kvm/lib/guest_modes.c | 5 ++
> tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++
> 5 files changed, 103 insertions(+), 5 deletions(-)
> ---
> base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
> change-id: 20260825-arm64-52bit-va-32f1f4cd050d
>
> Best regards,
> --
> Itaru Kitayama <itaru.kitayama@fujitsu.com>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/2] 52-bit VA guest mode ID support
2026-08-25 21:18 [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
` (2 preceding siblings ...)
2026-09-04 2:55 ` [PATCH 0/2] 52-bit VA guest mode ID support Itaru Kitayama
@ 2026-09-04 8:14 ` Fuad Tabba
2026-09-08 2:18 ` Itaru Kitayama
3 siblings, 1 reply; 13+ messages in thread
From: Fuad Tabba @ 2026-09-04 8:14 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Itaru,
On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
>
> This patch series extends the arm64 KVM selftest framework
> to support 52-bit guest virtual address (VA) modes in addition to
> the existing 52-bit physical address (PA) configurations.
> The motivation is to enable validation of LPA2 guest memory-management
> behaviour in configurations that use a 52-bit VA space.
> While the selftest framework already supports testing 52-bit PA
> configurations, it lacks the ability to exercise guests running with
> 52-bit virtual addresses, leaving part of the LPA2 functionality untested.
The series adds three 52-bit VA guest modes, but nothing in tree maps
a guest VA high enough to use them. The mode-iterating tests map at a
fixed low GVA, so pgd_index() returns 0 and only the first entry of
the top level is ever used.
What do you expect the modes to catch as they stand? The allocators
already take a minimum GVA, so mapping high in one of those tests
looks like a small change.
> To address this, the series introduces new guest modes for 52-bit VA
> operation, adds five-level page table support where required, and
> performs runtime detection of host 52-bit VA capability so that
> LPA2-enabled guest VA tests are executed only on supported systems.
>
> Testing:
>
> Built and tested on arm64.
> Verified on QEMU with a V52-capable guest configuration.
> Confirmed correct operation of high virtual address mappings by
> exercising guest memory accesses in the 52-bit VA range.
I could not reproduce "exercising guest memory accesses in the 52-bit
VA range" with anything in tree either. Could you say which test you
ran, which guest modes, and on what?
Thanks,
/fuad
> Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
> Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
> ---
> Itaru Kitayama (2):
> KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
> KVM: selftests: arm64: Add 52-bit VA guest modes
>
> .../selftests/kvm/include/arm64/processor.h | 2 +
> tools/testing/selftests/kvm/include/kvm_util.h | 3 +
> tools/testing/selftests/kvm/lib/arm64/processor.c | 87 ++++++++++++++++++++--
> tools/testing/selftests/kvm/lib/guest_modes.c | 5 ++
> tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++
> 5 files changed, 103 insertions(+), 5 deletions(-)
> ---
> base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
> change-id: 20260825-arm64-52bit-va-32f1f4cd050d
>
> Best regards,
> --
> Itaru Kitayama <itaru.kitayama@fujitsu.com>
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 0/2] 52-bit VA guest mode ID support
2026-09-04 8:14 ` Fuad Tabba
@ 2026-09-08 2:18 ` Itaru Kitayama
2026-09-08 7:55 ` Fuad Tabba
0 siblings, 1 reply; 13+ messages in thread
From: Itaru Kitayama @ 2026-09-08 2:18 UTC (permalink / raw)
To: Fuad Tabba
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Fuad,
On Fri, Sep 04, 2026 at 09:14:36AM +0100, Fuad Tabba wrote:
> On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
> >
> > This patch series extends the arm64 KVM selftest framework
> > to support 52-bit guest virtual address (VA) modes in addition to
> > the existing 52-bit physical address (PA) configurations.
> > The motivation is to enable validation of LPA2 guest memory-management
> > behaviour in configurations that use a 52-bit VA space.
> > While the selftest framework already supports testing 52-bit PA
> > configurations, it lacks the ability to exercise guests running with
> > 52-bit virtual addresses, leaving part of the LPA2 functionality untested.
>
> The series adds three 52-bit VA guest modes, but nothing in tree maps
> a guest VA high enough to use them. The mode-iterating tests map at a
> fixed low GVA, so pgd_index() returns 0 and only the first entry of
> the top level is ever used.
>
> What do you expect the modes to catch as they stand? The allocators
> already take a minimum GVA, so mapping high in one of those tests
> looks like a small change.
I think at least a 4KB page is allocated for the level -1 translation table,
and entry 0 is populated with a Table descriptor pointing to the level 0 translation
table. But, no it does not test a nonzero top-level index.
>
> > To address this, the series introduces new guest modes for 52-bit VA
> > operation, adds five-level page table support where required, and
> > performs runtime detection of host 52-bit VA capability so that
> > LPA2-enabled guest VA tests are executed only on supported systems.
> >
> > Testing:
> >
> > Built and tested on arm64.
> > Verified on QEMU with a V52-capable guest configuration.
> > Confirmed correct operation of high virtual address mappings by
> > exercising guest memory accesses in the 52-bit VA range.
>
> I could not reproduce "exercising guest memory accesses in the 52-bit
> VA range" with anything in tree either. Could you say which test you
> ran, which guest modes, and on what?
I just in guest_code() of existing one of the kselftests, mapped and
accessed a page at 1ULL << 49 using virt_pg_map() and on QEMU TCG mode
as I don't currently have access to the machines LPA and LPA2 features.
Thanks,
Itaru.
>
> Thanks,
> /fuad
>
> > Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
> > Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
> > ---
> > Itaru Kitayama (2):
> > KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
> > KVM: selftests: arm64: Add 52-bit VA guest modes
> >
> > .../selftests/kvm/include/arm64/processor.h | 2 +
> > tools/testing/selftests/kvm/include/kvm_util.h | 3 +
> > tools/testing/selftests/kvm/lib/arm64/processor.c | 87 ++++++++++++++++++++--
> > tools/testing/selftests/kvm/lib/guest_modes.c | 5 ++
> > tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++
> > 5 files changed, 103 insertions(+), 5 deletions(-)
> > ---
> > base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
> > change-id: 20260825-arm64-52bit-va-32f1f4cd050d
> >
> > Best regards,
> > --
> > Itaru Kitayama <itaru.kitayama@fujitsu.com>
> >
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/2] 52-bit VA guest mode ID support
2026-09-08 2:18 ` Itaru Kitayama
@ 2026-09-08 7:55 ` Fuad Tabba
0 siblings, 0 replies; 13+ messages in thread
From: Fuad Tabba @ 2026-09-08 7:55 UTC (permalink / raw)
To: Itaru Kitayama
Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Paolo Bonzini, Shuah Khan,
linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Takayuki Okamoto
Hi Itaru,
On Tue, 8 Sept 2026 at 03:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
>
> Hi Fuad,
> On Fri, Sep 04, 2026 at 09:14:36AM +0100, Fuad Tabba wrote:
> > On Tue, 25 Aug 2026 at 22:18, Itaru Kitayama <itaru.kitayama@fujitsu.com> wrote:
> > >
> > > This patch series extends the arm64 KVM selftest framework
> > > to support 52-bit guest virtual address (VA) modes in addition to
> > > the existing 52-bit physical address (PA) configurations.
> > > The motivation is to enable validation of LPA2 guest memory-management
> > > behaviour in configurations that use a 52-bit VA space.
> > > While the selftest framework already supports testing 52-bit PA
> > > configurations, it lacks the ability to exercise guests running with
> > > 52-bit virtual addresses, leaving part of the LPA2 functionality untested.
> >
> > The series adds three 52-bit VA guest modes, but nothing in tree maps
> > a guest VA high enough to use them. The mode-iterating tests map at a
> > fixed low GVA, so pgd_index() returns 0 and only the first entry of
> > the top level is ever used.
> >
> > What do you expect the modes to catch as they stand? The allocators
> > already take a minimum GVA, so mapping high in one of those tests
> > looks like a small change.
>
> I think at least a 4KB page is allocated for the level -1 translation table,
> and entry 0 is populated with a Table descriptor pointing to the level 0 translation
> table. But, no it does not test a nonzero top-level index.
Right, that's the gap. Every mode-iterating test maps at a fixed low
GVA (0xc0000000), so the new modes only ever fill entry 0 of the top
table. If the series adds the modes, it should add a test that drives
a VA into the 52-bit range.
> >
> > > To address this, the series introduces new guest modes for 52-bit VA
> > > operation, adds five-level page table support where required, and
> > > performs runtime detection of host 52-bit VA capability so that
> > > LPA2-enabled guest VA tests are executed only on supported systems.
> > >
> > > Testing:
> > >
> > > Built and tested on arm64.
> > > Verified on QEMU with a V52-capable guest configuration.
> > > Confirmed correct operation of high virtual address mappings by
> > > exercising guest memory accesses in the 52-bit VA range.
> >
> > I could not reproduce "exercising guest memory accesses in the 52-bit
> > VA range" with anything in tree either. Could you say which test you
> > ran, which guest modes, and on what?
>
> I just in guest_code() of existing one of the kselftests, mapped and
> accessed a page at 1ULL << 49 using virt_pg_map() and on QEMU TCG mode
> as I don't currently have access to the machines LPA and LPA2 features.
That test is what the series needs, and you've already written it.
Folding a mode-iterating version in tree would exercise the modes and
make the cover letter's "52-bit VA range" line reproducible. It runs
under TCG, so no LPA2 hardware needed.
Cheers,
/fuad
> Thanks,
> Itaru.
> >
> > Thanks,
> > /fuad
> >
> > > Signed-off-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
> > > Reviewed-by: Takayuki Okamoto <tokamoto@fujitsu.com>
> > > ---
> > > Itaru Kitayama (2):
> > > KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
> > > KVM: selftests: arm64: Add 52-bit VA guest modes
> > >
> > > .../selftests/kvm/include/arm64/processor.h | 2 +
> > > tools/testing/selftests/kvm/include/kvm_util.h | 3 +
> > > tools/testing/selftests/kvm/lib/arm64/processor.c | 87 ++++++++++++++++++++--
> > > tools/testing/selftests/kvm/lib/guest_modes.c | 5 ++
> > > tools/testing/selftests/kvm/lib/kvm_util.c | 11 +++
> > > 5 files changed, 103 insertions(+), 5 deletions(-)
> > > ---
> > > base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
> > > change-id: 20260825-arm64-52bit-va-32f1f4cd050d
> > >
> > > Best regards,
> > > --
> > > Itaru Kitayama <itaru.kitayama@fujitsu.com>
> > >
^ permalink raw reply [flat|nested] 13+ messages in thread