From nobody Sun Feb 8 23:03:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35ECAC001DE for ; Tue, 18 Jul 2023 23:53:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231226AbjGRXxF (ORCPT ); Tue, 18 Jul 2023 19:53:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231468AbjGRXvf (ORCPT ); Tue, 18 Jul 2023 19:51:35 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B50EE1FCA for ; Tue, 18 Jul 2023 16:49:56 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-1b9de3e7fb1so32328785ad.1 for ; Tue, 18 Jul 2023 16:49:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1689724156; x=1692316156; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=Q98IcrUH3D9bs3/KGOraZ2fk7jlneSyp5eOXwjGSzPo=; b=7kCME8pPCngu4gaFGpXg5a7UwFpOLrO0My4DJgf3Tu41/gplqgzLOGhIhYQhJyAw82 pOUm0o0ToYchYR+sqCJB8nr8JQwkY05K+mmvehoPNKX+xtAJe85ypqZrf7NdEBuc7dVO Loia1s+Vi2KmoQuGxm/1vLkByuS5Llxi1PwzbhcxuMWRdPNpQbFdZ1M0EUvFj2O4HykG lFhG2TpgpmRIG1QsBv9/L63IGFhxigQF4dGb407i8DsIDC4msrdSTzNotl+OShvkqjOU uJoKfxiuAmED0YbOhUTgqzr2Njgz4J6LJbFZG7TW80PXAaqsgV0K7Lq43642a6sItsfg Wm6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689724156; x=1692316156; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Q98IcrUH3D9bs3/KGOraZ2fk7jlneSyp5eOXwjGSzPo=; b=IhILKQMxwI7gBiZomwKa0hPtDbdG4bySFe0d/LLmEntRvwfyYJbCG1ha8QyIHEU30f xKvFH1UPTUYgbEDklwCpWlkglQLCxQXm7rzt5S08aTv+9mL8p5lbZx/RYmUP7WMT4Xdd TahupeDENJZ/ub2yYswb2qWrJ2EMKAk7kfwIqWHNsgt1R/z+jzKBJSDlLx9v533fMPIm reUpDvQ20tG+dbKPA+tkh+sv7xSUdTr3toVgxrS+C1PoJ17gIC7HnDM4jRF0Po/VP1Jy bry9/qTG3spJbRkATogcJbjKE9vWHWxWi0UCWDqtiD4UMDLYrB1sZCtIFGTKPv0R4AHH Ea5g== X-Gm-Message-State: ABy/qLaG36VtQ2SR54iLrdc69u7qgh9tk9OEwQFxxZ9YuQe1hE729I60 Q/RIMd5Xw+ln5wemjLHRc/CvVUdMgyg= X-Google-Smtp-Source: APBJJlGNaFpMXi9SkErxKUtHkpkIjtXAaXLFttzvWMq3kzuSVkOJWJ0e7R+lluyhOtMVN8C9CK1Syvi8Yw4= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:903:22ce:b0:1b8:80c9:a98e with SMTP id y14-20020a17090322ce00b001b880c9a98emr18845plg.13.1689724155930; Tue, 18 Jul 2023 16:49:15 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 18 Jul 2023 16:45:06 -0700 In-Reply-To: <20230718234512.1690985-1-seanjc@google.com> Mime-Version: 1.0 References: <20230718234512.1690985-1-seanjc@google.com> X-Mailer: git-send-email 2.41.0.255.g8b1d071c50-goog Message-ID: <20230718234512.1690985-24-seanjc@google.com> Subject: [RFC PATCH v11 23/29] KVM: selftests: Introduce VM "shape" to allow tests to specify the VM type From: Sean Christopherson To: Paolo Bonzini , Marc Zyngier , Oliver Upton , Huacai Chen , Michael Ellerman , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Sean Christopherson , "Matthew Wilcox (Oracle)" , Andrew Morton , Paul Moore , James Morris , "Serge E. Hallyn" Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Chao Peng , Fuad Tabba , Jarkko Sakkinen , Yu Zhang , Vishal Annapurve , Ackerley Tng , Maciej Szmigiero , Vlastimil Babka , David Hildenbrand , Quentin Perret , Michael Roth , Wang , Liam Merwick , Isaku Yamahata , "Kirill A . Shutemov" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/dirty_log_test.c | 2 +- .../selftests/kvm/include/kvm_util_base.h | 54 +++++++++++++++---- .../selftests/kvm/kvm_page_table_test.c | 2 +- tools/testing/selftests/kvm/lib/kvm_util.c | 43 +++++++-------- tools/testing/selftests/kvm/lib/memstress.c | 3 +- .../kvm/x86_64/ucna_injection_test.c | 2 +- 6 files changed, 72 insertions(+), 34 deletions(-) diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/s= elftests/kvm/dirty_log_test.c index 936f3a8d1b83..6cbecf499767 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -699,7 +699,7 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode= , struct kvm_vcpu **vcpu, =20 pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode)); =20 - vm =3D __vm_create(mode, 1, extra_mem_pages); + vm =3D __vm_create(VM_SHAPE(mode), 1, extra_mem_pages); =20 log_mode_create_vm_done(vm); *vcpu =3D vm_vcpu_add(vm, 0, guest_code); diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 1819787b773b..856440294013 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -167,6 +167,23 @@ enum vm_guest_mode { NUM_VM_MODES, }; =20 +struct vm_shape { + enum vm_guest_mode mode; + unsigned int type; +}; + +#define VM_TYPE_DEFAULT 0 + +#define VM_SHAPE(__mode) \ +({ \ + struct vm_shape shape =3D { \ + .mode =3D (__mode), \ + .type =3D VM_TYPE_DEFAULT \ + }; \ + \ + shape; \ +}) + #if defined(__aarch64__) =20 extern enum vm_guest_mode vm_mode_default; @@ -199,6 +216,8 @@ extern enum vm_guest_mode vm_mode_default; =20 #endif =20 +#define VM_SHAPE_DEFAULT VM_SHAPE(VM_MODE_DEFAULT) + #define MIN_PAGE_SIZE (1U << MIN_PAGE_SHIFT) #define PTES_PER_MIN_PAGE ptes_per_page(MIN_PAGE_SIZE) =20 @@ -754,21 +773,21 @@ vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm); * __vm_create() does NOT create vCPUs, @nr_runnable_vcpus is used purely = to * calculate the amount of memory needed for per-vCPU data, e.g. stacks. */ -struct kvm_vm *____vm_create(enum vm_guest_mode mode); -struct kvm_vm *__vm_create(enum vm_guest_mode mode, uint32_t nr_runnable_v= cpus, +struct kvm_vm *____vm_create(struct vm_shape shape); +struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, uint64_t nr_extra_pages); =20 static inline struct kvm_vm *vm_create_barebones(void) { - return ____vm_create(VM_MODE_DEFAULT); + return ____vm_create(VM_SHAPE_DEFAULT); } =20 static inline struct kvm_vm *vm_create(uint32_t nr_runnable_vcpus) { - return __vm_create(VM_MODE_DEFAULT, nr_runnable_vcpus, 0); + return __vm_create(VM_SHAPE_DEFAULT, nr_runnable_vcpus, 0); } =20 -struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr= _vcpus, +struct kvm_vm *__vm_create_with_vcpus(struct vm_shape shape, uint32_t nr_v= cpus, uint64_t extra_mem_pages, void *guest_code, struct kvm_vcpu *vcpus[]); =20 @@ -776,17 +795,27 @@ static inline struct kvm_vm *vm_create_with_vcpus(uin= t32_t nr_vcpus, void *guest_code, struct kvm_vcpu *vcpus[]) { - return __vm_create_with_vcpus(VM_MODE_DEFAULT, nr_vcpus, 0, + return __vm_create_with_vcpus(VM_SHAPE_DEFAULT, nr_vcpus, 0, guest_code, vcpus); } =20 + +struct kvm_vm *__vm_create_shape_with_one_vcpu(struct vm_shape shape, + struct kvm_vcpu **vcpu, + uint64_t extra_mem_pages, + void *guest_code); + /* * Create a VM with a single vCPU with reasonable defaults and @extra_mem_= pages * additional pages of guest memory. Returns the VM and vCPU (via out par= am). */ -struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, - uint64_t extra_mem_pages, - void *guest_code); +static inline struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **v= cpu, + uint64_t extra_mem_pages, + void *guest_code) +{ + return __vm_create_shape_with_one_vcpu(VM_SHAPE_DEFAULT, vcpu, + extra_mem_pages, guest_code); +} =20 static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcp= u, void *guest_code) @@ -794,6 +823,13 @@ static inline struct kvm_vm *vm_create_with_one_vcpu(s= truct kvm_vcpu **vcpu, return __vm_create_with_one_vcpu(vcpu, 0, guest_code); } =20 +static inline struct kvm_vm *vm_create_shape_with_one_vcpu(struct vm_shape= shape, + struct kvm_vcpu **vcpu, + void *guest_code) +{ + return __vm_create_shape_with_one_vcpu(shape, vcpu, 0, guest_code); +} + struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); =20 void kvm_pin_this_task_to_pcpu(uint32_t pcpu); diff --git a/tools/testing/selftests/kvm/kvm_page_table_test.c b/tools/test= ing/selftests/kvm/kvm_page_table_test.c index b3b00be1ef82..e8c2aabbca2b 100644 --- a/tools/testing/selftests/kvm/kvm_page_table_test.c +++ b/tools/testing/selftests/kvm/kvm_page_table_test.c @@ -254,7 +254,7 @@ static struct kvm_vm *pre_init_before_test(enum vm_gues= t_mode mode, void *arg) =20 /* Create a VM with enough guest pages */ guest_num_pages =3D test_mem_size / guest_page_size; - vm =3D __vm_create_with_vcpus(mode, nr_vcpus, guest_num_pages, + vm =3D __vm_create_with_vcpus(VM_SHAPE(mode), nr_vcpus, guest_num_pages, guest_code, test_args.vcpus); =20 /* Align down GPA of the testing memslot */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 1283e24b76f1..64221c320389 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -209,7 +209,7 @@ __weak void vm_vaddr_populate_bitmap(struct kvm_vm *vm) (1ULL << (vm->va_bits - 1)) >> vm->page_shift); } =20 -struct kvm_vm *____vm_create(enum vm_guest_mode mode) +struct kvm_vm *____vm_create(struct vm_shape shape) { struct kvm_vm *vm; =20 @@ -221,13 +221,13 @@ struct kvm_vm *____vm_create(enum vm_guest_mode mode) vm->regions.hva_tree =3D RB_ROOT; hash_init(vm->regions.slot_hash); =20 - vm->mode =3D mode; - vm->type =3D 0; + vm->mode =3D shape.mode; + vm->type =3D shape.type; =20 - vm->pa_bits =3D vm_guest_mode_params[mode].pa_bits; - vm->va_bits =3D vm_guest_mode_params[mode].va_bits; - vm->page_size =3D vm_guest_mode_params[mode].page_size; - vm->page_shift =3D vm_guest_mode_params[mode].page_shift; + vm->pa_bits =3D vm_guest_mode_params[vm->mode].pa_bits; + vm->va_bits =3D vm_guest_mode_params[vm->mode].va_bits; + vm->page_size =3D vm_guest_mode_params[vm->mode].page_size; + vm->page_shift =3D vm_guest_mode_params[vm->mode].page_shift; =20 /* Setup mode specific traits. */ switch (vm->mode) { @@ -265,7 +265,7 @@ struct kvm_vm *____vm_create(enum vm_guest_mode mode) /* * Ignore KVM support for 5-level paging (vm->va_bits =3D=3D 57), * it doesn't take effect unless a CR4.LA57 is set, which it - * isn't for this VM_MODE. + * isn't for this mode (48-bit virtual address space). */ TEST_ASSERT(vm->va_bits =3D=3D 48 || vm->va_bits =3D=3D 57, "Linear address width (%d bits) not supported", @@ -285,10 +285,11 @@ struct kvm_vm *____vm_create(enum vm_guest_mode mode) vm->pgtable_levels =3D 5; break; default: - TEST_FAIL("Unknown guest mode, mode: 0x%x", mode); + TEST_FAIL("Unknown guest mode: 0x%x", vm->mode); } =20 #ifdef __aarch64__ + TEST_ASSERT(!vm->type, "ARM doesn't support test-provided types"); if (vm->pa_bits !=3D 40) vm->type =3D KVM_VM_TYPE_ARM_IPA_SIZE(vm->pa_bits); #endif @@ -343,19 +344,19 @@ static uint64_t vm_nr_pages_required(enum vm_guest_mo= de mode, return vm_adjust_num_guest_pages(mode, nr_pages); } =20 -struct kvm_vm *__vm_create(enum vm_guest_mode mode, uint32_t nr_runnable_v= cpus, +struct kvm_vm *__vm_create(struct vm_shape shape, uint32_t nr_runnable_vcp= us, uint64_t nr_extra_pages) { - uint64_t nr_pages =3D vm_nr_pages_required(mode, nr_runnable_vcpus, + uint64_t nr_pages =3D vm_nr_pages_required(shape.mode, nr_runnable_vcpus, nr_extra_pages); struct userspace_mem_region *slot0; struct kvm_vm *vm; int i; =20 - pr_debug("%s: mode=3D'%s' pages=3D'%ld'\n", __func__, - vm_guest_mode_string(mode), nr_pages); + pr_debug("%s: mode=3D'%s' type=3D'%d', pages=3D'%ld'\n", __func__, + vm_guest_mode_string(shape.mode), shape.type, nr_pages); =20 - vm =3D ____vm_create(mode); + vm =3D ____vm_create(shape); =20 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0, 0, nr_pages, 0); for (i =3D 0; i < NR_MEM_REGIONS; i++) @@ -396,7 +397,7 @@ struct kvm_vm *__vm_create(enum vm_guest_mode mode, uin= t32_t nr_runnable_vcpus, * extra_mem_pages is only used to calculate the maximum page table size, * no real memory allocation for non-slot0 memory in this function. */ -struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr= _vcpus, +struct kvm_vm *__vm_create_with_vcpus(struct vm_shape shape, uint32_t nr_v= cpus, uint64_t extra_mem_pages, void *guest_code, struct kvm_vcpu *vcpus[]) { @@ -405,7 +406,7 @@ struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_mod= e mode, uint32_t nr_vcpus =20 TEST_ASSERT(!nr_vcpus || vcpus, "Must provide vCPU array"); =20 - vm =3D __vm_create(mode, nr_vcpus, extra_mem_pages); + vm =3D __vm_create(shape, nr_vcpus, extra_mem_pages); =20 for (i =3D 0; i < nr_vcpus; ++i) vcpus[i] =3D vm_vcpu_add(vm, i, guest_code); @@ -413,15 +414,15 @@ struct kvm_vm *__vm_create_with_vcpus(enum vm_guest_m= ode mode, uint32_t nr_vcpus return vm; } =20 -struct kvm_vm *__vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, - uint64_t extra_mem_pages, - void *guest_code) +struct kvm_vm *__vm_create_shape_with_one_vcpu(struct vm_shape shape, + struct kvm_vcpu **vcpu, + uint64_t extra_mem_pages, + void *guest_code) { struct kvm_vcpu *vcpus[1]; struct kvm_vm *vm; =20 - vm =3D __vm_create_with_vcpus(VM_MODE_DEFAULT, 1, extra_mem_pages, - guest_code, vcpus); + vm =3D __vm_create_with_vcpus(shape, 1, extra_mem_pages, guest_code, vcpu= s); =20 *vcpu =3D vcpus[0]; return vm; diff --git a/tools/testing/selftests/kvm/lib/memstress.c b/tools/testing/se= lftests/kvm/lib/memstress.c index df457452d146..d05487e5a371 100644 --- a/tools/testing/selftests/kvm/lib/memstress.c +++ b/tools/testing/selftests/kvm/lib/memstress.c @@ -168,7 +168,8 @@ struct kvm_vm *memstress_create_vm(enum vm_guest_mode m= ode, int nr_vcpus, * The memory is also added to memslot 0, but that's a benign side * effect as KVM allows aliasing HVAs in meslots. */ - vm =3D __vm_create_with_vcpus(mode, nr_vcpus, slot0_pages + guest_num_pag= es, + vm =3D __vm_create_with_vcpus(VM_SHAPE(mode), nr_vcpus, + slot0_pages + guest_num_pages, memstress_guest_code, vcpus); =20 args->vm =3D vm; diff --git a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c b/too= ls/testing/selftests/kvm/x86_64/ucna_injection_test.c index 85f34ca7e49e..0ed32ec903d0 100644 --- a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c +++ b/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c @@ -271,7 +271,7 @@ int main(int argc, char *argv[]) =20 kvm_check_cap(KVM_CAP_MCE); =20 - vm =3D __vm_create(VM_MODE_DEFAULT, 3, 0); + vm =3D __vm_create(VM_SHAPE_DEFAULT, 3, 0); =20 kvm_ioctl(vm->kvm_fd, KVM_X86_GET_MCE_CAP_SUPPORTED, &supported_mcg_caps); --=20 2.41.0.255.g8b1d071c50-goog