[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250401161106.790710-28-pbonzini@redhat.com>
Date: Tue, 1 Apr 2025 18:11:04 +0200
From: Paolo Bonzini <pbonzini@...hat.com>
To: linux-kernel@...r.kernel.org,
kvm@...r.kernel.org
Cc: roy.hopkins@...e.com,
seanjc@...gle.com,
thomas.lendacky@....com,
ashish.kalra@....com,
michael.roth@....com,
jroedel@...e.de,
nsaenz@...zon.com,
anelkz@...zon.de,
James.Bottomley@...senPartnership.com
Subject: [PATCH 27/29] selftests: kvm: introduce basic test for VM planes
Check a few error cases and ensure that a vCPU can have a second plane
added to it. For now, all interactions happen through the bare
__vm_ioctl() interface or even directly through the ioctl() system
call.
Signed-off-by: Paolo Bonzini <pbonzini@...hat.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
tools/testing/selftests/kvm/plane_test.c | 108 +++++++++++++++++++++++
2 files changed, 109 insertions(+)
create mode 100644 tools/testing/selftests/kvm/plane_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index f62b0a5aba35..b1d0b410cc03 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -57,6 +57,7 @@ TEST_GEN_PROGS_COMMON += guest_print_test
TEST_GEN_PROGS_COMMON += kvm_binary_stats_test
TEST_GEN_PROGS_COMMON += kvm_create_max_vcpus
TEST_GEN_PROGS_COMMON += kvm_page_table_test
+TEST_GEN_PROGS_COMMON += plane_test
TEST_GEN_PROGS_COMMON += set_memory_region_test
# Compiled test targets
diff --git a/tools/testing/selftests/kvm/plane_test.c b/tools/testing/selftests/kvm/plane_test.c
new file mode 100644
index 000000000000..43c8de13490a
--- /dev/null
+++ b/tools/testing/selftests/kvm/plane_test.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 Red Hat, Inc.
+ *
+ * Test for architecture-neutral VM plane functionality
+ */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_util.h"
+
+#include "kvm_util.h"
+#include "asm/kvm.h"
+#include "linux/kvm.h"
+
+void test_create_plane_errors(int max_planes)
+{
+ struct kvm_vm *vm;
+ struct kvm_vcpu *vcpu;
+ int planefd, plane_vcpufd;
+
+ vm = vm_create_barebones();
+ vcpu = __vm_vcpu_add(vm, 0);
+
+ planefd = __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)0);
+ TEST_ASSERT(planefd == -1 && errno == EEXIST,
+ "Creating existing plane, expecting EEXIST. ret: %d, errno: %d",
+ planefd, errno);
+
+ planefd = __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)max_planes);
+ TEST_ASSERT(planefd == -1 && errno == EINVAL,
+ "Creating plane %d, expecting EINVAL. ret: %d, errno: %d",
+ max_planes, planefd, errno);
+
+ plane_vcpufd = __vm_ioctl(vm, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->fd);
+ TEST_ASSERT(plane_vcpufd == -1 && errno == ENOTTY,
+ "Creating vCPU for plane 0, expecting ENOTTY. ret: %d, errno: %d",
+ plane_vcpufd, errno);
+
+ kvm_vm_free(vm);
+ ksft_test_result_pass("error conditions\n");
+}
+
+void test_create_plane(void)
+{
+ struct kvm_vm *vm;
+ struct kvm_vcpu *vcpu;
+ int r, planefd, plane_vcpufd;
+
+ vm = vm_create_barebones();
+ vcpu = __vm_vcpu_add(vm, 0);
+
+ planefd = __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1);
+ TEST_ASSERT(planefd >= 0, "Creating new plane, got error: %d",
+ errno);
+
+ r = ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_PLANES);
+ TEST_ASSERT(r == 0,
+ "Checking KVM_CHECK_EXTENSION(KVM_CAP_PLANES). ret: %d", r);
+
+ r = ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_CHECK_EXTENSION_VM);
+ TEST_ASSERT(r == 1,
+ "Checking KVM_CHECK_EXTENSION(KVM_CAP_CHECK_EXTENSION_VM). ret: %d", r);
+
+ r = __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1);
+ TEST_ASSERT(r == -1 && errno == EEXIST,
+ "Creating existing plane, expecting EEXIST. ret: %d, errno: %d",
+ r, errno);
+
+ plane_vcpufd = ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->fd);
+ TEST_ASSERT(plane_vcpufd >= 0, "Creating vCPU for plane 1, got error: %d", errno);
+
+ r = ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->fd);
+ TEST_ASSERT(r == -1 && errno == EEXIST,
+ "Creating vCPU again for plane 1. ret: %d, errno: %d",
+ r, errno);
+
+ r = ioctl(planefd, KVM_RUN, (void *)(unsigned long)0);
+ TEST_ASSERT(r == -1 && errno == ENOTTY,
+ "Running plane vCPU again for plane 1. ret: %d, errno: %d",
+ r, errno);
+
+ close(plane_vcpufd);
+ close(planefd);
+
+ kvm_vm_free(vm);
+ ksft_test_result_pass("basic planefd and plane_vcpufd operation\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int cap_planes = kvm_check_cap(KVM_CAP_PLANES);
+ TEST_REQUIRE(cap_planes);
+
+ ksft_print_header();
+ ksft_set_plan(2);
+
+ pr_info("# KVM_CAP_PLANES: %d\n", cap_planes);
+
+ test_create_plane_errors(cap_planes);
+
+ if (cap_planes > 1)
+ test_create_plane();
+
+ ksft_finished();
+}
--
2.49.0
Powered by blists - more mailing lists