From nobody Sun Sep 14 14:58:58 2025 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 819B7C27C76 for ; Sat, 21 Jan 2023 00:19:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229972AbjAUATr (ORCPT ); Fri, 20 Jan 2023 19:19:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229558AbjAUATp (ORCPT ); Fri, 20 Jan 2023 19:19:45 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9690173ADE for ; Fri, 20 Jan 2023 16:19:07 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-4faa8f4bfb9so62583937b3.17 for ; Fri, 20 Jan 2023 16:19:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=g5VuYA7TfsmgF2IHsazybR3ND1uceEDVTzczLitCcAI=; b=AELPrk1zBkNIV9cP+6+WXe2bVRfYoHvxNjoMs7iwc+ivh9gsI07Q+Bc/tiz/KjOul6 fDPoOU+FuoKeDVcWBv8OSHis/6i5iGmPc7YfJqjbM2IuEsKAVmO2YCXUslLxkpb5dDdg AOCiOLWNIb0NxWYVQZn4WUQwpXoAiLzKvjEGNXInDpjjzWkSasuDKjTa822uYkaHxbBG V0omf+WQMWPjk66vRiouDdId4GvlaMLGQw2CEqaurBUIl1DYGcpF9TOjjRG+uKF7mKIO LAqJ5Ie9Dz0YYsaqeX0PLyjoow/xxe4R0LzNB4BEa3C8eAaFZDOGS0Ak6U29A4+ubDOV 8JOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=g5VuYA7TfsmgF2IHsazybR3ND1uceEDVTzczLitCcAI=; b=1tXFcyyF/ETqe6jnoDCfy1pnQ/PtAO7XBl4/GsN0gn6nnYjGPBIVkKTfk5cB+Va0/z WCbBA2BFgIsftnGfoC9nZ4X5sN0aaY7poQX/ouOj57wowwfcXcfl0l+BvZMbKmV1c5mD /KRTrSkLsR+TP4fyV2tAVd1NOq3uShaxeGC0RkDwGCszzETxx/xXUHnAKJ+MjnUs5dNB jUMokkSMvcxpXam8P2Y2q5K/jMtOdSBSViLURuIsNEzTuTnK03/X3YWejydq5LlBk9Lc MftCDi7A0b6S/dmLN5odRU1CJZlcqsuf9hnxgIX3udsDbNF2trLexaNsure2OoP6BOuj 7UvQ== X-Gm-Message-State: AFqh2kqkk4xF0hK8cckN+YXoVbuVdGn2pdHtxmVA9YPUCZ11xaAOzfQQ KrkrAiN+vhg7vO6KEdcBd/IkIFVbeCpCZ65Esg== X-Google-Smtp-Source: AMrXdXvuSjsl6TR8kJdBnnBblDEK81ds6Q5bjRNVFbE846CCJXHQ5fcuyFgRXnB7ys47BAOCndeG1//KafcQ1cJ9ZQ== X-Received: from ackerleytng-cloudtop-sg.c.googlers.com ([fda3:e722:ac3:cc00:4f:4b78:c0a8:b30]) (user=ackerleytng job=sendgmr) by 2002:a81:1754:0:b0:4fd:ff18:de6c with SMTP id 81-20020a811754000000b004fdff18de6cmr436255ywx.227.1674260281776; Fri, 20 Jan 2023 16:18:01 -0800 (PST) Date: Sat, 21 Jan 2023 00:15:36 +0000 In-Reply-To: <20230121001542.2472357-1-ackerleytng@google.com> Mime-Version: 1.0 References: <20230121001542.2472357-1-ackerleytng@google.com> X-Mailer: git-send-email 2.39.0.246.g2a6d74b583-goog Message-ID: <20230121001542.2472357-26-ackerleytng@google.com> Subject: [RFC PATCH v3 25/31] KVM: selftests: Add support for restricted memory From: Ackerley Tng To: linux-kselftest@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, isaku.yamahata@intel.com, sagis@google.com, erdemaktas@google.com, afranji@google.com, runanwang@google.com, shuah@kernel.org, drjones@redhat.com, maz@kernel.org, bgardon@google.com, jmattson@google.com, dmatlack@google.com, peterx@redhat.com, oupton@google.com, ricarkol@google.com, yang.zhong@intel.com, wei.w.wang@intel.com, xiaoyao.li@intel.com, pgonda@google.com, marcorr@google.com, eesposit@redhat.com, borntraeger@de.ibm.com, eric.auger@redhat.com, wangyanan55@huawei.com, aaronlewis@google.com, vkuznets@redhat.com, pshier@google.com, axelrasmussen@google.com, zhenzhong.duan@intel.com, maciej.szmigiero@oracle.com, like.xu@linux.intel.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Ackerley Tng Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With this, vm_userspace_mem_region_add() can use restricted memory to back guest memory. Signed-off-by: Ackerley Tng --- .../selftests/kvm/include/kvm_util_base.h | 7 ++- .../testing/selftests/kvm/include/test_util.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 48 ++++++++++++++++--- tools/testing/selftests/kvm/lib/test_util.c | 7 +++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/te= sting/selftests/kvm/include/kvm_util_base.h index 30453e2de8396..950fd337898e1 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -33,7 +33,10 @@ typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) = physical address */ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ =20 struct userspace_mem_region { - struct kvm_userspace_memory_region region; + union { + struct kvm_userspace_memory_region region; + struct kvm_userspace_memory_region_ext region_ext; + }; struct sparsebit *unused_phy_pages; struct sparsebit *protected_phy_pages; int fd; @@ -214,7 +217,7 @@ static inline bool kvm_has_cap(long cap) =20 #define kvm_do_ioctl(fd, cmd, arg) \ ({ \ - static_assert(!_IOC_SIZE(cmd) || sizeof(*arg) =3D=3D _IOC_SIZE(cmd), "");= \ + static_assert(!_IOC_SIZE(cmd) || sizeof(*arg) >=3D _IOC_SIZE(cmd), ""); \ ioctl(fd, cmd, arg); \ }) =20 diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testin= g/selftests/kvm/include/test_util.h index befc754ce9b3b..01456a78b3a2e 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -94,6 +94,7 @@ enum vm_mem_backing_src_type { VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB, VM_MEM_SRC_ANONYMOUS_HUGETLB_2GB, VM_MEM_SRC_ANONYMOUS_HUGETLB_16GB, + VM_MEM_SRC_ANONYMOUS_AND_RESTRICTED_MEMFD, VM_MEM_SRC_SHMEM, VM_MEM_SRC_SHARED_HUGETLB, NUM_SRC_TYPES, @@ -104,6 +105,7 @@ enum vm_mem_backing_src_type { struct vm_mem_backing_src_alias { const char *name; uint32_t flag; + bool need_restricted_memfd; }; =20 #define MIN_RUN_DELAY_NS 200000UL diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 6673be2f49c31..4e5928fa71c44 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -15,7 +15,6 @@ #include #include #include -#include =20 #define KVM_UTIL_MIN_PFN 2 =20 @@ -799,6 +798,27 @@ void vm_set_user_memory_region(struct kvm_vm *vm, uint= 32_t slot, uint32_t flags, errno, strerror(errno)); } =20 +/** + * Initialize memory in restricted_fd with size @memory_region_size and re= turn + * the fd. + * + * Errors out if there's any error + */ +static int initialize_restricted_memfd(uint64_t memory_region_size) +{ + int ret; + int mfd =3D -1; + + mfd =3D syscall(__NR_memfd_restricted, 0); + TEST_ASSERT(mfd !=3D -1, "Failed to create private memfd"); + ret =3D ftruncate(mfd, memory_region_size); + TEST_ASSERT(ret !=3D -1, "Failed to resize memfd %d to %lx", mfd, memory_= region_size); + ret =3D fallocate(mfd, 0, 0, memory_region_size); + TEST_ASSERT(ret !=3D -1, "Failed to allocate %lx bytes in memfd %d", memo= ry_region_size, mfd); + + return mfd; +} + /* * VM Userspace Memory Region Add * @@ -830,6 +850,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, struct userspace_mem_region *region; size_t backing_src_pagesz =3D get_backing_src_pagesz(src_type); size_t alignment; + int restricted_memfd =3D -1; =20 TEST_ASSERT(vm_adjust_num_guest_pages(vm->mode, npages) =3D=3D npages, "Number of guest pages is not compatible with the host. " @@ -927,14 +948,24 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, =20 /* As needed perform madvise */ if ((src_type =3D=3D VM_MEM_SRC_ANONYMOUS || - src_type =3D=3D VM_MEM_SRC_ANONYMOUS_THP) && thp_configured()) { - ret =3D madvise(region->host_mem, npages * vm->page_size, - src_type =3D=3D VM_MEM_SRC_ANONYMOUS ? MADV_NOHUGEPAGE : MADV_HUG= EPAGE); + src_type =3D=3D VM_MEM_SRC_ANONYMOUS_THP || + src_type =3D=3D VM_MEM_SRC_ANONYMOUS_AND_RESTRICTED_MEMFD) && thp_co= nfigured()) { + int advice =3D src_type =3D=3D VM_MEM_SRC_ANONYMOUS_THP + ? MADV_HUGEPAGE + : MADV_NOHUGEPAGE; + ret =3D madvise(region->host_mem, npages * vm->page_size, advice); TEST_ASSERT(ret =3D=3D 0, "madvise failed, addr: %p length: 0x%lx src_ty= pe: %s", region->host_mem, npages * vm->page_size, vm_mem_backing_src_alias(src_type)->name); } =20 + if (vm_mem_backing_src_alias(src_type)->need_restricted_memfd) { + restricted_memfd =3D initialize_restricted_memfd(npages * vm->page_size); + TEST_ASSERT(restricted_memfd !=3D -1, + "Failed to create restricted memfd"); + flags |=3D KVM_MEM_PRIVATE; + } + region->unused_phy_pages =3D sparsebit_alloc(); region->protected_phy_pages =3D sparsebit_alloc(); sparsebit_set_num(region->unused_phy_pages, @@ -944,13 +975,16 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, region->region.guest_phys_addr =3D guest_paddr; region->region.memory_size =3D npages * vm->page_size; region->region.userspace_addr =3D (uintptr_t) region->host_mem; - ret =3D __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region); + region->region_ext.restricted_fd =3D restricted_memfd; + region->region_ext.restricted_offset =3D 0; + ret =3D __vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion->region_ext); TEST_ASSERT(ret =3D=3D 0, "KVM_SET_USER_MEMORY_REGION IOCTL failed,\n" " rc: %i errno: %i\n" " slot: %u flags: 0x%x\n" - " guest_phys_addr: 0x%lx size: 0x%lx", + " guest_phys_addr: 0x%lx size: 0x%lx restricted_fd: %d", ret, errno, slot, flags, - guest_paddr, (uint64_t) region->region.memory_size); + guest_paddr, (uint64_t) region->region.memory_size, + restricted_memfd); =20 /* Add to quick lookup data structures */ vm_userspace_mem_region_gpa_insert(&vm->regions.gpa_tree, region); diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/se= lftests/kvm/lib/test_util.c index 6d23878bbfe1a..2d53e55d13565 100644 --- a/tools/testing/selftests/kvm/lib/test_util.c +++ b/tools/testing/selftests/kvm/lib/test_util.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -254,6 +255,11 @@ const struct vm_mem_backing_src_alias *vm_mem_backing_= src_alias(uint32_t i) */ .flag =3D MAP_SHARED, }, + [VM_MEM_SRC_ANONYMOUS_AND_RESTRICTED_MEMFD] =3D { + .name =3D "anonymous_and_restricted_memfd", + .flag =3D ANON_FLAGS, + .need_restricted_memfd =3D true, + }, }; _Static_assert(ARRAY_SIZE(aliases) =3D=3D NUM_SRC_TYPES, "Missing new backing src types?"); @@ -272,6 +278,7 @@ size_t get_backing_src_pagesz(uint32_t i) switch (i) { case VM_MEM_SRC_ANONYMOUS: case VM_MEM_SRC_SHMEM: + case VM_MEM_SRC_ANONYMOUS_AND_RESTRICTED_MEMFD: return getpagesize(); case VM_MEM_SRC_ANONYMOUS_THP: return get_trans_hugepagesz(); --=20 2.39.0.246.g2a6d74b583-goog