[PATCH RFC v4 29/44] KVM: selftests: Convert with allocated folios in different layouts

Ackerley Tng
2026-03-26T22:25:24Z

Add a guest_memfd selftest to verify that memory conversions work
correctly with allocated folios in different layouts.

By iterating through which pages are initially faulted, the test covers
various layouts of contiguous allocated and unallocated regions, exercising
conversion with different range layouts.

Signed-off-by: Ackerley Tng <ackerleytng@google.com>
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../selftests/kvm/guest_memfd_conversions_test.c | 31 ++++++++++++++++++++++
1 file changed, 31 insertions(+)

diff --git a/tools/testing/selftests/kvm/guest_memfd_conversions_test.c b/tools/testing/selftests/kvm/guest_memfd_conversions_test.c
index 1198c9c914318..8f09671505b32 100644
--- a/tools/testing/selftests/kvm/guest_memfd_conversions_test.c
+++ b/tools/testing/selftests/kvm/guest_memfd_conversions_test.c
@@ -289,6 +289,37 @@ GMEM_CONVERSION_TEST_INIT_PRIVATE(before_allocation_private)
test_convert_to_shared(t, 0, 0, 'A', 'B');
}

+/*
+ * Test that when some of the folios in the conversion range are allocated,
+ * conversion requests are handled correctly in guest_memfd. Vary the ranges
+ * allocated before conversion, using test_page, to cover various layouts of
+ * contiguous allocated and unallocated regions.
+ */
+GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(unallocated_folios, 8)
+{
+ const int second_page_to_fault = 4;
+ int i;
+
+ /*
+ * Fault 2 of the pages to test filemap range operations except when
+ * test_page == second_page_to_fault.
+ */
+ host_do_rmw(t->mem, test_page, 0, 'A');
+ if (test_page != second_page_to_fault)
+ host_do_rmw(t->mem, second_page_to_fault, 0, 'A');
+
+ gmem_set_private(t->gmem_fd, 0, nr_pages * page_size,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE);
+ for (i = 0; i < nr_pages; ++i) {
+ char expected = (i == test_page || i == second_page_to_fault) ? 'A' : 0;
+
+ test_private(t, i, expected, 'B');
+ }
+
+ for (i = 0; i < nr_pages; ++i)
+ test_convert_to_shared(t, i, 'B', 'C', 'D');
+}
+
int main(int argc, char *argv[])
{
TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_VM));

--
2.53.0.1018.g2bb0e51243-goog