From nobody Thu May 8 20:00:18 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0726224243 for <linux-kernel@vger.kernel.org>; Tue, 1 Apr 2025 16:12:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523951; cv=none; b=MHrkFNYGD1O0ZVF89wtR2gNCLmFkMWUg/odoeaRp95jX4YQxHO8sLglwJhyvTsMDl8TCVFXNTPXJCSNEpO8kCCTm2Mv8nVjG3eqmm+hTSDwmaqz2Rk2J8Lqg47CMTjdh107yie85CrhDGElE8vVb/7CrtrTlOSuHUC8pTMMks44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523951; c=relaxed/simple; bh=IzgYPa9TLRk/unXxPit+XhBgPDXmtIE8BQwrHks1a1I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X7F0ZnqqWX+T1/hrhJ3IOJ2h8RxjAPiK5j795z5Ta+TY8/bQcXYlCeAQSnn1IWAQcJfy7hD0uYlUarTI99EPV9qoJLQjMcByO6SAVeecl4yr6LhRRWjrj6e5Ti7lYA+m/VmDRYb+9D6S0JNwz1eQ6X5XRwyJBClZShUHMBo5sk0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FskCZzmj; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FskCZzmj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523949; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ThjFpyMC5Hp17v5ZX3gmbcUwmxsf/SI/3VCI26Zru1Q=; b=FskCZzmjo+biTgYld/gpiRMW4B2e+sWznDvvJVRCIvziwmnB3QKsy9mCsAlXScE629cxVF S4+ESB1xsk5/2ZJjZSx3CbH41qf1YybYW8ci4LOnm2VR8Z9FOeiXwm64kxVkbKlPLBCL4Y 80i3NnAkJxHEo/zphfUKEWla89n1HMw= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-56-onhNahw8Ozedos648IqU4Q-1; Tue, 01 Apr 2025 12:12:27 -0400 X-MC-Unique: onhNahw8Ozedos648IqU4Q-1 X-Mimecast-MFC-AGG-ID: onhNahw8Ozedos648IqU4Q_1743523947 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-3912e4e2033so2464164f8f.0 for <linux-kernel@vger.kernel.org>; Tue, 01 Apr 2025 09:12:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523946; x=1744128746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ThjFpyMC5Hp17v5ZX3gmbcUwmxsf/SI/3VCI26Zru1Q=; b=KQNYI5C4vbL+6vZsOz8cUCOhMan9F5vE0Kyb0s3aImkmOpMYyEskzcQSWw7sNkxKCS tm+nw7VdtV8Ll/9uVV5O+FhdfcRvmaemWLTzFSLeNXds09pvVxP7oD40q8KEJnMDtqvU YDxEXs11onh3YiAETC2zM5ChFXLlvzEHkSVzwJ/VrG6HdTuhGPMmJrJxKnRCRhKExdam UTLJxrJFotwzdUDBINU8crhAdKp5v8bYegrn7PnF24n4aXAL3ZspgPZtqE66ITZKwcsW H5gGhQ2mp2+71VQRDvplGgAkhRrVr2lC5ihmLtGve1qHBUwPTFPq61HbmSbuO9TTEjgq ohZw== X-Gm-Message-State: AOJu0YwdzovWGZhqverwmsqGH2KRJ0JgljPtXQPkkn5hjRHFwf1ZybiB u97oUMtL/KTDUi0IL9+Np7k/XKpYZv3V7S3ZHBZjEe9lxrnYxLRmSSWkfjNMagidBgc99cAuGiz C+uaC+yT2E7pouyqTK/1vTfIMptde/mPmMNLgPgIHJdEvebqzH5ai+kdI+nsAVa3XafXYfwQPAQ TVA5SrO7zLd5ob4lk9H71NmfOu8mrYtgmSEyrkeke34KRZYg== X-Gm-Gg: ASbGnctEk5BXvFWWKzwGj3cz7f/sTWbRUfAWJUHZD9SNi8h6uigXd/uaRa5YPlM6IwJ LLFhNshUk1iCSGdvcIOBE9rtVaeEAXREq9sxeulNVegijSYe0jZhWpoPjNsFl7veUDEBLj67rgD W/mLwcLkD8TuLEm/2XKCdseBsy8/Xi37iPmjV7bO4vm+VcN370ZEHOAOqBCfbengndyJAR5eLPt pD1RgYag98FQFr59xS3AKjOV5XI4w9vWug6rCTSzZuk3x/JX4XSWXx2yd9auHmgdPH56DCcFgD+ ThlAWITR2RGl8jZjdXfIAQ== X-Received: by 2002:a5d:5984:0:b0:391:4095:49b7 with SMTP id ffacd0b85a97d-39c120e079amr11107187f8f.25.1743523946174; Tue, 01 Apr 2025 09:12:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEBwtO/kXcEsLY7KXcPjFkl0MSW5C3pyJQtoPcatQB9sVIkAZFxi2d3eLTTZNav5W8Iob3Pfw== X-Received: by 2002:a5d:5984:0:b0:391:4095:49b7 with SMTP id ffacd0b85a97d-39c120e079amr11107136f8f.25.1743523945640; Tue, 01 Apr 2025 09:12:25 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d830f5ea4sm206316555e9.25.2025.04.01.09.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:23 -0700 (PDT) From: Paolo Bonzini <pbonzini@redhat.com> To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 28/29] selftests: kvm: add plane infrastructure Date: Tue, 1 Apr 2025 18:11:05 +0200 Message-ID: <20250401161106.790710-29-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-1-pbonzini@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow creating plane and vCPU-plane file descriptors, and close them when the VM is freed. Rewrite the previous test using the new infrastructure (separate for easier review). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- .../testing/selftests/kvm/include/kvm_util.h | 48 ++++++++++++++ tools/testing/selftests/kvm/lib/kvm_util.c | 65 ++++++++++++++++++- tools/testing/selftests/kvm/plane_test.c | 21 +++--- 3 files changed, 119 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 373912464fb4..c1dfe071357e 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -67,6 +67,20 @@ struct kvm_vcpu { uint32_t dirty_gfns_count; }; =20 +struct kvm_plane { + struct list_head list; + uint32_t id; + int fd; + struct kvm_vm *vm; +}; + +struct kvm_plane_vcpu { + struct list_head list; + uint32_t id; + int fd; + struct kvm_vcpu *plane0; +}; + struct userspace_mem_regions { struct rb_root gpa_tree; struct rb_root hva_tree; @@ -93,6 +107,8 @@ struct kvm_vm { unsigned int va_bits; uint64_t max_gfn; struct list_head vcpus; + struct list_head planes; + struct list_head plane_vcpus; struct userspace_mem_regions regions; struct sparsebit *vpages_valid; struct sparsebit *vpages_mapped; @@ -338,6 +354,21 @@ do { \ __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, vm); \ }) =20 +static __always_inline void static_assert_is_plane(struct kvm_plane *plane= ) { } + +#define __plane_ioctl(plane, cmd, arg) \ +({ \ + static_assert_is_plane(plane); \ + kvm_do_ioctl((plane)->fd, cmd, arg); \ +}) + +#define plane_ioctl(plane, cmd, arg) \ +({ \ + int ret =3D __plane_ioctl(plane, cmd, arg); \ + \ + __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (plane)->vm); \ +}) + static __always_inline void static_assert_is_vcpu(struct kvm_vcpu *vcpu) {= } =20 #define __vcpu_ioctl(vcpu, cmd, arg) \ @@ -353,6 +384,21 @@ static __always_inline void static_assert_is_vcpu(stru= ct kvm_vcpu *vcpu) { } __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (vcpu)->vm); \ }) =20 +static __always_inline void static_assert_is_plane_vcpu(struct kvm_plane_v= cpu *plane_vcpu) { } + +#define __plane_vcpu_ioctl(plane_vcpu, cmd, arg) \ +({ \ + static_assert_is_plane_vcpu(plane_vcpu); \ + kvm_do_ioctl((plane_vcpu)->fd, cmd, arg); \ +}) + +#define plane_vcpu_ioctl(plane_vcpu, cmd, arg) \ +({ \ + int ret =3D __plane_vcpu_ioctl(plane_vcpu, cmd, arg); \ + \ + __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (plane_vcpu)->plane0->vm); \ +}) + /* * Looks up and returns the value corresponding to the capability * (KVM_CAP_*) given by cap. @@ -601,6 +647,8 @@ void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_= t slot, uint32_t flags); void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa= ); void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot); struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id); +struct kvm_plane *vm_plane_add(struct kvm_vm *vm, int plane_id); +struct kvm_plane_vcpu *__vm_plane_vcpu_add(struct kvm_vcpu *vcpu, struct k= vm_plane *plane); void vm_populate_vaddr_bitmap(struct kvm_vm *vm); vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t va= ddr_min); vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_m= in); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 815bc45dd8dc..a2f233945e1c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -279,6 +279,8 @@ struct kvm_vm *____vm_create(struct vm_shape shape) TEST_ASSERT(vm !=3D NULL, "Insufficient Memory"); =20 INIT_LIST_HEAD(&vm->vcpus); + INIT_LIST_HEAD(&vm->planes); + INIT_LIST_HEAD(&vm->plane_vcpus); vm->regions.gpa_tree =3D RB_ROOT; vm->regions.hva_tree =3D RB_ROOT; hash_init(vm->regions.slot_hash); @@ -757,10 +759,22 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_= vcpu *vcpu) =20 void kvm_vm_release(struct kvm_vm *vmp) { - struct kvm_vcpu *vcpu, *tmp; + struct kvm_vcpu *vcpu, *tmp_vcpu; + struct kvm_plane_vcpu *plane_vcpu, *tmp_plane_vcpu; + struct kvm_plane *plane, *tmp_plane; int ret; =20 - list_for_each_entry_safe(vcpu, tmp, &vmp->vcpus, list) + list_for_each_entry_safe(plane_vcpu, tmp_plane_vcpu, &vmp->plane_vcpus, l= ist) { + close(plane_vcpu->fd); + free(plane_vcpu); + } + + list_for_each_entry_safe(plane, tmp_plane, &vmp->planes, list) { + close(plane->fd); + free(plane); + } + + list_for_each_entry_safe(vcpu, tmp_vcpu, &vmp->vcpus, list) vm_vcpu_rm(vmp, vcpu); =20 ret =3D close(vmp->fd); @@ -1314,6 +1328,52 @@ static bool vcpu_exists(struct kvm_vm *vm, uint32_t = vcpu_id) return false; } =20 +/* + * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. + * No additional vCPU setup is done. Returns the vCPU. + */ +struct kvm_plane *vm_plane_add(struct kvm_vm *vm, int plane_id) +{ + struct kvm_plane *plane; + + /* Allocate and initialize new vcpu structure. */ + plane =3D calloc(1, sizeof(*plane)); + TEST_ASSERT(plane !=3D NULL, "Insufficient Memory"); + + plane->fd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)pla= ne_id); + TEST_ASSERT_VM_VCPU_IOCTL(plane->fd >=3D 0, KVM_CREATE_PLANE, plane->fd, = vm); + plane->vm =3D vm; + plane->id =3D plane_id; + + /* Add to linked-list of extra-plane VCPUs. */ + list_add(&plane->list, &vm->planes); + + return plane; +} + +/* + * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. + * No additional vCPU setup is done. Returns the vCPU. + */ +struct kvm_plane_vcpu *__vm_plane_vcpu_add(struct kvm_vcpu *vcpu, struct k= vm_plane *plane) +{ + struct kvm_plane_vcpu *plane_vcpu; + + /* Allocate and initialize new vcpu structure. */ + plane_vcpu =3D calloc(1, sizeof(*plane_vcpu)); + TEST_ASSERT(plane_vcpu !=3D NULL, "Insufficient Memory"); + + plane_vcpu->fd =3D __plane_ioctl(plane, KVM_CREATE_VCPU_PLANE, (void *)(u= nsigned long)vcpu->fd); + TEST_ASSERT_VM_VCPU_IOCTL(plane_vcpu->fd >=3D 0, KVM_CREATE_VCPU_PLANE, p= lane_vcpu->fd, plane->vm); + plane_vcpu->id =3D vcpu->id; + plane_vcpu->plane0 =3D vcpu; + + /* Add to linked-list of extra-plane VCPUs. */ + list_add(&plane_vcpu->list, &plane->vm->plane_vcpus); + + return plane_vcpu; +} + /* * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. * No additional vCPU setup is done. Returns the vCPU. @@ -2021,6 +2081,7 @@ static struct exit_reason { KVM_EXIT_STRING(NOTIFY), KVM_EXIT_STRING(LOONGARCH_IOCSR), KVM_EXIT_STRING(MEMORY_FAULT), + KVM_EXIT_STRING(PLANE_EVENT), }; =20 /* diff --git a/tools/testing/selftests/kvm/plane_test.c b/tools/testing/selft= ests/kvm/plane_test.c index 43c8de13490a..9cf3ab76b3cd 100644 --- a/tools/testing/selftests/kvm/plane_test.c +++ b/tools/testing/selftests/kvm/plane_test.c @@ -47,20 +47,19 @@ void test_create_plane(void) { struct kvm_vm *vm; struct kvm_vcpu *vcpu; - int r, planefd, plane_vcpufd; + struct kvm_plane *plane; + int r; =20 vm =3D vm_create_barebones(); vcpu =3D __vm_vcpu_add(vm, 0); =20 - planefd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1); - TEST_ASSERT(planefd >=3D 0, "Creating new plane, got error: %d", - errno); + plane =3D vm_plane_add(vm, 1); =20 - r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_PLANES); + r =3D __plane_ioctl(plane, KVM_CHECK_EXTENSION, (void *)(unsigned long)KV= M_CAP_PLANES); TEST_ASSERT(r =3D=3D 0, "Checking KVM_CHECK_EXTENSION(KVM_CAP_PLANES). ret: %d", r); =20 - r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_CHECK_EXTENSION_VM); + r =3D __plane_ioctl(plane, KVM_CHECK_EXTENSION, (void *)(unsigned long)KV= M_CAP_CHECK_EXTENSION_VM); TEST_ASSERT(r =3D=3D 1, "Checking KVM_CHECK_EXTENSION(KVM_CAP_CHECK_EXTENSION_VM). ret: %d",= r); =20 @@ -69,22 +68,18 @@ void test_create_plane(void) "Creating existing plane, expecting EEXIST. ret: %d, errno: %d", r, errno); =20 - plane_vcpufd =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned = long)vcpu->fd); - TEST_ASSERT(plane_vcpufd >=3D 0, "Creating vCPU for plane 1, got error: %= d", errno); + __vm_plane_vcpu_add(vcpu, plane); =20 - r =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->= fd); + r =3D __plane_ioctl(plane, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)= vcpu->fd); TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, "Creating vCPU again for plane 1. ret: %d, errno: %d", r, errno); =20 - r =3D ioctl(planefd, KVM_RUN, (void *)(unsigned long)0); + r =3D __plane_ioctl(plane, KVM_RUN, (void *)(unsigned long)0); TEST_ASSERT(r =3D=3D -1 && errno =3D=3D ENOTTY, "Running plane vCPU again for plane 1. ret: %d, errno: %d", r, errno); =20 - close(plane_vcpufd); - close(planefd); - kvm_vm_free(vm); ksft_test_result_pass("basic planefd and plane_vcpufd operation\n"); } --=20 2.49.0