* [PATCH 0/2] 52-bit VA guest mode ID support
@ 2026-08-25 21:18 Itaru Kitayama
2026-08-25 21:18 ` [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table Itaru Kitayama
` (3 more replies)
0 siblings, 4 replies; 7+ 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
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>
---
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] 7+ messages in thread
* [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; 7+ 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] 7+ 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; 7+ 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] 7+ 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; 7+ 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] 7+ 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
3 siblings, 0 replies; 7+ 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] 7+ 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
0 siblings, 0 replies; 7+ 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] 7+ 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
0 siblings, 0 replies; 7+ 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] 7+ messages in thread
end of thread, other threads:[~2026-09-04 8:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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-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
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox