Re: [PATCH v10 40/41] KVM: selftests: Update private_mem_conversions_test to mmap() guest_memfd
From: Ackerley Tng
Date: Tue Aug 25 2026 - 10:37:44 EST
Xiaoyao Li <xiaoyao.li@xxxxxxxxx> writes:
> On 8/25/2026 5:32 PM, Ackerley Tng wrote:
>> Sean Christopherson <seanjc@xxxxxxxxxx> writes:
>>
>>> On Fri, Aug 21, 2026, Xiaoyao Li wrote:
>>>> On 8/8/2026 5:53 AM, Ackerley Tng via B4 Relay wrote:
>>>>> From: Ackerley Tng<ackerleytng@xxxxxxxxxx>
>>>>>
>>>>> Update the private memory conversions selftest to also test conversions
>>>>> that are done "in-place" via per-guest_memfd memory attributes. In-place
>>>>> conversions require the host to be able to mmap() the guest_memfd so that
>>>>> the host and guest can share the same backing physical memory.
>>>>>
>>>>> This includes several updates, that are conditioned on the system
>>>>> supporting per-guest_memfd attributes (kvm_has_gmem_attributes):
>>>>>
>>>>> 1. Set up guest_memfd requesting MMAP and INIT_SHARED.
>>>>
>>>> If I understand correctly, even with in-place gmem, the model that shared
>>>> memory comes from the userspace_addr and private memory comes from gmem can
>>>> still work without passing GUEST_MEMFD_FLAG_MMAP flag.
>>>>
>>>> Since this model is not prohibited by KVM. I think we should keep the
>>>> testcase for this model to ensure test coverage?
>>>
>>> +1. Deprecated doesn't mean unsupported.
>>
>> The original test case was for non-in-place conversion, which wasn't
>> removed, it still passes.
>
> It only passes when
>
> /sys/module/kvm/parameters/gmem_in_place_conversion=n
>
> It fails as below when gmem_in_place_conversion=y
>
> ./tools/testing/selftests/kvm/x86/private_mem_conversions_test
> Random seed: 0x7eace343
>
> ==== Test Assertion Failure ====
> x86/private_mem_conversions_test.c:46: mem[i] == pattern
> pid=288745 tid=288747 errno=4 - Interrupted system call
> 1 0x000000000040426a: memcmp_h at private_mem_conversions_test.c:46
> 2 (inlined by) __test_mem_conversions at
> private_mem_conversions_test.c:356
> 3 0x00007f2ea2c89c01: ?? ??:0
> 4 0x00007f2ea2d0ec3f: ?? ??:0
> Host expected 0xaa at gpa 0x100000000, got 0x0
>
>> Is the ask to also test, under kvm_has_gmem_attributes aka
>> gmem_in_place_conversion, to have guest_memfd used as purely for private
>> memory and have shared memory taken from somewhere else completely?
>>
>> I can rephrase the changelog and change the code to clarify that this
>> patch is meant to specifically test in-place conversion with MMAP, the
>> intended usage of in-place conversions.
>>
>> The ask to test gmem for private and something else for shared seems
>> like a different test that can be added separately, perhaps in a
>> follow-up series?
>
> I see it as the fix for existing testcase, not another new test. And the
> fix is simple:
> 1. change to use vm_mem_set_memory_attributes() to set memory attribute.
> 2. pass GUEST_MEMFD_FLAG_INIT_SHARED to create the gmem because this
> test expects the initial state of the gfn is shared.
>
I understand now. I worked it out, I should be able to post v11
tomorrow, just need a little bit more testing.
> ---8<----
> diff --git
> a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> index cf50e9a332c5..fbd6c63d21cf 100644
> --- a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> +++ b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> @@ -307,7 +307,7 @@ static void handle_exit_hypercall(struct kvm_vcpu *vcpu)
> vm_guest_mem_fallocate(vm, gpa, size, map_shared);
>
> if (set_attributes)
> - vm_set_memory_attributes(vm, gpa, size,
> + vm_mem_set_memory_attributes(vm, gpa, size,
> map_shared ? 0 :
> KVM_MEMORY_ATTRIBUTE_PRIVATE);
> run->hypercall.ret = 0;
> }
> @@ -382,6 +382,7 @@ static void test_mem_conversions(enum
> vm_mem_backing_src_type src_type, u32 nr_v
> const size_t slot_size = memfd_size / nr_memslots;
> struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> pthread_t threads[KVM_MAX_VCPUS];
> + u64 gmem_flags = 0;
> struct kvm_vm *vm;
> int memfd, i;
>
> @@ -397,7 +398,10 @@ static void test_mem_conversions(enum
> vm_mem_backing_src_type src_type, u32 nr_v
>
> vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, (1 <<
> KVM_HC_MAP_GPA_RANGE));
>
> - memfd = vm_create_guest_memfd(vm, memfd_size, 0);
> + if (kvm_has_gmem_attributes)
> + gmem_flags = GUEST_MEMFD_FLAG_INIT_SHARED;
> +
> + memfd = vm_create_guest_memfd(vm, memfd_size, gmem_flags);
>
> for (i = 0; i < nr_memslots; i++)
> vm_mem_add(vm, src_type, BASE_DATA_GPA + slot_size * i,