From: Ackerley Tng <[email protected]>

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.

Co-developed-by: Sean Christopherson <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]>
Tested-by: Shivank Garg <[email protected]>
Signed-off-by: Ackerley Tng <[email protected]>
---
 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 3cfe243d7c8b0..795c9eb311071 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 b1456ed76e27e..1188d0a6c0a5f 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1332,27 +1332,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);
        }
 }
 
@@ -1689,6 +1682,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.654.g21b8a5bc05-goog



Reply via email to