Re: [PATCH v7 12/12] KVM: selftests: Test guest execution from direct map removed gmem

Brendan Jackman
2025-10-30T17:18:34Z

On Wed Sep 24, 2025 at 3:22 PM UTC, Patrick Roy wrote:
> Add a selftest that loads itself into guest_memfd (via
> GUEST_MEMFD_FLAG_MMAP) and triggers an MMIO exit when executed. This
> exercises x86 MMIO emulation code inside KVM for guest_memfd-backed
> memslots where the guest_memfd folios are direct map removed.
> Particularly, it validates that x86 MMIO emulation code (guest page
> table walks + instruction fetch) correctly accesses gmem through the VMA
> that's been reflected into the memslot's userspace_addr field (instead
> of trying to do direct map accesses).
>
> Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
> ---
> .../selftests/kvm/set_memory_region_test.c | 50 +++++++++++++++++--
> 1 file changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
> index ce3ac0fd6dfb..cb3bc642d376 100644
> --- a/tools/testing/selftests/kvm/set_memory_region_test.c
> +++ b/tools/testing/selftests/kvm/set_memory_region_test.c
> @@ -603,6 +603,41 @@ static void test_mmio_during_vectoring(void)
>
> kvm_vm_free(vm);
> }
> +
> +static void guest_code_trigger_mmio(void)
> +{
> + /*
> + * Read some GPA that is not backed by a memslot. KVM consider this
> + * as MMIO and tell userspace to emulate the read.
> + */
> + READ_ONCE(*((uint64_t *)MEM_REGION_GPA));
> +
> + GUEST_DONE();
> +}
> +
> +static void test_guest_memfd_mmio(void)
> +{
> + struct kvm_vm *vm;
> + struct kvm_vcpu *vcpu;
> + struct vm_shape shape = {
> + .mode = VM_MODE_DEFAULT,
> + .src_type = VM_MEM_SRC_GUEST_MEMFD_NO_DIRECT_MAP,
> + };
> + pthread_t vcpu_thread;
> +
> + pr_info("Testing MMIO emulation for instructions in gmem\n");
> +
> + vm = __vm_create_shape_with_one_vcpu(shape, &vcpu, 0, guest_code_trigger_mmio);

When I run this test on my minimal config in a nested VM I get:

[root@testvm:~]# /nix/store/xlxd60n7v1qfr6s5zxda410zrzdd0xc2-kselftests/bin/run_kselftest.sh -t kvm:set_memory_region_test
TAP version 13
1..1
# timeout set to 120
# selftests: kvm: set_memory_region_test
# Random seed: 0x6b8b4567
# Testing KVM_RUN with zero added memory regions
# Testing MMIO during vectoring error handling
# Allowed number of memory slots: 32764
# Adding slots 0..32763, each memory region with 2048K size
# Testing MMIO emulation for instructions in gmem
# ==== Test Assertion Failure ====
# lib/kvm_util.c:1118: region->mmap_start != MAP_FAILED
# pid=614 tid=614 errno=19 - No such device
# 1 0x0000000000407b02: vm_mem_add at ??:?
# 2 0x000000000040a924: __vm_create at ??:?
# 3 0x000000000040ab16: __vm_create_shape_with_one_vcpu at ??:?
# 4 0x00000000004042cf: main at ??:?
# 5 0x00007faa6b08a47d: ?? ??:0
# 6 0x00007faa6b08a538: ?? ??:0
# 7 0x0000000000404384: _start at ??:?
# mmap() failed, rc: -1 errno: 19 (No such device)

Here's the kconfig I'm using (basically defconfig+KVM):

https://gist.githubusercontent.com/bjackman/4ea941ef5072606769211f3b000c8ed7/raw/73808882ddae6ff2ae8a0be85ac977b2980f7292/kconfig.txt

Sorry I'm too ignorant about KVM to know what I'm missing here but I
guess it's a missing TEST_REQUIRE()?