Re: [PATCH 1/2] KVM: selftest: arm64: Support 5-level paging in stage 1 translation table
From: Fuad Tabba <fuad.tabba@linux.dev>
Date: 2026-09-08 08:08:42
Also in:
kvm, kvmarm, linux-kselftest, lkml
Hi Itaru, On Tue, 8 Sept 2026 at 02:44, Itaru Kitayama [off-list ref] wrote: ...
quoted
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.quoted
Cheers, /fuadquoted
+{ + 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