Re: [PATCH v8 41/46] KVM: selftests: Provide function to look up guest_memfd details from gpa
From: Fuad Tabba
Date: Thu Jun 25 2026 - 05:00:40 EST
On Fri, 19 Jun 2026 at 01:32, Ackerley Tng via B4 Relay
<devnull+ackerleytng.google.com@xxxxxxxxxx> wrote:
>
> From: Ackerley Tng <ackerleytng@xxxxxxxxxx>
>
> Introduce a new helper, kvm_gpa_to_guest_memfd(), to find the
> guest_memfd-related details of a memory region that contains a given guest
> physical address (GPA).
>
> The function returns the file descriptor for the memfd, the offset into
> the file that corresponds to the GPA, and the number of bytes remaining
> in the region from that GPA.
>
> kvm_gpa_to_guest_memfd() was factored out from vm_guest_mem_fallocate();
> refactor vm_guest_mem_fallocate() to use the new helper.
>
> Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
> Co-developed-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Reviewed-by: Fuad Tabba <tabba@xxxxxxxxxx>
Cheers,
/fuad
> ---
> tools/testing/selftests/kvm/include/kvm_util.h | 3 +++
> tools/testing/selftests/kvm/lib/kvm_util.c | 37 ++++++++++++++++----------
> 2 files changed, 26 insertions(+), 14 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index 79ab64ac8b869..3a6b1fa7f26ef 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -428,6 +428,9 @@ static inline void vm_enable_cap(struct kvm_vm *vm, u32 cap, u64 arg0)
> vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap);
> }
>
> +int kvm_gpa_to_guest_memfd(struct kvm_vm *vm, gpa_t gpa, off_t *fd_offset,
> + size_t *nr_bytes);
> +
> /*
> * KVM_SET_MEMORY_ATTRIBUTES{,2} overwrites _all_ attributes. These
> * flows need significant enhancements to support multiple attributes.
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index 524ef97d634bf..0b2256ea65ff9 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -1305,27 +1305,20 @@ void vm_guest_mem_fallocate(struct kvm_vm *vm, u64 base, u64 size,
> bool punch_hole)
> {
> const int mode = FALLOC_FL_KEEP_SIZE | (punch_hole ? FALLOC_FL_PUNCH_HOLE : 0);
> - struct userspace_mem_region *region;
> u64 end = base + size;
> - gpa_t gpa, len;
> off_t fd_offset;
> - int ret;
> + int fd, ret;
> + size_t len;
> + gpa_t gpa;
>
> for (gpa = base; gpa < end; gpa += len) {
> - u64 offset;
> -
> - region = userspace_mem_region_find(vm, gpa, gpa);
> - TEST_ASSERT(region && region->region.flags & KVM_MEM_GUEST_MEMFD,
> - "Private memory region not found for GPA 0x%lx", gpa);
> + fd = kvm_gpa_to_guest_memfd(vm, gpa, &fd_offset, &len);
> + len = min(end - gpa, len);
>
> - offset = gpa - region->region.guest_phys_addr;
> - fd_offset = region->region.guest_memfd_offset + offset;
> - len = min_t(u64, end - gpa, region->region.memory_size - offset);
> -
> - ret = fallocate(region->region.guest_memfd, mode, fd_offset, len);
> + ret = fallocate(fd, mode, fd_offset, len);
> TEST_ASSERT(!ret, "fallocate() failed to %s at %lx (len = %lu), fd = %d, mode = %x, offset = %lx",
> punch_hole ? "punch hole" : "allocate", gpa, len,
> - region->region.guest_memfd, mode, fd_offset);
> + fd, mode, fd_offset);
> }
> }
>
> @@ -1662,6 +1655,22 @@ void *addr_gpa2alias(struct kvm_vm *vm, gpa_t gpa)
> return (void *) ((uintptr_t) region->host_alias + offset);
> }
>
> +int kvm_gpa_to_guest_memfd(struct kvm_vm *vm, gpa_t gpa, off_t *fd_offset,
> + size_t *nr_bytes)
> +{
> + struct userspace_mem_region *region;
> + gpa_t gpa_offset;
> +
> + region = userspace_mem_region_find(vm, gpa, gpa);
> + TEST_ASSERT(region && region->region.flags & KVM_MEM_GUEST_MEMFD,
> + "guest_memfd memory region not found for GPA 0x%lx", gpa);
> +
> + gpa_offset = gpa - region->region.guest_phys_addr;
> + *fd_offset = region->region.guest_memfd_offset + gpa_offset;
> + *nr_bytes = region->region.memory_size - gpa_offset;
> + return region->region.guest_memfd;
> +}
> +
> /* Create an interrupt controller chip for the specified VM. */
> void vm_create_irqchip(struct kvm_vm *vm)
> {
>
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
>