On Mon, 31 Aug 2026 at 01:25, Ackerley Tng via B4 Relay <[email protected]> wrote: > > From: Ackerley Tng <[email protected]> > > Currently, vm_mem_add derives the backing source page size, alignment > padding, and mmap size from the backing source type upfront before checking > if guest_memfd is being mmapped. > > With shared memory also mmap()-ed from guest_memfd, the alignment of the > mmap-ed address needs to respect guest_memfd's backing page size. > > Refactor the backing store setup to configure the backing source page > size, alignment, mmap flags, and mmap offset directly for guest_memfd > when it is mmapped, ignoring the backing source type. > > Skip hugepage validation and anonymous memory madvise calls when mmapping > from guest_memfd, since those are not applicable when mmapping guest_memfd. > > Signed-off-by: Ackerley Tng <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > tools/testing/selftests/kvm/lib/kvm_util.c | 74 > ++++++++++++++++++------------ > 1 file changed, 45 insertions(+), 29 deletions(-) > > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c > b/tools/testing/selftests/kvm/lib/kvm_util.c > index cac5624e99774..3f559f207408f 100644 > --- a/tools/testing/selftests/kvm/lib/kvm_util.c > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c > @@ -1034,11 +1034,12 @@ void vm_mem_add(struct kvm_vm *vm, enum > vm_mem_backing_src_type src_type, > { > int ret; > struct userspace_mem_region *region; > - size_t backing_src_pagesz = get_backing_src_pagesz(src_type); > - int mmap_flags = vm_mem_backing_src_alias(src_type)->flag; > size_t mem_size = npages * vm->page_size; > - off_t mmap_offset = 0; > - size_t alignment = 1; > + size_t backing_src_pagesz; > + off_t mmap_offset; > + bool is_gmem_mmap; > + size_t alignment; > + int mmap_flags; > > TEST_REQUIRE_SET_USER_MEMORY_REGION2(); > > @@ -1090,19 +1091,31 @@ void vm_mem_add(struct kvm_vm *vm, enum > vm_mem_backing_src_type src_type, > /* Allocate and initialize new mem region structure. */ > region = calloc(1, sizeof(*region)); > TEST_ASSERT(region != NULL, "Insufficient Memory"); > - region->mmap_size = mem_size; > > - /* > - * When using THP mmap is not guaranteed to returned a hugepage > aligned > - * address so we have to pad the mmap. Padding is not needed for > HugeTLB > - * because mmap will always return an address aligned to the HugeTLB > - * page size. > - */ > - if (src_type == VM_MEM_SRC_ANONYMOUS_THP) > - alignment = max(backing_src_pagesz, alignment); > + is_gmem_mmap = (flags & KVM_MEM_GUEST_MEMFD) && > + (gmem_flags & GUEST_MEMFD_FLAG_MMAP); > + > + if (is_gmem_mmap) { > + backing_src_pagesz = getpagesize(); > + alignment = 1; > + mmap_flags = MAP_SHARED; > + mmap_offset = gmem_offset; > + } else { > + backing_src_pagesz = get_backing_src_pagesz(src_type); > + /* > + * When using THP mmap is not guaranteed to returned a > hugepage aligned > + * address so we have to pad the mmap. Padding is not needed > for HugeTLB > + * because mmap will always return an address aligned to the > HugeTLB > + * page size. > + */ > + alignment = src_type == VM_MEM_SRC_ANONYMOUS_THP ? > backing_src_pagesz : 1; > + mmap_flags = vm_mem_backing_src_alias(src_type)->flag; > + mmap_offset = 0; > + } > > TEST_ASSERT_EQ(gpa, align_up(gpa, backing_src_pagesz)); > > + region->mmap_size = mem_size; > /* Add enough memory to align up if necessary */ > if (alignment > 1) > region->mmap_size += alignment; > @@ -1129,10 +1142,8 @@ void vm_mem_add(struct kvm_vm *vm, enum > vm_mem_backing_src_type src_type, > } > > region->fd = -1; > - if (flags & KVM_MEM_GUEST_MEMFD && gmem_flags & > GUEST_MEMFD_FLAG_MMAP) { > + if (is_gmem_mmap) { > region->fd = kvm_dup(gmem_fd); > - mmap_flags = MAP_SHARED; > - mmap_offset = gmem_offset; > } else if (backing_src_is_shared(src_type)) { > region->fd = kvm_memfd_alloc(region->mmap_size, > src_type == > VM_MEM_SRC_SHARED_HUGETLB); > @@ -1141,22 +1152,27 @@ void vm_mem_add(struct kvm_vm *vm, enum > vm_mem_backing_src_type src_type, > region->mmap_start = __kvm_mmap(region->mmap_size, PROT_READ | > PROT_WRITE, > mmap_flags, region->fd, mmap_offset); > > - TEST_ASSERT(!is_backing_src_hugetlb(src_type) || > - region->mmap_start == align_ptr_up(region->mmap_start, > backing_src_pagesz), > - "mmap_start %p is not aligned to HugeTLB page size 0x%lx", > - region->mmap_start, backing_src_pagesz); > - > /* Align host address */ > region->host_mem = align_ptr_up(region->mmap_start, alignment); > > - /* As needed perform madvise */ > - if ((src_type == VM_MEM_SRC_ANONYMOUS || > - src_type == VM_MEM_SRC_ANONYMOUS_THP) && thp_configured()) { > - ret = madvise(region->host_mem, mem_size, > - src_type == VM_MEM_SRC_ANONYMOUS ? > MADV_NOHUGEPAGE : MADV_HUGEPAGE); > - TEST_ASSERT(ret == 0, "madvise failed, addr: %p length: 0x%lx > src_type: %s", > - region->host_mem, mem_size, > - vm_mem_backing_src_alias(src_type)->name); > + if (!is_gmem_mmap) { > + TEST_ASSERT(!is_backing_src_hugetlb(src_type) || > + region->mmap_start == > + align_ptr_up(region->mmap_start, > backing_src_pagesz), > + "mmap_start %p is not aligned to HugeTLB page > size 0x%lx", > + region->mmap_start, backing_src_pagesz); > + > + /* As needed perform madvise */ > + if ((src_type == VM_MEM_SRC_ANONYMOUS || > + src_type == VM_MEM_SRC_ANONYMOUS_THP) && > thp_configured()) { > + int advice = src_type == VM_MEM_SRC_ANONYMOUS ? > + MADV_NOHUGEPAGE : MADV_HUGEPAGE; > + > + ret = madvise(region->host_mem, mem_size, advice); > + TEST_ASSERT(ret == 0, "madvise failed, addr: %p > length: 0x%lx src_type: %s", > + region->host_mem, mem_size, > + vm_mem_backing_src_alias(src_type)->name); > + } > } > > region->backing_src_type = src_type; > > -- > 2.55.0.897.gb25b4bd76c-goog > >
