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 <[email protected]>
> ---
>  .../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()?


Reply via email to