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 <[email protected]> > 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 > >

