KVM: selftests: Add a test for KVM_CAP_EXIT_ON_EMULATION_FAILURE
authorDavid Matlack <dmatlack@google.com>
Wed, 2 Nov 2022 18:46:54 +0000 (11:46 -0700)
committerSean Christopherson <seanjc@google.com>
Thu, 17 Nov 2022 00:59:02 +0000 (16:59 -0800)
Add a selftest to exercise the KVM_CAP_EXIT_ON_EMULATION_FAILURE
capability.

This capability is also exercised through
smaller_maxphyaddr_emulation_test, but that test requires
allow_smaller_maxphyaddr=Y, which is off by default on Intel when ept=Y
and unconditionally disabled on AMD when npt=Y. This new test ensures
that KVM_CAP_EXIT_ON_EMULATION_FAILURE is exercised independent of
allow_smaller_maxphyaddr.

Signed-off-by: David Matlack <dmatlack@google.com>
Link: https://lore.kernel.org/r/20221102184654.282799-11-dmatlack@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
tools/testing/selftests/kvm/.gitignore
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c [new file with mode: 0644]

index 053e5d3..bef984e 100644 (file)
@@ -17,6 +17,7 @@
 /x86_64/cr4_cpuid_sync_test
 /x86_64/debug_regs
 /x86_64/evmcs_test
+/x86_64/exit_on_emulation_failure_test
 /x86_64/fix_hypercall_test
 /x86_64/get_msr_index_features
 /x86_64/kvm_clock_test
index cff3a7f..487248c 100644 (file)
@@ -82,6 +82,7 @@ TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
 TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
 TEST_GEN_PROGS_x86_64 += x86_64/get_msr_index_features
 TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test
+TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
 TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
diff --git a/tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c b/tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c
new file mode 100644 (file)
index 0000000..37c61f7
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022, Google LLC.
+ *
+ * Test for KVM_CAP_EXIT_ON_EMULATION_FAILURE.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_short_name */
+
+#include "flds_emulation.h"
+
+#include "test_util.h"
+
+#define MMIO_GPA       0x700000000
+#define MMIO_GVA       MMIO_GPA
+
+static void guest_code(void)
+{
+       /* Execute flds with an MMIO address to force KVM to emulate it. */
+       flds(MMIO_GVA);
+       GUEST_DONE();
+}
+
+int main(int argc, char *argv[])
+{
+       struct kvm_vcpu *vcpu;
+       struct kvm_vm *vm;
+
+       /* Tell stdout not to buffer its content */
+       setbuf(stdout, NULL);
+
+       TEST_REQUIRE(kvm_has_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE));
+
+       vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+       vm_enable_cap(vm, KVM_CAP_EXIT_ON_EMULATION_FAILURE, 1);
+       virt_map(vm, MMIO_GVA, MMIO_GPA, 1);
+
+       vcpu_run(vcpu);
+       handle_flds_emulation_failure_exit(vcpu);
+       vcpu_run(vcpu);
+       ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_DONE);
+
+       kvm_vm_free(vm);
+       return 0;
+}