From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 354CE31282F; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=KrioOV8vceSKst3u6jhNAx3sSMidjojVPIrpyuySI74/KwcXC2zgT6pHjfB1NYnNUSA94nxC+CryvwJoKRI7eA05d1wIdFkejUfICDJYQ/D4G2VUwpWjhsG+BLVXnkpz2tIW6mT0MBbkKI/pIyluvm3SInjLSYPKXWMJhPeZj6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=tEia40dB0p9J7pUU5lkk/Q96P0r+DPH1vw/1+oo1knU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q2hIIqOvFOsNqxawHgB+lIuI0YzSOI69uE8WZUM5/KAG5CEF0NaPkHuPpyGnhI0GKN6BusTk9XaqDkUUjY+2cXKNU8N/apdcobXgge3wnAn0lgkdSCXdjss79657fN7fPhOp/XHvNrWiZs+oKWNASWhfLRiLdvbMRHsmIyVKA28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BxAyebrF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BxAyebrF" Received: by smtp.kernel.org (Postfix) with ESMTPS id D92F5C2BCFA; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139567; bh=tEia40dB0p9J7pUU5lkk/Q96P0r+DPH1vw/1+oo1knU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=BxAyebrF8yoM9SF9HWfvC+ByEeTj+wv03T7fXCx02EsIf7f85q8+YdyNABC0x5Gxz fB3uNz1nWCs+8gWUl4agEO0S8JgcL4aHGxvIIUJQo+hvYvIFtMmXrgSfDTJvEtGzC+ LhIRjmvlM11CkRqmRHJ4/eCWmamOYdgddbBU+OzvRG6VrB2zHgz3Kkj2GBxptPihgd NDZxraEF6ojvQxXhmCZ2jdrwGVDxQLHl4JXjEnsG8HYdX7o3wu1yHpl9rgnqu8ClKK IC5IVHqWWLSZ39C/9HC3M1d8WMOI9V8lzSzskId/loIRYnJPw1AqgPabHByo5vzNdY XGBOk35biEkoA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0383C5ACAB; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:40 -0700 Subject: [PATCH v10 01/41] KVM: guest_memfd: Use kvm_mem_is_private() when populating guest_memfd memory Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-1-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=1090; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=sAMqSCb/MXVvnJq73E9rSMuOWQstWqj6/6Qg36KPzcU=; b=cmKf8pfXyJOIt2jhLTeNcCrFZyW63ls9RwHVg/1LQjI5AItwXbeFEGikLMFxnoMSYbqbA+Wul +5dWBJzgS9oBFaZbki6inPmHvz4xHU/CUHWwk3oNbfC+Mszy+HKIiQ2 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Using kvm_mem_is_private() when populating guest_memfd instead of using an open coded equivalent. In addition to simplifying the populate code *now*, this avoids the need to provide a range-based gmem lookup API in the future as well. No functional change intended. Suggested-by: Xiaoyao Li Signed-off-by: Sean Christopherson Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu Reviewed-by: Fuad Tabba Reviewed-by: Xiaoyao Li --- virt/kvm/guest_memfd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index b596486d184ca..a11cf6dc785da 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -811,9 +811,7 @@ static long __kvm_gmem_populate(struct kvm *kvm, struct= kvm_memory_slot *slot, =20 folio_unlock(folio); =20 - if (!kvm_range_has_memory_attributes(kvm, gfn, gfn + 1, - KVM_MEMORY_ATTRIBUTE_PRIVATE, - KVM_MEMORY_ATTRIBUTE_PRIVATE)) { + if (!kvm_mem_is_private(kvm, gfn)) { ret =3D -EINVAL; goto out_put_folio; } --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 41BBF36896D; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=G4G8YCzJUzB4ZgW9xqXwCyL2Yt332fY/Fh6KFTGG03vsnSnbT2F1Bpm/g8rUcHKBhHKS/NAN4yzsndvtq/ESwX7BQyUTT7rvedvMb3D7iHz+ds1m92inAQ7QeIWgsMup1GhI4OXIoc+zoM84eh3M0Wd1c0SnDxcolvlktDkIm2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=yJVooWS7ae6T4DJ/d7fNHTSwQ4/FQ/9iT74RjMBDS4M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=U5plLLjeYKInftp4yDv1CwuaNnDyMi5hI3H1Cu/BY5JG9p35JQSP7PWRyOGn1nh7MUclZqyjPfY0P5/mwHrBxqZTpGTt1onnwyhcacm2CYj4XUzNBrQfnIqCVtHhMN4OMJr9U7BBR55I0P2Lu0Q1T0h5v0OlqaH9VuyXTCo7cZY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tu9qp0fC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tu9qp0fC" Received: by smtp.kernel.org (Postfix) with ESMTPS id EDC99C2BCFC; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=yJVooWS7ae6T4DJ/d7fNHTSwQ4/FQ/9iT74RjMBDS4M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=tu9qp0fCgOU1ZQzkJ3xliAmJ8ZxuKuuuS6VelWzX/+nZBDPqsnXo379Nqk/LNtm2z lgizkdMdLLhwx2UE4FTLVef/8nyikhDjNeX0o8tRHZJvrAuXHplsYZvnMqejPysxub x/LC1Qk3fuEa+KpsWEe0TFmzF1NhxzKQXtvEQRhYd8bZNuCmyug1dUuOngodmAt8Ej hP46pkcPfZ4Rd9M+iZXDfPX8dvfKOo70lFWEiAhZ5a5Dw4Nd7ZqOnvg4kCuFMLYewg hJNV1d+HVEFNJMGjmbodrpgkYGOl5P95/yokA582HonZVXDO7dTOXwNHdWwNy+Cc+F lbCP+BmDiXMCA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5F37C5ACD1; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:41 -0700 Subject: [PATCH v10 02/41] KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-2-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=8465; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=1nOMPFicDBXgDI3srbMuJXuAmX4cJHFBglLbazHe5uM=; b=OiqsSQH799o+a0nXP1B8S8quubZv0zAEmDtuW7nunbn2va3CCzQqcfD1DgjWR9G0Q3GCly7N5 q8LTBzZDLGzBZ3l9gLtanHYelXoY0vI5fRSyIy1lMUKPvigVI0z/Tan X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Start plumbing in guest_memfd support for in-place private<=3D>shared conversions by tracking attributes via a maple tree. KVM currently tracks private vs. shared attributes on a per-VM basis, which made sense when a guest_memfd _only_ supported private memory, but tracking per-VM simply can't work for in-place conversions as the shared/private status of a given page needs to be per-gmem_inode, not per-VM. Use the filemap invalidation lock to protect the maple tree, as taking the lock for read when faulting in memory (for userspace or the guest) isn't expected to result in meaningful contention, and using a separate lock would add significant complexity (avoiding deadlock is quite difficult). Co-developed-by: Vishal Annapurve Signed-off-by: Vishal Annapurve Co-developed-by: Fuad Tabba Signed-off-by: Fuad Tabba Signed-off-by: Sean Christopherson Tested-by: Shivank Garg Reviewed-by: Xiaoyao Li Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu --- virt/kvm/guest_memfd.c | 133 ++++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 116 insertions(+), 17 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index a11cf6dc785da..1f1ae61b4878b 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,13 @@ struct gmem_inode { struct list_head gmem_file_list; =20 u64 flags; + /* + * Every index in this inode, whether memory is populated or + * not, is tracked in attributes. The entire range of indices, + * corresponding to the size of this inode, is represented in + * this maple tree. + */ + struct maple_tree attributes; }; =20 static __always_inline struct gmem_inode *GMEM_I(struct inode *inode) @@ -61,9 +69,25 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot= *slot, gfn_t gfn) return gfn - slot->base_gfn + slot->gmem.pgoff; } =20 +static u64 kvm_gmem_get_attributes(struct inode *inode, void *entry) +{ + if (WARN_ON_ONCE(!entry)) { + bool initially_shared =3D GMEM_I(inode)->flags & + GUEST_MEMFD_FLAG_INIT_SHARED; + + return initially_shared ? 0 : KVM_MEMORY_ATTRIBUTE_PRIVATE; + } + + return xa_to_value(entry); +} + static bool kvm_gmem_is_private_mem(struct inode *inode, pgoff_t index) { - return !(GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED); + struct maple_tree *mt =3D &GMEM_I(inode)->attributes; + void *entry =3D mtree_load(mt, index); + + return kvm_gmem_get_attributes(inode, entry) & + KVM_MEMORY_ATTRIBUTE_PRIVATE; } =20 static bool kvm_gmem_is_shared_mem(struct inode *inode, pgoff_t index) @@ -364,10 +388,13 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct = vm_fault *vmf) if (((loff_t)vmf->pgoff << PAGE_SHIFT) >=3D i_size_read(inode)) return VM_FAULT_SIGBUS; =20 - if (!kvm_gmem_is_shared_mem(inode, vmf->pgoff)) - return VM_FAULT_SIGBUS; + filemap_invalidate_lock_shared(inode->i_mapping); + if (kvm_gmem_is_shared_mem(inode, vmf->pgoff)) + folio =3D kvm_gmem_get_folio(inode, vmf->pgoff); + else + folio =3D ERR_PTR(-EACCES); + filemap_invalidate_unlock_shared(inode->i_mapping); =20 - folio =3D kvm_gmem_get_folio(inode, vmf->pgoff); if (IS_ERR(folio)) { if (PTR_ERR(folio) =3D=3D -EAGAIN) return VM_FAULT_RETRY; @@ -520,6 +547,51 @@ bool __weak kvm_arch_supports_gmem_init_shared(struct = kvm *kvm) return true; } =20 +static int kvm_gmem_init_inode(struct inode *inode, loff_t size, u64 flags) +{ + struct gmem_inode *gi =3D GMEM_I(inode); + MA_STATE(mas, &gi->attributes, 0, (size >> PAGE_SHIFT) - 1); + u64 attrs; + int r; + + inode->i_op =3D &kvm_gmem_iops; + inode->i_mapping->a_ops =3D &kvm_gmem_aops; + inode->i_mode |=3D S_IFREG; + inode->i_size =3D size; + mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); + + /* + * guest_memfd memory is neither migratable nor swappable: set + * inaccessible to gate off both. + */ + mapping_set_inaccessible(inode->i_mapping); + WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); + + gi->flags =3D flags; + + mt_set_external_lock(&gi->attributes, + &inode->i_mapping->invalidate_lock); + + /* + * Store default attributes for the entire gmem instance. Ensuring every + * index is represented in the maple tree at all times simplifies the + * conversion and merging logic. + */ + attrs =3D gi->flags & GUEST_MEMFD_FLAG_INIT_SHARED ? 0 : KVM_MEMORY_ATTRI= BUTE_PRIVATE; + + /* + * Acquire the invalidation lock purely to make lockdep happy. The + * maple tree library expects all stores to be protected via the lock, + * and the library can't know when the tree is reachable only by the + * caller, as is the case here. + */ + filemap_invalidate_lock(inode->i_mapping); + r =3D mas_store_gfp(&mas, xa_mk_value(attrs), GFP_KERNEL); + filemap_invalidate_unlock(inode->i_mapping); + + return r; +} + static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) { static const char *name =3D "[kvm-gmem]"; @@ -550,16 +622,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t s= ize, u64 flags) goto err_fops; } =20 - inode->i_op =3D &kvm_gmem_iops; - inode->i_mapping->a_ops =3D &kvm_gmem_aops; - inode->i_mode |=3D S_IFREG; - inode->i_size =3D size; - mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); - mapping_set_inaccessible(inode->i_mapping); - /* Unmovable mappings are supposed to be marked unevictable as well. */ - WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); - - GMEM_I(inode)->flags =3D flags; + err =3D kvm_gmem_init_inode(inode, size, flags); + if (err) + goto err_inode; =20 file =3D alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR, &kvm_gmem_f= ops); if (IS_ERR(file)) { @@ -764,9 +829,13 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memor= y_slot *slot, if (!file) return -EFAULT; =20 + filemap_invalidate_lock_shared(file_inode(file)->i_mapping); + folio =3D __kvm_gmem_get_pfn(file, slot, index, pfn, max_order); - if (IS_ERR(folio)) - return PTR_ERR(folio); + if (IS_ERR(folio)) { + r =3D PTR_ERR(folio); + goto out; + } =20 if (!folio_test_uptodate(folio)) { clear_highpage(folio_page(folio, 0)); @@ -786,6 +855,8 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory= _slot *slot, else folio_put(folio); =20 +out: + filemap_invalidate_unlock_shared(file_inode(file)->i_mapping); return r; } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_get_pfn); @@ -915,6 +986,15 @@ static struct inode *kvm_gmem_alloc_inode(struct super= _block *sb) =20 mpol_shared_policy_init(&gi->policy, NULL); =20 + /* + * Memory attributes are protected by the filemap invalidation lock, but + * the lock structure isn't available at this time. Immediately mark + * maple tree as using external locking so that accessing the tree + * before it's fully initialized results in NULL pointer dereferences + * and not more subtle bugs. + */ + mt_init_flags(&gi->attributes, MT_FLAGS_LOCK_EXTERN | MT_FLAGS_USE_RCU); + gi->flags =3D 0; INIT_LIST_HEAD(&gi->gmem_file_list); return &gi->vfs_inode; @@ -922,7 +1002,26 @@ static struct inode *kvm_gmem_alloc_inode(struct supe= r_block *sb) =20 static void kvm_gmem_destroy_inode(struct inode *inode) { - mpol_free_shared_policy(&GMEM_I(inode)->policy); + struct gmem_inode *gi =3D GMEM_I(inode); + + mpol_free_shared_policy(&gi->policy); + + /* + * Note! Checking for an empty tree is functionally necessary + * to avoid explosions if the tree hasn't been fully + * initialized, i.e. if the inode is being destroyed before + * guest_memfd can set the external lock, lockdep would find + * that the tree's internal ma_lock was not held. + */ + if (!mtree_empty(&gi->attributes)) { + /* + * Acquire the invalidation lock purely to make lockdep happy, + * the inode is unreachable at this point. + */ + filemap_invalidate_lock(inode->i_mapping); + __mt_destroy(&gi->attributes); + filemap_invalidate_unlock(inode->i_mapping); + } } =20 static void kvm_gmem_free_inode(struct inode *inode) --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7316F45A294; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=ks7NQhk+1A5gLTk998/g5gXAvIpTa4/2nYf2n6G97WaYiUb4ZrHWXLS1iRxuBmpugAS+hDSYlBSUAfZtLOjVcRURHaUkFDvPM3cuJ3mZpg2/Loi0DDGE1l7hH2xxEzet/OIuMYX4i7uklbga9TGFBCQP1c4jPS3/2/zdCfspFuk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=ZnJgY0dnS4WX51GG785q8yjPb3EiWCzAcEUWyLfjAzI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u//UyLay+oyEOCkvIc7+dDfR2IcSSsOXBXwqShr0NxDD4PjrleiVfBXk13zn1Hv2ff13RdXM4eoC4hz9Mx0aiSewN2ENQKRy3F3SZI0GUgL6FxSZ+1dLoiJjNNXGGbT9g3UjJ93uvTUg0DUHVZF8xxaRbPgcTgmAwZKjU/R4czA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Beq+INjx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Beq+INjx" Received: by smtp.kernel.org (Postfix) with ESMTPS id 0BBF7C32781; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=ZnJgY0dnS4WX51GG785q8yjPb3EiWCzAcEUWyLfjAzI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Beq+INjx1HD91lUBJdD6maXBI3ROLpEDuG0xOpMSr1pDLIjJhIC61cvks6/iKio/n dv2DHaDxTqyMTiwQ7qO7e6m36h7C58H5/ekUKpEDb3PzMpTAsW7Z3HAfEblf9uZLf3 V4MWQzQqiNLo4s0OZyPdpUCdKlmMePP9arL1nUeAl3z4sALgh7EIdn+UgUos2ytR59 mvvWL/TbcQzSIuhGwuY3lJtOXTTIZ42D/7CpYQeCy782uxhp0n9ajHWEpPXOeZHKRz E8EbNSqjSQ2U9/XTaAxCyiGQVgXsVZwOsXKGiGkToLQSZNAoA91LJmM7WT1VarNAg2 1LSkOITboQtIg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB22AC5ACD7; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:42 -0700 Subject: [PATCH v10 03/41] KVM: Rename KVM_GENERIC_MEMORY_ATTRIBUTES to KVM_VM_MEMORY_ATTRIBUTES Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-3-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=8858; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=fsrD9vd9T66vvV/NIHC8tFCltlc15QVXhroIFddRfPE=; b=p4XqINXrZ1Q7g6QqTt+8lOtXKLwWDEWBoLtVAEwgLzY0kwwp1QekUm2Q24ueFlRSD3w/5O4fg FyVN2MlrQLAAuEOIb8G5FjNmhDFajNb7KYNcEDGX3Uak84zBIzRO7ft X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Rename the per-VM memory attributes Kconfig to make it explicitly about per-VM attributes in anticipation of adding memory attributes support to guest_memfd, at which point it will be possible (and desirable) to have memory attributes without the per-VM support, even in x86. No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Reviewed-by: Xiaoyao Li Reviewed-by: Binbin Wu Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/Kconfig | 6 +++--- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h | 8 ++++---- include/trace/events/kvm.h | 4 ++-- virt/kvm/Kconfig | 2 +- virt/kvm/kvm_main.c | 14 +++++++------- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 283847619ff88..14d86851fce78 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1851,7 +1851,7 @@ enum kvm_intr_type { ((vcpu) && (vcpu)->arch.handling_intr_from_guest && \ (!!in_nmi() =3D=3D ((vcpu)->arch.handling_intr_from_guest =3D=3D KVM_HAN= DLING_NMI))) =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) #endif =20 diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 538ed1e803326..2f8e1b5a8a72c 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -84,7 +84,7 @@ config KVM_SW_PROTECTED_VM bool "Enable support for KVM software-protected VMs" depends on EXPERT depends on KVM_X86 && X86_64 - select KVM_GENERIC_MEMORY_ATTRIBUTES + select KVM_VM_MEMORY_ATTRIBUTES help Enable support for KVM software-protected VMs. Currently, software- protected VMs are purely a development and testing vehicle for @@ -135,7 +135,7 @@ config KVM_INTEL_TDX bool "Intel Trust Domain Extensions (TDX) support" default y depends on INTEL_TDX_HOST - select KVM_GENERIC_MEMORY_ATTRIBUTES + select KVM_VM_MEMORY_ATTRIBUTES select HAVE_KVM_ARCH_GMEM_POPULATE help Provides support for launching Intel Trust Domain Extensions (TDX) @@ -159,7 +159,7 @@ config KVM_AMD_SEV depends on KVM_AMD && X86_64 depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=3Dy && CRYPTO_DEV_CCP_DD=3Dm) select ARCH_HAS_CC_PLATFORM - select KVM_GENERIC_MEMORY_ATTRIBUTES + select KVM_VM_MEMORY_ATTRIBUTES select HAVE_KVM_ARCH_GMEM_CONVERT select HAVE_KVM_ARCH_GMEM_RECLAIM select HAVE_KVM_ARCH_GMEM_INVALIDATE diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index c519e8e8d646f..acafa7964964c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -8070,7 +8070,7 @@ void kvm_mmu_pre_destroy_vm(struct kvm *kvm) vhost_task_stop(kvm->arch.nx_huge_page_recovery_thread); } =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static bool hugepage_test_mixed(struct kvm_memory_slot *slot, gfn_t gfn, int level) { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d94b59140c452..f1d977060489b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10134,7 +10134,7 @@ static int kvm_alloc_memslot_metadata(struct kvm *k= vm, } } =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES kvm_mmu_init_memslot_memory_attributes(kvm, slot); #endif =20 diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 03bfc92864b6e..3e86cdd00e59b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -722,7 +722,7 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_= vcpu *vcpu) } #endif =20 -#ifndef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifndef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static inline bool kvm_arch_has_private_mem(struct kvm *kvm) { return false; @@ -872,7 +872,7 @@ struct kvm { #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER struct notifier_block pm_notifier; #endif -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES /* Protected by slots_lock (for writes) and RCU (for reads) */ struct xarray mem_attr_array; #endif @@ -2560,7 +2560,7 @@ static inline bool kvm_memslot_is_gmem_only(const str= uct kvm_memory_slot *slot) return slot->flags & KVM_MEMSLOT_GMEM_ONLY; } =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn= _t gfn) { return xa_to_value(xa_load(&kvm->mem_attr_array, gfn)); @@ -2582,7 +2582,7 @@ static inline bool kvm_mem_is_private(struct kvm *kvm= , gfn_t gfn) { return false; } -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 #ifdef CONFIG_KVM_GUEST_MEMFD int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index b282e3a867696..1ba72bd73ea2f 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -358,7 +358,7 @@ TRACE_EVENT(kvm_dirty_ring_exit, TP_printk("vcpu %d", __entry->vcpu_id) ); =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES /* * @start: Starting address of guest memory range * @end: End address of guest memory range @@ -383,7 +383,7 @@ TRACE_EVENT(kvm_vm_set_mem_attributes, TP_printk("%#016llx -- %#016llx [0x%lx]", __entry->start, __entry->end, __entry->attr) ); -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 TRACE_EVENT(kvm_unmap_hva_range, TP_PROTO(unsigned long start, unsigned long end), diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index c3c0ee253fc77..df575449d97b5 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -100,7 +100,7 @@ config KVM_ELIDE_TLB_FLUSH_IF_YOUNG config KVM_MMU_LOCKLESS_AGING bool =20 -config KVM_GENERIC_MEMORY_ATTRIBUTES +config KVM_VM_MEMORY_ATTRIBUTES bool =20 config KVM_GUEST_MEMFD diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f3a6ba740ff79..e3a77d1e6d8ae 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1116,7 +1116,7 @@ static struct kvm *kvm_create_vm(unsigned long type, = const char *fdname) spin_lock_init(&kvm->mn_invalidate_lock); rcuwait_init(&kvm->mn_memslots_update_rcuwait); xa_init(&kvm->vcpu_array); -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES xa_init(&kvm->mem_attr_array); #endif =20 @@ -1301,7 +1301,7 @@ static void kvm_destroy_vm(struct kvm *kvm) cleanup_srcu_struct(&kvm->irq_srcu); srcu_barrier(&kvm->srcu); cleanup_srcu_struct(&kvm->srcu); -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES xa_destroy(&kvm->mem_attr_array); #endif kvm_arch_free_vm(kvm); @@ -2419,7 +2419,7 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *k= vm, } #endif /* CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT */ =20 -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static u64 kvm_supported_mem_attributes(struct kvm *kvm) { if (!kvm || kvm_arch_has_private_mem(kvm)) @@ -2624,7 +2624,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm= *kvm, =20 return kvm_vm_set_mem_attributes(kvm, start, end, attrs->attributes); } -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) { @@ -4941,7 +4941,7 @@ static int kvm_vm_ioctl_check_extension_generic(struc= t kvm *kvm, long arg) case KVM_CAP_SYSTEM_EVENT_DATA: case KVM_CAP_DEVICE_CTRL: return 1; -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES case KVM_CAP_MEMORY_ATTRIBUTES: return kvm_supported_mem_attributes(kvm); #endif @@ -5345,7 +5345,7 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES case KVM_SET_MEMORY_ATTRIBUTES: { struct kvm_memory_attributes attrs; =20 @@ -5356,7 +5356,7 @@ static long kvm_vm_ioctl(struct file *filp, r =3D kvm_vm_ioctl_set_mem_attributes(kvm, &attrs); break; } -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ case KVM_CREATE_DEVICE: { struct kvm_create_device cd; =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 736E645A297; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=JGfovVNvr/q2+xlLNxerNw+hWS4bd90H1dNEWEqNW2LmikQaSB7u5HnCM5fCgyy16kG/PIay/dnpD9CizqywtIifAnM53lj8XNpUThcm3rFDG3HCBgbPOtJTg4H0SsXqkVO6CaWEEhWF2/onaKWdEY65XVzqNmJ6uG3Ra5YJ+GQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=CYny0H8G1T1w5+2Vn0HiiBpDYPh6AX3u7WawyvebPVg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q3hYZWdBs75HvpuAT4guZZGkB5a9iUZg91/GsWvC1AifTSwP2Uvz8pYZyCyd7GYQQRxHvAeKHpCshaAbHbo/P/K49isIegvhp11k/EP4Q5KripyasX3rjjsUUabhnXLrBVTQSvtXljT0vXCU7e/P1bVAq7mfVFwzWkYtuZm4yxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r96v3Ova; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r96v3Ova" Received: by smtp.kernel.org (Postfix) with ESMTPS id 2219FC2BD05; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=CYny0H8G1T1w5+2Vn0HiiBpDYPh6AX3u7WawyvebPVg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=r96v3OvaH5RV5b/doFdmZHVxUc/gBza7+Wmv5pnL2TBpb06WKD/0aDNy/lqOIR/qX DWQhLiBz2yPL/ZXIZPLxq7jIa+aK2S3ofc3h8NZ8GrzTL4apjmluT/UqTnd90PWF2w MZX0uZi0dg7OCVL9WgUoA4oSsahPYO9sdU5kycw6MHvqXOybA4rYWrI0GSAqMyslvo KW8SX38Mm6VqvNOo62sEeuUVlH17XZxd15gqecCjbt6yw2KeVmgElDVYTWmcXJQikq 1E6zZPyVDrcvBpKWcCStpmwnFTYsU00e+oMUln1bgSXlXdEJEAjMLqh5Ic6Pkr3mDQ DpPHWgbysJjJA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2F1BC5ACD4; Fri, 7 Aug 2026 21:52:47 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:43 -0700 Subject: [PATCH v10 04/41] KVM: Enumerate support for PRIVATE memory iff kvm_arch_has_private_mem is defined Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-4-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=2340; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=lFRsujEsk43JmAvWcgvkvnyu0Lj39PjjRyBwxKpEywk=; b=grHE6Tsfr/GTzaFa3DypnMYU/6GjDXIIps37lx53+eCQ/JceF11Nx9OhYJqWN6hiC1v6rBqMQ p9UTgoF5KrMDwHPxXStn+EGP6DjqH7cyGTEklh93j3gHn0yv4HEbEPu X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Explicitly guard reporting support for KVM_MEMORY_ATTRIBUTE_PRIVATE based on kvm_arch_has_private_mem being #defined in anticipation of tracking PRIVATE vs. SHARED state per-guest_memfd, not per-VM (to allow in-place conversion). guest_memfd support for memory attributes is expected to be unconditional to avoid yet more macros (all architectures that support guest_memfd are expected to use per-gmem attributes at some point), at which point enumerating support KVM_MEMORY_ATTRIBUTE_PRIVATE based solely on memory attributes being supported by KVM at-large would result in a system-scope check (NULL @kvm) over-reporting support on arm64. Give architectures full control over overriding the default definition of kvm_arch_has_private_mem() by removing the coupling with CONFIG_KVM_VM_MEMORY_ATTRIBUTES. In a later patch, kvm_arch_has_private_mem() will be defined based on whether architectural features are compiled in, and made orthogonal to CONFIG_KVM_VM_MEMORY_ATTRIBUTES. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Reviewed-by: Binbin Wu Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: Xiaoyao Li --- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3e86cdd00e59b..e3666d0b40b74 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -722,7 +722,7 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_= vcpu *vcpu) } #endif =20 -#ifndef CONFIG_KVM_VM_MEMORY_ATTRIBUTES +#ifndef kvm_arch_has_private_mem static inline bool kvm_arch_has_private_mem(struct kvm *kvm) { return false; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e3a77d1e6d8ae..560ff05e95959 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2422,8 +2422,10 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *= kvm, #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static u64 kvm_supported_mem_attributes(struct kvm *kvm) { +#ifdef kvm_arch_has_private_mem if (!kvm || kvm_arch_has_private_mem(kvm)) return KVM_MEMORY_ATTRIBUTE_PRIVATE; +#endif =20 return 0; } --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8028245C6E1; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=tiV+XTAJX4GpEs0AVT3tqE6WubOeA79UIpdsbK92GdwT1rzP87TChDufuYn6Pqgre2D/0vizNOQ79lLAhNCbnUGQScJ2IdFRA25RAMfdbIpCBKosffQCcPTQ95OFZd/ZDBqj2COfE1Liv17pEhZKAJB7Ka8bCC50VnD8Tko+794= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=PbfisaKwe7jLYuLRO2Nu12hjMeFEkZ+viTDMytBOidU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nuv5a/k0xbBciIAeFAhf0GWfX3tsc+kohwstfdPBeevoavL4J7I9aJTWJ5Lzvbf0A/NgJ4gAGzWQPi2dYo5YuqelabFFEqK1NnuIQr/rEQgu8Hksp7AvmA3mC5gNWoAwJ5JE8CJZBVZZGncHB2Z0w7T2KKfea6RIJ0FEofpnfKQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q71zSnh2; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q71zSnh2" Received: by smtp.kernel.org (Postfix) with ESMTPS id 2FA67C32786; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=PbfisaKwe7jLYuLRO2Nu12hjMeFEkZ+viTDMytBOidU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Q71zSnh2bSiq5Nf/2KHKnPI623imkzhodTNGPSPk9HXky6qQ4GU9/zcoXyYXJb3kh OLKLZ+wfKFBCTfQ773ayAMj0QqB+QCMgJjivvjw+3jjupHEhR7GMxWiszvyHNFnRAb zlCfMGvzRdUtyYK6LeXsh5kxsQ3hrBqEYqMyaaVePLuPEaX/2+vn2xZCpDv17W4UyN xmdnl19ktMDI4jM01KubraTFbhZWqOAeSzFKlckWG8rRFne/WGpc/SwJ+DVymjjBti 5V4FflEr9XPA+XwFNc8/MoKGgTZVlQSkLPYMa9RR6KHHO0kOIwL0BorEUtVwgqdOQM fvfFVVpjkZfaA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16AECC5ACD8; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:44 -0700 Subject: [PATCH v10 05/41] KVM: Rename memory attribute APIs to prepare for in-place gmem conversion Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-5-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=9969; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=C83vX1lAmz8SBa+/53A0ujJhVXz9H4O3UCQrFd3/VNI=; b=twt2ZPW27wC5JlvijhCC0Gmq1xhHh8LZOQJFxsOqpajmw7ZLFYulAnqL8YXgsdsOyfNmZ5rXU huDewhAxu32C92edhQ6dV5Eig7SE3a8YayF9dcfBT3wngfVS4IsKo8N X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Rename memory attribute APIs to add a "vm_" in the name in anticipation of moving PRIVATE tracking into guest_memfd, to allow in-place conversion between SHARED and PRIVATE. At that point, there will effectively be two (potential) sources of memory attributes: the VM and guest_memfd. kvm_vm_set_mem_attributes() already has "vm" in the name to indicate that it is a VM ioctl. Rename it to kvm_set_vm_mem_attributes() to show that it is setting the VM's memory attributes. (Drop the VM-ioctl scoping since it is a helper local to the file.) Update the accompanying trace function to match. No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Reviewed-by: Xiaoyao Li Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu --- arch/x86/kvm/mmu/mmu.c | 14 +++++++------- include/linux/kvm_host.h | 16 ++++++++-------- include/trace/events/kvm.h | 2 +- virt/kvm/kvm_main.c | 32 ++++++++++++++++---------------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index acafa7964964c..2b3bc73845a8a 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -8089,8 +8089,8 @@ static void hugepage_set_mixed(struct kvm_memory_slot= *slot, gfn_t gfn, lpage_info_slot(gfn, slot, level)->disallow_lpage |=3D KVM_LPAGE_MIXED_FL= AG; } =20 -bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range) +bool kvm_arch_pre_set_vm_memory_attributes(struct kvm *kvm, + struct kvm_gfn_range *range) { struct kvm_memory_slot *slot =3D range->slot; int level; @@ -8159,18 +8159,18 @@ static bool hugepage_has_attrs(struct kvm *kvm, str= uct kvm_memory_slot *slot, const unsigned long end =3D start + KVM_PAGES_PER_HPAGE(level); =20 if (level =3D=3D PG_LEVEL_2M) - return kvm_range_has_memory_attributes(kvm, start, end, ~0, attrs); + return kvm_range_has_vm_memory_attributes(kvm, start, end, ~0, attrs); =20 for (gfn =3D start; gfn < end; gfn +=3D KVM_PAGES_PER_HPAGE(level - 1)) { if (hugepage_test_mixed(slot, gfn, level - 1) || - attrs !=3D kvm_get_memory_attributes(kvm, gfn)) + attrs !=3D kvm_get_vm_memory_attributes(kvm, gfn)) return false; } return true; } =20 -bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range) +bool kvm_arch_post_set_vm_memory_attributes(struct kvm *kvm, + struct kvm_gfn_range *range) { unsigned long attrs =3D range->arg.attributes; struct kvm_memory_slot *slot =3D range->slot; @@ -8263,7 +8263,7 @@ void kvm_mmu_init_memslot_memory_attributes(struct kv= m *kvm, * be manually checked as the attributes may already be mixed. */ for (gfn =3D start; gfn < end; gfn +=3D nr_pages) { - unsigned long attrs =3D kvm_get_memory_attributes(kvm, gfn); + unsigned long attrs =3D kvm_get_vm_memory_attributes(kvm, gfn); =20 if (hugepage_has_attrs(kvm, slot, gfn, level, attrs)) hugepage_clear_mixed(slot, gfn, level); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index e3666d0b40b74..3464a0ddbae74 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2561,21 +2561,21 @@ static inline bool kvm_memslot_is_gmem_only(const s= truct kvm_memory_slot *slot) } =20 #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES -static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn= _t gfn) +static inline unsigned long kvm_get_vm_memory_attributes(struct kvm *kvm, = gfn_t gfn) { return xa_to_value(xa_load(&kvm->mem_attr_array, gfn)); } =20 -bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, - unsigned long mask, unsigned long attrs); -bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range); -bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range); +bool kvm_range_has_vm_memory_attributes(struct kvm *kvm, gfn_t start, gfn_= t end, + unsigned long mask, unsigned long attrs); +bool kvm_arch_pre_set_vm_memory_attributes(struct kvm *kvm, + struct kvm_gfn_range *range); +bool kvm_arch_post_set_vm_memory_attributes(struct kvm *kvm, + struct kvm_gfn_range *range); =20 static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) { - return kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; + return kvm_get_vm_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIV= ATE; } #else static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 1ba72bd73ea2f..c4d514d2350cf 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -364,7 +364,7 @@ TRACE_EVENT(kvm_dirty_ring_exit, * @end: End address of guest memory range * @attr: The value of the attribute being set. */ -TRACE_EVENT(kvm_vm_set_mem_attributes, +TRACE_EVENT(kvm_set_vm_mem_attributes, TP_PROTO(gfn_t start, gfn_t end, unsigned long attr), TP_ARGS(start, end, attr), =20 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 560ff05e95959..b3f9396123be2 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2420,7 +2420,7 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *k= vm, #endif /* CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT */ =20 #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES -static u64 kvm_supported_mem_attributes(struct kvm *kvm) +static u64 kvm_supported_vm_mem_attributes(struct kvm *kvm) { #ifdef kvm_arch_has_private_mem if (!kvm || kvm_arch_has_private_mem(kvm)) @@ -2434,19 +2434,19 @@ static u64 kvm_supported_mem_attributes(struct kvm = *kvm) * Returns true if _all_ gfns in the range [@start, @end) have attributes * such that the bits in @mask match @attrs. */ -bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, - unsigned long mask, unsigned long attrs) +bool kvm_range_has_vm_memory_attributes(struct kvm *kvm, gfn_t start, gfn_= t end, + unsigned long mask, unsigned long attrs) { XA_STATE(xas, &kvm->mem_attr_array, start); unsigned long index; void *entry; =20 - mask &=3D kvm_supported_mem_attributes(kvm); + mask &=3D kvm_supported_vm_mem_attributes(kvm); if (attrs & ~mask) return false; =20 if (end =3D=3D start + 1) - return (kvm_get_memory_attributes(kvm, start) & mask) =3D=3D attrs; + return (kvm_get_vm_memory_attributes(kvm, start) & mask) =3D=3D attrs; =20 guard(rcu)(); if (!attrs) @@ -2517,8 +2517,8 @@ static __always_inline void kvm_handle_gfn_range(stru= ct kvm *kvm, KVM_MMU_UNLOCK(kvm); } =20 -static bool kvm_pre_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range) +static bool kvm_pre_set_vm_memory_attributes(struct kvm *kvm, + struct kvm_gfn_range *range) { /* * Unconditionally add the range to the invalidation set, regardless of @@ -2533,18 +2533,18 @@ static bool kvm_pre_set_memory_attributes(struct kv= m *kvm, */ kvm_mmu_invalidate_range_add(kvm, range->start, range->end); =20 - return kvm_arch_pre_set_memory_attributes(kvm, range); + return kvm_arch_pre_set_vm_memory_attributes(kvm, range); } =20 /* Set @attributes for the gfn range [@start, @end). */ -static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, +static int kvm_set_vm_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, unsigned long attributes) { struct kvm_mmu_notifier_range pre_set_range =3D { .start =3D start, .end =3D end, .arg.attributes =3D attributes, - .handler =3D kvm_pre_set_memory_attributes, + .handler =3D kvm_pre_set_vm_memory_attributes, .on_lock =3D kvm_mmu_invalidate_start, .flush_on_ret =3D true, .may_block =3D true, @@ -2553,7 +2553,7 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm,= gfn_t start, gfn_t end, .start =3D start, .end =3D end, .arg.attributes =3D attributes, - .handler =3D kvm_arch_post_set_memory_attributes, + .handler =3D kvm_arch_post_set_vm_memory_attributes, .on_lock =3D kvm_mmu_invalidate_end, .may_block =3D true, }; @@ -2563,12 +2563,12 @@ static int kvm_vm_set_mem_attributes(struct kvm *kv= m, gfn_t start, gfn_t end, =20 entry =3D attributes ? xa_mk_value(attributes) : NULL; =20 - trace_kvm_vm_set_mem_attributes(start, end, attributes); + trace_kvm_set_vm_mem_attributes(start, end, attributes); =20 mutex_lock(&kvm->slots_lock); =20 /* Nothing to do if the entire range has the desired attributes. */ - if (kvm_range_has_memory_attributes(kvm, start, end, ~0, attributes)) + if (kvm_range_has_vm_memory_attributes(kvm, start, end, ~0, attributes)) goto out_unlock; =20 /* @@ -2607,7 +2607,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm= *kvm, /* flags is currently not used. */ if (attrs->flags) return -EINVAL; - if (attrs->attributes & ~kvm_supported_mem_attributes(kvm)) + if (attrs->attributes & ~kvm_supported_vm_mem_attributes(kvm)) return -EINVAL; if (attrs->size =3D=3D 0 || attrs->address + attrs->size < attrs->address) return -EINVAL; @@ -2624,7 +2624,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm= *kvm, */ BUILD_BUG_ON(sizeof(attrs->attributes) !=3D sizeof(unsigned long)); =20 - return kvm_vm_set_mem_attributes(kvm, start, end, attrs->attributes); + return kvm_set_vm_mem_attributes(kvm, start, end, attrs->attributes); } #endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 @@ -4945,7 +4945,7 @@ static int kvm_vm_ioctl_check_extension_generic(struc= t kvm *kvm, long arg) return 1; #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES case KVM_CAP_MEMORY_ATTRIBUTES: - return kvm_supported_mem_attributes(kvm); + return kvm_supported_vm_mem_attributes(kvm); #endif #ifdef CONFIG_KVM_GUEST_MEMFD case KVM_CAP_GUEST_MEMFD: --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 95A9A45C6FA; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=cpJbedgrM7f254GgSEUxWPqH+mPus6HIxpgYTn5kgpP4z6e3p35NwEyS+n8+IIS6vGGhr+SFWYudzkdCIfHvMCY8n7HHD0th2gmk87uGIaHA3QxJFbfKMWHfKaSV81PldkMnaN1oJFTM6pS97QetTnZBw8muumHL43YZGfm4eMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=uI91Yewbkf+Mkw4PYrkVUsL5tNVKDc9QB0xaPQu5GMU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SkzIPaVhiT6YSXTErU9FTPgJUxCXnqmEwV5pczT4CRKhIx5fXsEmR9Z/by7hx+YIBbvEB1cPZSOyUnSrc30fnB7Sv/tuMsQyXZSubGnoMdbwMzgdZamKr4PaM/26inUNJRTTiOIARbjJcS15UZOM4yN6jCnPeBPjEZZTbmaoxP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D193Nm1K; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D193Nm1K" Received: by smtp.kernel.org (Postfix) with ESMTPS id 45DF0C4AF11; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=uI91Yewbkf+Mkw4PYrkVUsL5tNVKDc9QB0xaPQu5GMU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=D193Nm1K77USjqqEfj9Z4y0RWpxu6gOFevMfkKCa6iJpcIZ5hY/Hi0ikY1CBS9asF /8jK83cFG+CSwHunIHDHvGDgDCLbXRpDjfJQUK+8+rRZOpODp6UZGhUZVZzH8w0gcZ xAbM5SNtGxT1HMw2ZlT5kkqQSrPQo5r/SEI85Qb8Op8xH2JMPH5hamkfo9lGCihjA3 F/D1o7fwqmiXY1I0unnV90JKzXEiRhkReDEno4i1kkuc9p4JUMHXWlslFYcc7ZmuE7 42hT6MNC+e8fiBeTXuSIz6bBxXczn/KS2zzdZvPRZHnRZymU2o9xVEnWCnfAK0ebsR wA8BT8x/rdjUw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D8E1C5ACAB; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:45 -0700 Subject: [PATCH v10 06/41] KVM: Provide generic interface for checking memory private/shared status Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-6-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139564; l=3207; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=tXmTU53UAzCKCqiruNWMK+ptv3ayxg/pSi3V0XXYtxc=; b=z5CpksCk8raj6CBDraRTpqXZPGIP90pBjTwW4L9SU1f/B5Z+N8ACkkCgv6UAKJAsNfqQUg4j3 cGPMWEfZeFABf/uMelDu+hsoaBtRe32LfvkbrAecRj8ak7vwbMR3p5X X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Introduce a generic kvm_mem_is_private() interface using a static call to determine if a GFN is private. This allows the implementation for checking a GFN's private/shared status to be set at runtime. In preparation for choosing implementations between a guest_memfd lookup and the existing VM attribute lookup, rename the existing VM-attribute-based check to kvm_vm_mem_is_private to emphasize that it looks up VM attributes. Signed-off-by: Sean Christopherson Reviewed-by: Xiaoyao Li Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu --- include/linux/kvm_host.h | 14 ++++++++++++-- virt/kvm/kvm_main.c | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3464a0ddbae74..65fbce46b63f4 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2573,16 +2573,26 @@ bool kvm_arch_pre_set_vm_memory_attributes(struct k= vm *kvm, bool kvm_arch_post_set_vm_memory_attributes(struct kvm *kvm, struct kvm_gfn_range *range); =20 -static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) +static inline bool kvm_vm_mem_is_private(struct kvm *kvm, gfn_t gfn) { return kvm_get_vm_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIV= ATE; } +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ + +#ifdef kvm_arch_has_private_mem +typedef bool (kvm_mem_is_private_t)(struct kvm *kvm, gfn_t gfn); +DECLARE_STATIC_CALL(__kvm_mem_is_private, kvm_mem_is_private_t); + +static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) +{ + return static_call(__kvm_mem_is_private)(kvm, gfn); +} #else static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) { return false; } -#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ +#endif /* kvm_arch_has_private_mem */ =20 #ifdef CONFIG_KVM_GUEST_MEMFD int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b3f9396123be2..a01d336eab18b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2628,6 +2628,20 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kv= m *kvm, } #endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 +#ifdef kvm_arch_has_private_mem +DEFINE_STATIC_CALL_RET0(__kvm_mem_is_private, kvm_mem_is_private_t); +EXPORT_STATIC_CALL_GPL(__kvm_mem_is_private); + +static void kvm_init_memory_attributes(void) +{ +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES + static_call_update(__kvm_mem_is_private, kvm_vm_mem_is_private); +#endif +} +#else +static void kvm_init_memory_attributes(void) { } +#endif + struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) { return __gfn_to_memslot(kvm_memslots(kvm), gfn); @@ -6547,6 +6561,7 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align,= struct module *module) kvm_preempt_ops.sched_in =3D kvm_sched_in; kvm_preempt_ops.sched_out =3D kvm_sched_out; =20 + kvm_init_memory_attributes(); kvm_init_debug(); =20 r =3D kvm_vfio_ops_init(); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9EFFD45D19F; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=X4moIK8xPddoABzn4dcDbThBVEYXm7WI9+cxmtRqtu/KtH8u4qp8V3/SYc+nMK5aQbLrggibdxzfLs+vm5/dUoHB/tkUeJG65bJ3KjwnR5lkW8kckAezhNaeYXX/EC3udguHn3dqplvOQOSW9VELkzTmqBh64zr1bwTG5yf33X8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=R28ZEIBAzL55bIZ0Jfb2Dv5F59rVFGvixvPDAxwkpYE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TEBOyyoqbmTmkvyvOaSTNC6aRL6VtKYjqfdkRh4mhcccC34eL/qOcVXxoupZv5xXlGFFdxSZBOpAoGDBZZIXbLcClduxeRZN1KDyMlLDTVeQX2faSQFY6AoTT2DBhDH/ziQXoRkgG60wrHtrh9HFYnLzT9Oa7Ju/NLYV9k3oLhQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gJxf7rF4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gJxf7rF4" Received: by smtp.kernel.org (Postfix) with ESMTPS id 58D33C19425; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=R28ZEIBAzL55bIZ0Jfb2Dv5F59rVFGvixvPDAxwkpYE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=gJxf7rF4QQgoi2wUBUXO07as85mWqVIidSadVmC0eHXDaMcgDktxcVMi8Qfe7KrlO 5kr2s12ePf4GDC2Y2sssMuWmWyRkX9x8Eq8vBFLQPt0YRRGz6XlsLWgfcKNgQ1t5/4 RkYZ865In/RYwQFA4uHXM8fdzGNIgef6JCY1HNks6w080B7YxiaTNi3etByORrEXd2 Sm6Z+fSkUHNPVFoG4uyGQqAcS4GfSJv1ulEvLsai2Nmrf4LFdX2a58gL2RFvC9qHTp 2GChyeIOtEd0MbnmJmbQBvwwRrEvZhpaxlgF5V37l2bZVOkJgbPCcY3yiIChnz/nhe KtXUU8oVbpriA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44301C5ACD1; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:46 -0700 Subject: [PATCH v10 07/41] KVM: guest_memfd: Stub in ability to enable in-place shared<=>private conversion Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-7-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=4469; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=WLHFPoezUAm21n5cIFWjuAvOHkt2CQoZ0rZKzRZuazc=; b=ZDOH0/Oj5SJ3cr7plA8V5KsJ2F57SIEEItjUXWHMqaX8nEorDWE/Syxgz2w0EEtbnfoa9n15i Z4Jw6LnCohfCvMN0mc4oVdHsVk2dT8aCyEXPTbtZygtHYC2VjIp2QOD X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Stub in global variable to enable in-place guest_memfd private<=3D>shared memory conversion, which will eventually be exposed to userspace via a module param, and wire up the __kvm_mem_is_private() static call to the guest_memfd version when in-place conversion is enabled, i.e. when gmem is the sole authority on private vs. shared memory. Cc: Fuad Tabba Cc: Xiaoyao Li Signed-off-by: Sean Christopherson Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng Reviewed-by: Fuad Tabba Reviewed-by: Xiaoyao Li --- include/linux/kvm_host.h | 6 ++++++ virt/kvm/guest_memfd.c | 26 ++++++++++++++++++++++++++ virt/kvm/kvm_main.c | 12 +++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 65fbce46b63f4..9477ecebbbced 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2580,6 +2580,8 @@ static inline bool kvm_vm_mem_is_private(struct kvm *= kvm, gfn_t gfn) #endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ =20 #ifdef kvm_arch_has_private_mem +extern bool gmem_in_place_conversion; + typedef bool (kvm_mem_is_private_t)(struct kvm *kvm, gfn_t gfn); DECLARE_STATIC_CALL(__kvm_mem_is_private, kvm_mem_is_private_t); =20 @@ -2588,6 +2590,8 @@ static inline bool kvm_mem_is_private(struct kvm *kvm= , gfn_t gfn) return static_call(__kvm_mem_is_private)(kvm, gfn); } #else +#define gmem_in_place_conversion false + static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) { return false; @@ -2595,6 +2599,8 @@ static inline bool kvm_mem_is_private(struct kvm *kvm= , gfn_t gfn) #endif /* kvm_arch_has_private_mem */ =20 #ifdef CONFIG_KVM_GUEST_MEMFD +bool kvm_gmem_is_private(struct kvm *kvm, gfn_t gfn); + int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn, kvm_pfn_t *pfn, struct page **page, int *max_order); diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 1f1ae61b4878b..75979c885e030 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -475,6 +475,32 @@ static int kvm_gmem_mmap(struct file *file, struct vm_= area_struct *vma) return 0; } =20 +bool kvm_gmem_is_private(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *slot =3D gfn_to_memslot(kvm, gfn); + struct inode *inode; + + if (!slot) + return 0; + + CLASS(gmem_get_file, file)(slot); + if (!file) + return 0; + + inode =3D file_inode(file); + + /* + * Rely on the maple tree's internal RCU lock to ensure a stable result. + * This result can become stale as soon as the lock is dropped, so the + * caller _must_ protect consumption of private vs. shared either by + * holding guest_memfd's invalidate lock for the entire duration, or by + * checking mmu_invalidate_retry_gfn() under mmu_lock to serialize + * against concurrent attribute updates. + */ + return kvm_gmem_is_private_mem(inode, kvm_gmem_get_index(slot, gfn)); +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_is_private); + static struct file_operations kvm_gmem_fops =3D { .mmap =3D kvm_gmem_mmap, .open =3D generic_file_open, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a01d336eab18b..0a5a1bee8de0f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -102,6 +102,10 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(halt_poll_ns_shrink); static bool __ro_after_init allow_unsafe_mappings; module_param(allow_unsafe_mappings, bool, 0444); =20 +#ifdef kvm_arch_has_private_mem +bool __ro_after_init gmem_in_place_conversion =3D false; +#endif + /* * Ordering of locks: * @@ -2423,6 +2427,9 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *k= vm, static u64 kvm_supported_vm_mem_attributes(struct kvm *kvm) { #ifdef kvm_arch_has_private_mem + if (gmem_in_place_conversion) + return 0; + if (!kvm || kvm_arch_has_private_mem(kvm)) return KVM_MEMORY_ATTRIBUTE_PRIVATE; #endif @@ -2634,8 +2641,11 @@ EXPORT_STATIC_CALL_GPL(__kvm_mem_is_private); =20 static void kvm_init_memory_attributes(void) { + if (gmem_in_place_conversion) + static_call_update(__kvm_mem_is_private, kvm_gmem_is_private); #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES - static_call_update(__kvm_mem_is_private, kvm_vm_mem_is_private); + else + static_call_update(__kvm_mem_is_private, kvm_vm_mem_is_private); #endif } #else --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D316C463B92; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; cv=none; b=lmlQbfSrxqrAPcnIO3bslGKi1N/IG89VTCf2AI7ldcQ32u5OzuC77rP3BWgrNKWBCMabkyYYxHK36YBTC3C/Q0WbTva0IsWTNgLbR5Rla6P1fFRUzSuigNawlVruolrekEmvXKSZopPSqM3dIVqrUlbqBcx99G3LjAsRKZWzY+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139568; c=relaxed/simple; bh=Q2oTqLrG2Xi7qOaSJzOIcKifMjGFtSLrE8L5+xB+HSk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HgUjyaYNpUNwQNNLRtAcnDxgr0RYhzMuZlfZX8tMnnZlC+kB8cMXzuaYcIusRv9y5tqc1ORYy8vuZk7eAbW6U9qt3G0CrUEEVUXGXIQyB3xAPjwCEXnaRiWSNbVcTErvrTJ22jY7+zUT5V17XdUgab/UbCPMl+XJlq3ZblFzrR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jXaXsEBQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jXaXsEBQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 78F66C4AF65; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=Q2oTqLrG2Xi7qOaSJzOIcKifMjGFtSLrE8L5+xB+HSk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=jXaXsEBQzt5c6iRg8IbW4KJnhs+5r+44Tb6CuR4D4t1hOC69vcxS4ARag9OiWzUg3 Hq1MCcaqydv8q5yplqwOhSa/V0QAt0kFNn/1paxeIVHZQvWmFrAGyli0kCRFh8GYKD chPJFHVxbLwqGOwhCv3woCqW7OhYlsIA6DJtfuDEXStBqaznp3d7fRqfmB5pNmKgnT tB8b+2ldXAtXEf6Ys7apTR9WW0z2zOHhWMPIydlMI9wMAbX3BQ2AfVi3tsxejd97w5 vSocERu31Gw31ZhqMZYzmMZvq89WeRhRrVQFGfxUT8pPLRSEXJLES0U12aabuUNWKJ OATo9UsAH/7ug== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A39EC5ACD3; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:47 -0700 Subject: [PATCH v10 08/41] KVM: Consolidate private memory and guest_memfd ifdeffery in kvm_host.h Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-8-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2484; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=EV0WfoRp32ZTbW1sABDnt+s70i5+mhToqmVJyPng6P8=; b=evXG47pZgMj9SONAGK9U8n3Y7iXSwtapV2A8gESBHNoFe8YGA8Ic3MslrdR+Qamtbl/TxWRkU PNjX+iUA4KbDtEXk/s6+aQLD0zdWkRncid+9TmGEcBbUWPcbkAF3EXs X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Move the kvm_arch_has_private_mem() stub and a few guest_memfd function definitions/declarations "down" in kvm_host.h to utilize existing #ifdefs, and so that related code is clustered together. No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Xiaoyao Li Reviewed-by: Binbin Wu Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: David Hildenbrand (Arm) --- include/linux/kvm_host.h | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9477ecebbbced..dfdb3c97a7ac9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -722,27 +722,6 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm= _vcpu *vcpu) } #endif =20 -#ifndef kvm_arch_has_private_mem -static inline bool kvm_arch_has_private_mem(struct kvm *kvm) -{ - return false; -} -#endif - -#ifdef CONFIG_KVM_GUEST_MEMFD -bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm); - -static inline u64 kvm_gmem_get_supported_flags(struct kvm *kvm) -{ - u64 flags =3D GUEST_MEMFD_FLAG_MMAP; - - if (!kvm || kvm_arch_supports_gmem_init_shared(kvm)) - flags |=3D GUEST_MEMFD_FLAG_INIT_SHARED; - - return flags; -} -#endif - #ifndef kvm_arch_has_readonly_mem static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) { @@ -2592,6 +2571,11 @@ static inline bool kvm_mem_is_private(struct kvm *kv= m, gfn_t gfn) #else #define gmem_in_place_conversion false =20 +static inline bool kvm_arch_has_private_mem(struct kvm *kvm) +{ + return false; +} + static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) { return false; @@ -2600,6 +2584,17 @@ static inline bool kvm_mem_is_private(struct kvm *kv= m, gfn_t gfn) =20 #ifdef CONFIG_KVM_GUEST_MEMFD bool kvm_gmem_is_private(struct kvm *kvm, gfn_t gfn); +bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm); + +static inline u64 kvm_gmem_get_supported_flags(struct kvm *kvm) +{ + u64 flags =3D GUEST_MEMFD_FLAG_MMAP; + + if (!kvm || kvm_arch_supports_gmem_init_shared(kvm)) + flags |=3D GUEST_MEMFD_FLAG_INIT_SHARED; + + return flags; +} =20 int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn, kvm_pfn_t *pfn, struct page **page, --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E2047463B9C; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=E9R65foi4grz69uf+zLUu0YR1pIbk4e2fkwkTjafFABhlqp8HR+5GmnfLofvmOCyZHu67HEF8fEXs4v+dJ17kmii2NkcV5zfmKDeQJZ13Yar+w/EES331m/CpiGzAVJ7rZ1lG8jfDDdAeaqpj4mvWkOZ0XuxgnikeGZ7CaHFDuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=tfnbkDTsUgjV8ae+YfwtWqaHSKcI51uEln6Qb0OILDw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WwSIkeg0djvsLXFVq/Y9FUg62a70N82JmfUZhfrIPYDlAOS/cSuQq3nP1pGbLSIHQ0I/Gs70PGZtenMfKVn9Va4NXzMpk1XMWqQ5nVs3Tv+CUYsMM6h9kTrF7HzgBKxZfUiZ8xl+R25eoVKb9ki7L4gL300k5/OPELzpjvhEy7E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F8cgv8Mf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F8cgv8Mf" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8AA58C4DDE9; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=tfnbkDTsUgjV8ae+YfwtWqaHSKcI51uEln6Qb0OILDw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=F8cgv8MfzHRb/JwcnakLD17L0Bytvp0ggNKxjTZQmclTMZ/Svj2GqTenpYGeK3t5R TQ3bm8Axy2jSvcTIrSZnWbPjPBUnwtaGplt5OIQOc7OCBhq4SHEtGQEijnbBpAlNtf jBL0H2oyqAnN8GTloZXjc2c6c8DqJVwyqX3C+WwjpgGPMh2Dj43B3aTU2+9x5lU/tr qUPDhBSAS8EEMf8axkHOeWMEmyHXqNeb02eVELtqBo0fWpEV5qKx2OVKc3qjx7HjG3 Qqjf0rVsbq2ZiaOL+Qjn+jl/z0MqNYVLHekpDUgCLA0nIsHznprQ4vK7lP3bwfEFHz SuB3/1D6Hdd+A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73084C5ACD4; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:48 -0700 Subject: [PATCH v10 09/41] KVM: guest_memfd: Filter both shared and private when invalidating Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-9-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3422; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=1q8QLNSSzWUow4EJaKvrMqTfyteiIQK8uRHjtZo2+nk=; b=AQVmGM6AJ8KOerslpx3mVIgNVX/P+qago77Vsl429UlDPUt2QmWTsb/BsE4mhbCnGbxHgvHmy xOBW2RU7osOAlKfdi0+QBB0uwtE4wwZgeEuhdnNDBTlT835oA0tJgPL X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Before conversion, a guest_memfd could be either all shared, or all private, configured at creation time using the INIT_SHARED flag. Hence, when zapping pages from stage 2 page tables, guest_memfd can filter which to zap based on the initial shared/private state. With conversion, guest_memfd tracks shared/private state on a per-page level, so a range can contain both private and shared pages. Zap both private and shared pages for simplicity. An alternative would be to iterate guest_memfd attributes and only zap both if shared and private pages exist within the range. Setting both the shared and private filters lets the zapping logic do that iteration instead. Reviewed-by: Suzuki K Poulose Signed-off-by: Ackerley Tng Reviewed-by: Fuad Tabba --- virt/kvm/guest_memfd.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 75979c885e030..b1537226e5adf 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -136,14 +136,6 @@ static struct folio *kvm_gmem_get_folio(struct inode *= inode, pgoff_t index) return folio; } =20 -static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct ino= de *inode) -{ - if (GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED) - return KVM_FILTER_SHARED; - - return KVM_FILTER_PRIVATE; -} - static void __kvm_gmem_invalidate_start(struct gmem_file *f, pgoff_t start, pgoff_t end, enum kvm_gfn_range_filter attr_filter) @@ -186,15 +178,13 @@ static void __kvm_gmem_invalidate_start(struct gmem_f= ile *f, pgoff_t start, } =20 static void kvm_gmem_invalidate_start(struct inode *inode, pgoff_t start, - pgoff_t end) + pgoff_t end, + enum kvm_gfn_range_filter filter) { - enum kvm_gfn_range_filter attr_filter; struct gmem_file *f; =20 - attr_filter =3D kvm_gmem_get_invalidate_filter(inode); - kvm_gmem_for_each_file(f, inode) - __kvm_gmem_invalidate_start(f, start, end, attr_filter); + __kvm_gmem_invalidate_start(f, start, end, filter); } =20 static void __kvm_gmem_invalidate_end(struct gmem_file *f, pgoff_t start, @@ -229,7 +219,8 @@ static long kvm_gmem_punch_hole(struct inode *inode, lo= ff_t offset, loff_t len) */ filemap_invalidate_lock(inode->i_mapping); =20 - kvm_gmem_invalidate_start(inode, start, end); + kvm_gmem_invalidate_start(inode, start, end, + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); =20 truncate_inode_pages_range(inode->i_mapping, offset, offset + len - 1); =20 @@ -344,7 +335,7 @@ static int kvm_gmem_release(struct inode *inode, struct= file *file) * memory, as its lifetime is associated with the inode, not the file. */ __kvm_gmem_invalidate_start(f, 0, -1ul, - kvm_gmem_get_invalidate_filter(inode)); + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); __kvm_gmem_invalidate_end(f, 0, -1ul); =20 list_del(&f->entry); @@ -525,7 +516,8 @@ static int kvm_gmem_error_folio(struct address_space *m= apping, struct folio *fol start =3D folio->index; end =3D start + folio_nr_pages(folio); =20 - kvm_gmem_invalidate_start(mapping->host, start, end); + kvm_gmem_invalidate_start(mapping->host, start, end, + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); =20 /* * Do not truncate the range, what action is taken in response to the --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E2184463B9D; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=PjRlCBnOYhD//Knsed7bvTvN3DQwmOfZei0mw33dZg42FynRQqBOJBwpZyPTmv3Q5hUcp8KPcyzvNAZVd40uMYQ9Zy/U0lAH9wM4fKY3n7IlkifhXj+iM8xszFSz406gX5jbrc+b5WO2LwXC6rRsUK5mU3JQDdiqA587c76YgbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=jzGs6Dre0kjE1/gGJb1Q4TCVGuOJVo75IUH/LEp7RY8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RXWZb3FC80r80G9zhpjcynvWPcYjFTEQAMI7PGiqaVTQB4bcbLJRewSi2aKBOUpXs3wt0tLaL2dKxb74oN/puDcFfKKUHkG1jHiFbgSeE0yiK3aNpKYpZ5Izwl6TzTTEvSqVTFQUY3n1phP7ng4Y8Mdc85ltBXfs+kDgpX2wUGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DEhB1hHQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DEhB1hHQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id A65E9C4AF18; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=jzGs6Dre0kjE1/gGJb1Q4TCVGuOJVo75IUH/LEp7RY8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=DEhB1hHQgGgXMJBbJaj+EKP5Lc91x+1ViYSfzhYZvIH58KwR6IoPBqbZxEQcoXxIs btmLDuz7Og+DPlJP4Kqv6eS+RDteu7C/g9DaH9S4MNbtmpwnpwccwCUZuvg8MIRFLd CgomlhbjwGa7pNeuGnOQhNHkQekQXmiqmGBEwbTcZBIW9s1Pss4B4/oH2IYo2dNFfO w2Yv09jUafSZRko0OvxR5gkp/ipG34O86uqS9/qf30wg88lY2RiPPzqYg4XZtVVfio i0g8qNvfSp3yFm/EsC/xvuk+FwSUDSPbn+i9g5vOkmKdfI1Hd8nb0x7KiGQ7QsAamw rHt/nJ7lnLv8A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88F9EC5ACD7; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:49 -0700 Subject: [PATCH v10 10/41] KVM: guest_memfd: Add base support for KVM_SET_MEMORY_ATTRIBUTES2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-10-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=12652; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=Q0yQ+Ord5cK/y9TgTQWUapDCQ6db4odwiyYjviFgtpc=; b=VF33lw8ZJsgtzeNB2vq52/94+TbzhHJZAkZNRBSV/+seKIfCMJnAZu5GANgWzmGfQKCJv6Emq 6rsddCiLpcvCaVn6ULNx4pOdcyjb+Fx5QaIe1JSMsNjCGQgQKNSykJ6 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a new ioctl (and matching struct), KVM_SET_MEMORY_ATTRIBUTES2, using the same base ioctl number (0xd2), but with R/W semantics for the kernel instead of just read semantics. "Officially" documenting that KVM writes to the payload will allow KVM to support partial/incremental conversions, instead of all-or-nothing updates (which requires complex unwinding), by recording the failing offset if an error occurs. Opportunistically add a new struct as well, even though KVM could squeeze the error offset into "struct kvm_memory_attributes", as there's no cost to doing so in practice. Pad the struct with a pile of extra space to try and avoid ending up with "struct kvm_memory_attributes3" in the future. Use the same layout for the fields that common to version 1 of the struct, e.g. to ease upgrading userspace, and to provide flexibility if KVM ever adds support for KVM_SET_MEMORY_ATTRIBUTES2 at VM scope. Introduce KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES to advertise the availability of the KVM_SET_MEMORY_ATTRIBUTES2 ioctl. Update the KVM API documentation to define the new ioctl and its behavior, and add the necessary UAPI definitions and capability checks. The process of setting memory attributes has a clear point of no return because, for CoCo VMs, zapping stage 2 page tables is a destructive operation. Unlike regular VMs, where re-faulting pages into the stage 2 page tables merely incurs a performance penalty, CoCo guests must (re-):accept pages after every fault. To preserve CoCo security guarantees, guests will not accept pages they did not explicitly request faults for. Consequently, during memory conversions, any operation that could cause the process to abort must be completed before the stage 2 page tables are zapped. Zap only the ranges that are not already in the requested state to avoid inadvertently destroying (CoCo) data. ARM CCA guests will try to mark the entire DRAM as private at boot. If there are no shared pages at all, the to-private conversion can be skipped, but the existence of a single shared page would require the conversion process to proceed, and if it proceeds, zapping both shared and private pages would destroy data and break the guest. Co-developed-by: Vishal Annapurve Signed-off-by: Vishal Annapurve Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Reviewed-by: Binbin Wu Suggested-by: Michael Roth Tested-by: Shivank Garg Suggested-by: Suzuki K Poulose Reviewed-by: Suzuki K Poulose Signed-off-by: Ackerley Tng --- Documentation/virt/kvm/api.rst | 63 +++++++++++++++++++++- include/uapi/linux/kvm.h | 15 ++++++ virt/kvm/guest_memfd.c | 119 +++++++++++++++++++++++++++++++++++++= ++++ virt/kvm/kvm_main.c | 23 +++++--- 4 files changed, 212 insertions(+), 8 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 62afc031897ce..1a3f664dbb197 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -117,7 +117,7 @@ description: x86 includes both i386 and x86_64. =20 Type: - system, vm, or vcpu. + system, vm, vcpu or guest_memfd. =20 Parameters: what parameters are accepted by the ioctl. @@ -6382,6 +6382,8 @@ S390: Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set. Returns -EINVAL if called on a protected VM. =20 +.. _KVM_SET_MEMORY_ATTRIBUTES: + 4.141 KVM_SET_MEMORY_ATTRIBUTES ------------------------------- =20 @@ -6575,6 +6577,65 @@ KVM_S390_KEYOP_SSKE Sets the storage key for the guest address ``guest_addr`` to the key specified in ``key``, returning the previous value in ``key``. =20 +4.145 KVM_SET_MEMORY_ATTRIBUTES2 +--------------------------------- + +:Capability: KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES +:Architectures: all +:Type: guest_memfd ioctl +:Parameters: struct kvm_memory_attributes2 (in) +:Returns: 0 on success, <0 on error + +Errors: + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + EINVAL The specified `offset` or `size` was invalid (e.g. not + page aligned, causes an overflow, or size is zero). + EFAULT The parameter address was invalid. + ENOMEM Ran out of memory trying to track private/shared state + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +KVM_SET_MEMORY_ATTRIBUTES2 is an extension to +KVM_SET_MEMORY_ATTRIBUTES that supports returning (writing) values to +userspace. The original (pre-extension) fields are shared with +KVM_SET_MEMORY_ATTRIBUTES identically. + +Attribute values are shared with KVM_SET_MEMORY_ATTRIBUTES. + +:: + + struct kvm_memory_attributes2 { + union { + __u64 address; + __u64 offset; + }; + __u64 size; + __u64 attributes; + __u64 flags; + __u64 reserved[12]; + }; + + #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) + +Set attributes for a range of offsets within a guest_memfd to +KVM_MEMORY_ATTRIBUTE_PRIVATE to limit the specified guest_memfd backed +memory range for guest use. Even if KVM_CAP_GUEST_MEMFD_MMAP is +supported, after a successful call to set +KVM_MEMORY_ATTRIBUTE_PRIVATE, the requested range will not be mappable +into host userspace and will only be mappable by the guest. + +To allow the range to be mappable into host userspace again, call +KVM_SET_MEMORY_ATTRIBUTES2 on the guest_memfd again with +KVM_MEMORY_ATTRIBUTE_PRIVATE unset. + +KVM does not directly manipulate the memory contents of pages during +attribute updates. However, the process of setting these attributes, +which includes operations such as unmapping pages from the host or +stage-2 page tables, may result in side effects on memory contents +that vary across different trusted firmware implementations. + +See also: :ref: `KVM_SET_MEMORY_ATTRIBUTES`. + .. _kvm_run: =20 5. The kvm_run structure diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 419011097fa8e..80985e28e3b21 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -997,6 +997,7 @@ struct kvm_enable_cap { #define KVM_CAP_S390_KEYOP 247 #define KVM_CAP_S390_VSIE_ESAMODE 248 #define KVM_CAP_S390_HPAGE_2G 249 +#define KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES 250 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -1649,6 +1650,20 @@ struct kvm_memory_attributes { __u64 flags; }; =20 +/* Available with KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES */ +#define KVM_SET_MEMORY_ATTRIBUTES2 _IOWR(KVMIO, 0xd2, struct= kvm_memory_attributes2) + +struct kvm_memory_attributes2 { + union { + __u64 address; + __u64 offset; + }; + __u64 size; + __u64 attributes; + __u64 flags; + __u64 reserved[12]; +}; + #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) =20 #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest= _memfd) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index b1537226e5adf..3783e63476569 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -492,11 +492,130 @@ bool kvm_gmem_is_private(struct kvm *kvm, gfn_t gfn) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_is_private); =20 +/* + * Preallocate memory for attributes to be stored on a maple tree, pointed= to + * by mas. Adjacent ranges with attributes identical to the new attributes + * will be merged. Also sets mas's bounds up for storing attributes. + * + * This maintains the invariant that ranges with the same attributes will + * always be merged. + */ +static int kvm_gmem_mas_preallocate(struct ma_state *mas, u64 attributes, + pgoff_t start, size_t nr_pages) +{ + pgoff_t end =3D start + nr_pages; + pgoff_t last =3D end - 1; + void *entry; + + /* Try extending range. entry is NULL on overflow/wrap-around. */ + mas_set(mas, end); + entry =3D mas_find(mas, end); + if (entry && xa_to_value(entry) =3D=3D attributes) + last =3D mas->last; + + if (start > 0) { + mas_set(mas, start - 1); + entry =3D mas_find(mas, start - 1); + if (entry && xa_to_value(entry) =3D=3D attributes) + start =3D mas->index; + } + + mas_set_range(mas, start, last); + return mas_preallocate(mas, xa_mk_value(attributes), GFP_KERNEL); +} + +static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start, + size_t nr_pages, uint64_t attrs) +{ + bool to_private =3D attrs & KVM_MEMORY_ATTRIBUTE_PRIVATE; + struct address_space *mapping =3D inode->i_mapping; + struct gmem_inode *gi =3D GMEM_I(inode); + enum kvm_gfn_range_filter filter; + pgoff_t end =3D start + nr_pages; + struct maple_tree *mt; + struct ma_state mas; + int r; + + mt =3D &gi->attributes; + + filemap_invalidate_lock(mapping); + + mas_init(&mas, mt, start); + r =3D kvm_gmem_mas_preallocate(&mas, attrs, start, nr_pages); + if (r) + goto out; + + /* + * From this point on guest_memfd has performed necessary + * checks and can proceed to do guest-breaking changes. + */ + + filter =3D to_private ? KVM_FILTER_SHARED : KVM_FILTER_PRIVATE; + kvm_gmem_invalidate_start(inode, start, end, filter); + mas_store_prealloc(&mas, xa_mk_value(attrs)); + kvm_gmem_invalidate_end(inode, start, end); +out: + filemap_invalidate_unlock(mapping); + return r; +} + +static long kvm_gmem_set_attributes(struct file *file, void __user *argp) +{ + struct gmem_file *f =3D file->private_data; + struct inode *inode =3D file_inode(file); + struct kvm_memory_attributes2 attrs; + size_t nr_pages; + pgoff_t index; + int i; + + if (copy_from_user(&attrs, argp, sizeof(attrs))) + return -EFAULT; + + if (attrs.flags) + return -EINVAL; + for (i =3D 0; i < ARRAY_SIZE(attrs.reserved); i++) { + if (attrs.reserved[i]) + return -EINVAL; + } + if (!kvm_arch_has_private_mem(f->kvm)) + return -EINVAL; + if (attrs.attributes & ~KVM_MEMORY_ATTRIBUTE_PRIVATE) + return -EINVAL; + if (attrs.size =3D=3D 0 || attrs.offset + attrs.size < attrs.offset) + return -EINVAL; + if (!PAGE_ALIGNED(attrs.offset) || !PAGE_ALIGNED(attrs.size)) + return -EINVAL; + + if (attrs.offset >=3D i_size_read(inode) || + attrs.offset + attrs.size > i_size_read(inode)) + return -EINVAL; + + nr_pages =3D attrs.size >> PAGE_SHIFT; + index =3D attrs.offset >> PAGE_SHIFT; + return __kvm_gmem_set_attributes(inode, index, nr_pages, + attrs.attributes); +} + +static long kvm_gmem_ioctl(struct file *file, unsigned int ioctl, + unsigned long arg) +{ + switch (ioctl) { + case KVM_SET_MEMORY_ATTRIBUTES2: + if (!gmem_in_place_conversion) + return -ENOTTY; + + return kvm_gmem_set_attributes(file, (void __user *)arg); + default: + return -ENOTTY; + } +} + static struct file_operations kvm_gmem_fops =3D { .mmap =3D kvm_gmem_mmap, .open =3D generic_file_open, .release =3D kvm_gmem_release, .fallocate =3D kvm_gmem_fallocate, + .unlocked_ioctl =3D kvm_gmem_ioctl, }; =20 static int kvm_gmem_migrate_folio(struct address_space *mapping, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 0a5a1bee8de0f..c4c09593ef8b9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2423,18 +2423,22 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm = *kvm, } #endif /* CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT */ =20 +#ifdef kvm_arch_has_private_mem +static u64 kvm_supports_private_mem(struct kvm *kvm) +{ + return !kvm || kvm_arch_has_private_mem(kvm); +} +#else +#define kvm_supports_private_mem(kvm) false +#endif + #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES static u64 kvm_supported_vm_mem_attributes(struct kvm *kvm) { -#ifdef kvm_arch_has_private_mem - if (gmem_in_place_conversion) + if (gmem_in_place_conversion || !kvm_supports_private_mem(kvm)) return 0; =20 - if (!kvm || kvm_arch_has_private_mem(kvm)) - return KVM_MEMORY_ATTRIBUTE_PRIVATE; -#endif - - return 0; + return KVM_MEMORY_ATTRIBUTE_PRIVATE; } =20 /* @@ -4976,6 +4980,11 @@ static int kvm_vm_ioctl_check_extension_generic(stru= ct kvm *kvm, long arg) return 1; case KVM_CAP_GUEST_MEMFD_FLAGS: return kvm_gmem_get_supported_flags(kvm); + case KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES: + if (!gmem_in_place_conversion || !kvm_supports_private_mem(kvm)) + return 0; + + return KVM_MEMORY_ATTRIBUTE_PRIVATE; #endif default: break; --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 05C01466B03; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=NxZTDzPQLJeZBmSeM65X/FrvxXXZFO5m/vZ3k0gTt44YWmabJ/MKyqTISI1UoCD8zrJB/HPf7IzCqSgGG0OvpqPUMgHXkMB8iYFxmMbU2SYSPV+cMJnXdJF+ef5IBSOXaTciiHVbzqTJ/aOcg+rYi40hxv5vFQUqlIFgG/DlJhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=FyyHqquoBUWbUbzAMIdDVNoyKDJs/lRLdjMK8fj8r7w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EYd63qGGgswljBNA+uq+zFj8m7mRK2FVXmUmSaVZTAW0EDub3Gto7QsepPj0gcL+LY/ov57PlFUVYnf9zMA0G2azD/x+W7MPf5ak9xxZZ/GN25s1zwci8byeyB39CAjphghso71wXDmPk0zHihr9holRQ7U9Wp7gvio8m+ph55U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HqpCL/He; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HqpCL/He" Received: by smtp.kernel.org (Postfix) with ESMTPS id BD214C32781; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=FyyHqquoBUWbUbzAMIdDVNoyKDJs/lRLdjMK8fj8r7w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=HqpCL/HerE/aatYQsc1HxAOrFNefqitw3BKBkpwzfGODBbaoPmuLx4+07IAyXkCzJ M4mwfLjP2Txx5nIQlh0WacrTJ273mP65TrGWVKyQLo2qyjjiJYS/58R+teYnzjT1Su 1yW1KkeK0wM0R1+E0KYEvcf1u7hGs28wsVikQSokmT/Kg2D9xrNTjARloIeF7ggLIk RKYIKNQLAlYnT6hVfpdwcOa+8VWNFUxolg9aKLpj1sSs2ErZwyTh+b1fpJ2uiFFEhr SrLDe7VrZdmDYWsIg9l2GOP075BujEQHdPtvxcHp0/aDuWjtPGZVeQQlRBJ6EptJl1 jj1CnLu3IUgyw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9DC52C5ACDC; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:50 -0700 Subject: [PATCH v10 11/41] KVM: guest_memfd: Ensure pages are not in use before conversion Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-11-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=7232; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=LSONRx5cSknfD6LHxPz2U0/HXl5OqdyA76E4Ke5pn3g=; b=1uXwWm8T1P/DxIAqovl0eKJx3Y27+cP3JbSq7z1OKEBtMf6VoyKrfcLcLXNF0HF71N2nCEcok 3ctvCEsAYlZBLlVrzbw3sGEX5zp6Fmvtnb+QCpQgGOfjp5Q7f0tt7pT X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng When converting memory to private in guest_memfd, it is necessary to ensure that the pages are not currently being accessed by any other part of the kernel or userspace to avoid any current user writing to guest private memory. guest_memfd checks for unexpected refcounts to determine whether a page is still in use. The only expected refcounts after unmapping the range requested for conversion are those that are held by guest_memfd itself. Update the kvm_memory_attributes2 structure to include an error_offset field. This allows KVM to report the exact offset where a conversion failed to userspace. If the safety check fails, return -EAGAIN and copy the error_offset back to userspace so that it can potentially retry the operation or handle the failure gracefully. Update documentation to document the error_offset field and the possible -EAGAIN error. Suggested-by: David Hildenbrand Co-developed-by: Vishal Annapurve Signed-off-by: Vishal Annapurve Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- Documentation/virt/kvm/api.rst | 19 ++++++++++-- include/uapi/linux/kvm.h | 3 +- virt/kvm/guest_memfd.c | 66 ++++++++++++++++++++++++++++++++++++++= ---- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 1a3f664dbb197..1e64026d7c1e9 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6583,7 +6583,7 @@ KVM_S390_KEYOP_SSKE :Capability: KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES :Architectures: all :Type: guest_memfd ioctl -:Parameters: struct kvm_memory_attributes2 (in) +:Parameters: struct kvm_memory_attributes2 (in/out) :Returns: 0 on success, <0 on error =20 Errors: @@ -6592,6 +6592,8 @@ Errors: EINVAL The specified `offset` or `size` was invalid (e.g. not page aligned, causes an overflow, or size is zero). EFAULT The parameter address was invalid. + EAGAIN Some page within requested range had unexpected refcounts. The + offset of the page will be returned in `error_offset`. ENOMEM Ran out of memory trying to track private/shared state =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -6605,6 +6607,7 @@ Attribute values are shared with KVM_SET_MEMORY_ATTRI= BUTES. :: =20 struct kvm_memory_attributes2 { + /* in */ union { __u64 address; __u64 offset; @@ -6612,7 +6615,9 @@ Attribute values are shared with KVM_SET_MEMORY_ATTRI= BUTES. __u64 size; __u64 attributes; __u64 flags; - __u64 reserved[12]; + /* out */ + __u64 error_offset; + __u64 reserved[11]; }; =20 #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) @@ -6634,6 +6639,16 @@ which includes operations such as unmapping pages fr= om the host or stage-2 page tables, may result in side effects on memory contents that vary across different trusted firmware implementations. =20 +If this ioctl returns -EAGAIN, the offset of the page with unexpected +refcounts will be returned in `error_offset`. This can occur if there +are transient refcounts on the pages, taken by other parts of the +kernel. + +Userspace is expected to figure out how to remove all known refcounts +on the shared pages, such as refcounts taken by get_user_pages(), and +try the ioctl again. A possible source of these long term refcounts is +if the guest_memfd memory was pinned in IOMMU page tables. + See also: :ref: `KVM_SET_MEMORY_ATTRIBUTES`. =20 .. _kvm_run: diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 80985e28e3b21..129d6f6303251 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1661,7 +1661,8 @@ struct kvm_memory_attributes2 { __u64 size; __u64 attributes; __u64 flags; - __u64 reserved[12]; + __u64 error_offset; + __u64 reserved[11]; }; =20 #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 3783e63476569..13c3989136f67 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -524,8 +524,42 @@ static int kvm_gmem_mas_preallocate(struct ma_state *m= as, u64 attributes, return mas_preallocate(mas, xa_mk_value(attributes), GFP_KERNEL); } =20 +static bool kvm_gmem_is_safe_for_conversion(struct inode *inode, pgoff_t s= tart, + size_t nr_pages, pgoff_t *err_index) +{ + struct address_space *mapping =3D inode->i_mapping; + const int filemap_get_folios_refcount =3D 1; + pgoff_t last =3D start + nr_pages - 1; + struct folio_batch fbatch; + bool safe =3D true; + pgoff_t next; + int i; + + folio_batch_init(&fbatch); + + next =3D start; + while (safe && filemap_get_folios(mapping, &next, last, &fbatch)) { + for (i =3D 0; i < folio_batch_count(&fbatch); ++i) { + struct folio *folio =3D fbatch.folios[i]; + + if (folio_ref_count(folio) !=3D + folio_nr_pages(folio) + filemap_get_folios_refcount) { + safe =3D false; + *err_index =3D max(start, folio->index); + break; + } + } + + folio_batch_release(&fbatch); + cond_resched(); + } + + return safe; +} + static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start, - size_t nr_pages, uint64_t attrs) + size_t nr_pages, uint64_t attrs, + pgoff_t *err_index) { bool to_private =3D attrs & KVM_MEMORY_ATTRIBUTE_PRIVATE; struct address_space *mapping =3D inode->i_mapping; @@ -542,8 +576,21 @@ static int __kvm_gmem_set_attributes(struct inode *ino= de, pgoff_t start, =20 mas_init(&mas, mt, start); r =3D kvm_gmem_mas_preallocate(&mas, attrs, start, nr_pages); - if (r) + if (r) { + *err_index =3D start; goto out; + } + + if (to_private) { + unmap_mapping_pages(mapping, start, nr_pages, false); + + if (!kvm_gmem_is_safe_for_conversion(inode, start, nr_pages, + err_index)) { + mas_destroy(&mas); + r =3D -EAGAIN; + goto out; + } + } =20 /* * From this point on guest_memfd has performed necessary @@ -564,9 +611,10 @@ static long kvm_gmem_set_attributes(struct file *file,= void __user *argp) struct gmem_file *f =3D file->private_data; struct inode *inode =3D file_inode(file); struct kvm_memory_attributes2 attrs; + pgoff_t err_index; size_t nr_pages; pgoff_t index; - int i; + int i, r; =20 if (copy_from_user(&attrs, argp, sizeof(attrs))) return -EFAULT; @@ -592,8 +640,16 @@ static long kvm_gmem_set_attributes(struct file *file,= void __user *argp) =20 nr_pages =3D attrs.size >> PAGE_SHIFT; index =3D attrs.offset >> PAGE_SHIFT; - return __kvm_gmem_set_attributes(inode, index, nr_pages, - attrs.attributes); + r =3D __kvm_gmem_set_attributes(inode, index, nr_pages, attrs.attributes, + &err_index); + if (r) { + attrs.error_offset =3D ((uint64_t)err_index) << PAGE_SHIFT; + + if (copy_to_user(argp, &attrs, sizeof(attrs))) + return -EFAULT; + } + + return r; } =20 static long kvm_gmem_ioctl(struct file *file, unsigned int ioctl, --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 1D5C646982F; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=GGBvF7z+AVEadD7l02eIJcexsqZpmqqouv6zf82Z3sQFuepfYQQjdTbWuM594jmiYMhQMv6LY+CEw5pS7G39PdtTYYalV2Xn9VbKKq8b8mDccmhE5iZ7Lx/vFx25ksyTj7sYCGPI4q5SeqbLIoL/Y8CxgmLwUgK6uMm6E7yDhK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=Pzuw2+81iEHMVCvjZGWhoamaW8gUEktYXEZIbXEYWm8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s+MivHu8TpcKqzGGDePEQgLwz2z+hD28HySG9wXrlE3J1uOF8/WAROzBZ8ppxoHrP3SUAmb9lrxH/IttvBsYsxIfOskeO6Od/M8N9zsua2ILAZIHkpj/5+Na98iXJC16T+6oCoI8kiVczNazR86yFXkrIFzDNYAuuQ42y5wIkWA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MXjpFj8U; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MXjpFj8U" Received: by smtp.kernel.org (Postfix) with ESMTPS id CCC2DC4DDF0; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139568; bh=Pzuw2+81iEHMVCvjZGWhoamaW8gUEktYXEZIbXEYWm8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=MXjpFj8UxkR60BzbXuxOBUAvRDAAEd5gZZWzIZ/F9UX8XBm4Ka68HBk+DFoP9OGUM CrF0sGwGkk1z2w4zqpxG3FFXc9BviSpiexj43Q0vGg2C0kkjQ/iAajj8JBxlntVTvy /6zf7A3ylHAvyId7JeGICCy+X8lo2J/Wdo9+b+dwtggYAE2nNEjDyLBNuTosN7d1nc AeaRVZkFoiSLv6BYJQubSyHPjHyOaCVFBhs8FL2hfZklglCpPyTcpvZjyG6GJpx8M6 DwZCPsaeOfjNOqyNUrxzbiwrlOAf1wa4Qn6oNWmCBRJYbamkpa6vT220yh8FqeD7tr w7XZJDRglrTYg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6FB9C5ACD3; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:51 -0700 Subject: [PATCH v10 12/41] KVM: guest_memfd: Call arch make_shared callback for to-shared conversion Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-12-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Fuad Tabba X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=6041; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=1Ng/R74A05uOweRslhpPPJqNeRCRV6qc3VuI31edYL4=; b=w6qJsbvqKpJ1jhvhTXzGaTALgmTVrH8jPUJRQ4YOCMRGuHiWXfbnsjNn0MBtJLU507DXaYk0I tsf43LlCj/2AIdPYDntlj+M1qVADWcBl2bm5DKn9EYaUaTvSna1wvQ6 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng When memory in guest_memfd is converted from private to shared, the platform-specific state associated with the guest-private pages must be invalidated or cleaned up. Iterate over the folios in the affected range and call the kvm_arch_gmem_make_shared() hook for each PFN range. This allows architectures to update hardware metadata or encryption states to transition pages to the shared state. Invoke this helper after indicating to KVM's mmu code that an invalidation is in progress to stop in-flight page faults from succeeding. Omit support for calling the arch hook to make private, since SNP, the only implementer of the arch make-private hook today, would actually prefer making private only just before faulting memory into the NPTs. Calling the make-private arch hook would require iterating both bindings and the filemap to find the intersection of bindings and allocated folios. On top of that, SNP would need to figure out whether to actually make private based on whether the memory is about the be faulted, or whether it is a conversion. This does leak SNP-specific details into guest_memfd (as in, why only make-shared during conversions but not make-private?), but the additional complexity is not worth taking on until guest_memfd has a user actually requiring an arch make-private call. Reviewed-by: Fuad Tabba Signed-off-by: Ackerley Tng Reported-by: Binbin Wu Suggested-by: Ackerley Tng --- arch/x86/include/asm/kvm-x86-ops.h | 2 +- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/x86.c | 5 +++++ include/linux/kvm_host.h | 1 + virt/kvm/guest_memfd.c | 42 ++++++++++++++++++++++++++++++++++= ++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index e213c9ae3e301..67b43c167045b 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -150,7 +150,7 @@ KVM_X86_OP_OPTIONAL(alloc_apic_backing_page) #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT KVM_X86_OP_OPTIONAL_RET0(gmem_make_private) #endif -#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_RECLAIM +#if defined(CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT) || defined(CONFIG_HAVE_KVM_= ARCH_GMEM_RECLAIM) KVM_X86_OP_OPTIONAL(gmem_make_shared) #endif #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 14d86851fce78..497da6aaf2942 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1732,7 +1732,7 @@ struct kvm_x86_ops { int (*gmem_make_private)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, kvm_pfn_t nr_pages); #endif -#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_RECLAIM +#if defined(CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT) || defined(CONFIG_HAVE_KVM_= ARCH_GMEM_RECLAIM) void (*gmem_make_shared)(kvm_pfn_t pfn, kvm_pfn_t nr_pages); #endif #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f1d977060489b..39968610868fd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10647,6 +10647,11 @@ int kvm_arch_gmem_make_private(struct kvm *kvm, gf= n_t gfn, kvm_pfn_t pfn, { return kvm_x86_call(gmem_make_private)(kvm, gfn, pfn, nr_pages); } + +void kvm_arch_gmem_make_shared(kvm_pfn_t pfn, kvm_pfn_t nr_pages) +{ + kvm_x86_call(gmem_make_shared)(pfn, nr_pages); +} #endif =20 #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_RECLAIM diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index dfdb3c97a7ac9..a341c434a2b7e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2613,6 +2613,7 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm, #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT int kvm_arch_gmem_make_private(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, kvm_pfn_t nr_pages); +void kvm_arch_gmem_make_shared(kvm_pfn_t pfn, kvm_pfn_t nr_pages); #endif =20 #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_POPULATE diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 13c3989136f67..c9874bd85c5d8 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -557,6 +557,43 @@ static bool kvm_gmem_is_safe_for_conversion(struct ino= de *inode, pgoff_t start, return safe; } =20 +#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT +static void kvm_gmem_make_shared(struct inode *inode, pgoff_t start, pgoff= _t end) +{ + struct folio_batch fbatch; + pgoff_t next =3D start; + int i; + + folio_batch_init(&fbatch); + while (filemap_get_folios(inode->i_mapping, &next, end - 1, &fbatch)) { + for (i =3D 0; i < folio_batch_count(&fbatch); ++i) { + struct folio *folio =3D fbatch.folios[i]; + pgoff_t start_index, end_index; + kvm_pfn_t start_pfn; + kvm_pfn_t nr_pages; + + start_index =3D max(start, folio->index); + end_index =3D min(end, folio_next_index(folio)); + /* + * end_index is either in folio or points to + * the first page of the next folio. Hence, + * all pages in range [start_index, end_index) + * are contiguous. + */ + start_pfn =3D folio_file_pfn(folio, start_index); + nr_pages =3D end_index - start_index; + + kvm_arch_gmem_make_shared(start_pfn, nr_pages); + } + + folio_batch_release(&fbatch); + cond_resched(); + } +} +#else +static void kvm_gmem_make_shared(struct inode *inode, pgoff_t start, pgoff= _t end) {} +#endif + static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start, size_t nr_pages, uint64_t attrs, pgoff_t *err_index) @@ -599,7 +636,12 @@ static int __kvm_gmem_set_attributes(struct inode *ino= de, pgoff_t start, =20 filter =3D to_private ? KVM_FILTER_SHARED : KVM_FILTER_PRIVATE; kvm_gmem_invalidate_start(inode, start, end, filter); + + if (!to_private) + kvm_gmem_make_shared(inode, start, end); + mas_store_prealloc(&mas, xa_mk_value(attrs)); + kvm_gmem_invalidate_end(inode, start, end); out: filemap_invalidate_unlock(mapping); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3007446A5EE; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=d960wqFYfAJRb8t7Gs5CLafnMHrzEueHoVxmtN9fzyRynBi5zWtnpXoa0cbLtv5+u3Izp2GZ6HSnIQ0wKMNA3hucvIYr+Wax3hYt5xRYoK5PNp8upiP/IO3AlQ11rB9fN34I+m/uO7IBBeaxuqtnIoiIi4dZTdQALjO1UrVgnMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=vVlB90TkMEPlFOEarnxtlCTdvt+8JBrxx/lS7exZXfg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eVBpZidkUcRtNUcS8h8bQWWS0hGZKzcxNwRNcphAdZJ66n5hjHObN1sZWXN83Rbo09kO4ow3bqd43chkhDOJQsp7AppISEV+TbJpJpIWk6dppSGEPvjrGUrqrsVcvkzx8qZQkw1/O0S1HDyyFxN+uU9XS3ZsNYBIJTLc8LjZofc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gUAugGbu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gUAugGbu" Received: by smtp.kernel.org (Postfix) with ESMTPS id EFD36C4AF0F; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=vVlB90TkMEPlFOEarnxtlCTdvt+8JBrxx/lS7exZXfg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=gUAugGbuPkp8W/LWiGAXRpzlNXQ33WRr6bDE5WalAitW0UDZ+6ib39LpnxspJWvme CuxS92eb7WjwNcJY0NPjuCsATUGRpbfoZxMaAZLH2r+5MUvbDcB06bhbR+Jurz/QNU +A7DGERCMSbbZ8L3ctwR9fZn6cPhxfEAHh1r98CW0F8xwkQKxcLsyItw6aGOv1nKHo 4BvKooLoNBNNze8CcIH4cryj1CDLlSw0jgy4c0re/6twB88C7j74lW6RzGsBPUnlUw UYQdDuK2vX9QoV2pOnmcRyHZmyJpcr8Bwmr1gyFbbXfTA+ngy/oRMYu2lh/81EbduT oV/mwyr2fIGng== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDB54C5ACD8; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:52 -0700 Subject: [PATCH v10 13/41] KVM: guest_memfd: Return early if range already has requested attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-13-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=1860; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=klJ2px6Wqls0hGacJ6oWy+P1esd5PU6yM+WgWOJIUsI=; b=0vcu/MCQmdtGPWXOU8t4S5wJStaSMSvivJsV/Xl5Og7DLO+sy8ItmzZsKMw2S/tvGBDd0R6fn kv9xs7ln6iLBrXgNjDz8oyAG22n3GxyCUR0wMu/iTJCQy9zQht3v4sP X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Provide function to check that a range has given attributes. Optimize setting memory attributes by returning early if all pages in the requested range already has the requested attributes. Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu Reviewed-by: Xiaoyao Li --- virt/kvm/guest_memfd.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index c9874bd85c5d8..896699afcad9d 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -95,6 +95,24 @@ static bool kvm_gmem_is_shared_mem(struct inode *inode, = pgoff_t index) return !kvm_gmem_is_private_mem(inode, index); } =20 +static bool kvm_gmem_range_has_attributes(struct inode *inode, + pgoff_t index, size_t nr_pages, + u64 attributes) +{ + struct maple_tree *mt =3D &GMEM_I(inode)->attributes; + pgoff_t end =3D index + nr_pages - 1; + void *entry; + + lockdep_assert(mt_lock_is_held(mt)); + + mt_for_each(mt, entry, index, end) { + if (kvm_gmem_get_attributes(inode, entry) !=3D attributes) + return false; + } + + return true; +} + /* * Returns a locked folio on success. The caller is responsible for * setting the up-to-date flag before the memory is mapped into the guest. @@ -605,12 +623,15 @@ static int __kvm_gmem_set_attributes(struct inode *in= ode, pgoff_t start, pgoff_t end =3D start + nr_pages; struct maple_tree *mt; struct ma_state mas; - int r; + int r =3D 0; =20 mt =3D &gi->attributes; =20 filemap_invalidate_lock(mapping); =20 + if (kvm_gmem_range_has_attributes(inode, start, nr_pages, attrs)) + goto out; + mas_init(&mas, mt, start); r =3D kvm_gmem_mas_preallocate(&mas, attrs, start, nr_pages); if (r) { --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5E8A046D2B8; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=OWo36W64P/WGi/Hqu5jMM9YSKreqrzrv26IoI5Gwa3xariHg4s0ea3j36gASj7zQhOPNaHvw0+E8rWYOmwtSSqToygjd2HEh2iZx/OCjlYYtIuPLod3pinKEXdTc6UjcUmXI1wqRKop6B3wMQuL6pW6KA/Vf8wBxddTAFBd6yAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=C8OI6kju/OzMAnmo1MLoFl/+g7Mz5T91QIShVMCU3HM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=e6yTwSRlPLrAK4gFF3P9yr9Ccg2w9wwKlC2I/+a3m2kuCJV8gcKCeBWuT2NUKYF4A6dWcl1Owr27Xbkl3tMoAwH3KX3OF3941aV5s0R7erJS7bD+lQHC8LV6N52FvC6x4Ffn/LiJdTrcjFdMrkj3hLBqXwdJ5kz2o/blG/Zo46s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eGeSFBf7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eGeSFBf7" Received: by smtp.kernel.org (Postfix) with ESMTPS id 087B8C4AF50; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=C8OI6kju/OzMAnmo1MLoFl/+g7Mz5T91QIShVMCU3HM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=eGeSFBf7/4+J80IRIsOi3FHf6wjaVM8/+K955E0oLP9NWFiU1sGNewFog625zOgOY AOB7xqCmqQLkedW+shhfVpoqAzmKTGDrANHgX1UyZMqJgiFBNP6lrk9WukFa3T812/ lg/8XNxR148+odbnj29usyJTNpVN4/+hQ7xFNSDr7qUb0/KfvmPGmHVxMBbc4J2veL N+vljeyRxgGH/JyEWip/XQb8HjKdPVynYDcBA97fc18E0uPMfs2gB0sa26nBLjpPcs RIEXMJFp/0cDxs0crZvB14efNoNVqxGfbI/4YpduxgtlWL91v+cIQ17jn4NlqEWun7 PXjHq7DnisSBw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3EB2C5ACD1; Fri, 7 Aug 2026 21:52:48 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:53 -0700 Subject: [PATCH v10 14/41] mm/gup: factor out LRU cache draining for folio into lru_cache_drain_for_folio() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-14-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5756; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=xV++FlZvFI4NwrLc3veqIQ22RTFlEXFJFbRA5Ehxu/0=; b=9YrnGTHepXwH7Ocuf/jdvkIQyqGXFL+hq1GjIfVIdNlq/Sj/XRMZp5UufgETznFOEOs76yZdZ b8PmUno3coGDK7JcNd2gKLkodQEly/BURV7tihbNuQW+fmMbNrK3aFw X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: "David Hildenbrand (Arm)" KVM with guest_memfd wants to remove any folio references due to LRU caches, as it really must only allow to convert folios from shared to private when there are no unexpected folio references (e.g., from GUP references). So, to drive the refcount down, it needs a way to flush the LRU caches. Let's factor out what we have in lru_cache_drain_for_folio(). Document it, and also mention that concurrent folio (un)mapping might, in theory, miss detecting LRU cache references. Keep obtaining the expected refcount twice to minimize the possibility. For the current and future user that should work, and we don't really have a better alternative: we could detect if the mapcount changed, but it would still be racy and add more complexity with questionable benefit. Maybe there is a chance to avoid the draining entirely in the future, by avoiding extra references from the LRU cache: Hugh thinks there might be a way. But for the time being, this handling is unfortunately required. Make folio_may_be_lru_cached() accept a const pointer so lru_cache_drain_for_folio() can accept a const pointer as well. Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Ackerley Tng Reviewed-by: Fuad Tabba --- include/linux/swap.h | 11 ++++++++++- mm/gup.c | 15 ++------------- mm/swap.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 8f0f68e245baa..e625d64c9e13d 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -317,7 +317,7 @@ void folio_add_lru_vma(struct folio *, struct vm_area_s= truct *); void mark_page_accessed(struct page *); void folio_mark_accessed(struct folio *); =20 -static inline bool folio_may_be_lru_cached(struct folio *folio) +static inline bool folio_may_be_lru_cached(const struct folio *folio) { /* * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. @@ -344,6 +344,15 @@ extern void lru_add_drain(void); extern void lru_add_drain_cpu(int cpu); extern void lru_add_drain_cpu_zone(struct zone *zone); extern void lru_add_drain_all(void); + +enum lru_cache_drained { + LRU_CACHE_NOT_DRAINED, + LRU_CACHE_DRAINED, + LRU_CACHE_DRAINED_ALL, +}; +void lru_cache_drain_for_folio(const struct folio *folio, + unsigned int extra_refs, enum lru_cache_drained *drained); + void folio_deactivate(struct folio *folio); void folio_mark_lazyfree(struct folio *folio); extern void swap_setup(void); diff --git a/mm/gup.c b/mm/gup.c index bde05664fe9a9..1bd8915517196 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -2266,9 +2266,9 @@ static unsigned long collect_longterm_unpinnable_foli= os( struct list_head *movable_folio_list, struct pages_or_folios *pofs) { + enum lru_cache_drained drained =3D LRU_CACHE_NOT_DRAINED; unsigned long collected =3D 0; struct folio *folio; - int drained =3D 0; long i =3D 0; =20 for (folio =3D pofs_get_folio(pofs, i); folio; @@ -2293,18 +2293,7 @@ static unsigned long collect_longterm_unpinnable_fol= ios( * but also to remove any other folio references from LRU * caches. */ - if (drained =3D=3D 0 && folio_may_be_lru_cached(folio) && - folio_ref_count(folio) !=3D - folio_expected_ref_count(folio) + pin_refs) { - lru_add_drain(); - drained =3D 1; - } - if (drained =3D=3D 1 && folio_may_be_lru_cached(folio) && - folio_ref_count(folio) !=3D - folio_expected_ref_count(folio) + pin_refs) { - lru_add_drain_all(); - drained =3D 2; - } + lru_cache_drain_for_folio(folio, pin_refs, &drained); =20 if (!folio_isolate_lru(folio)) continue; diff --git a/mm/swap.c b/mm/swap.c index 588f50d8f1a8c..8e965c8ce9aa9 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -950,6 +950,52 @@ void lru_add_drain_all(void) } #endif /* CONFIG_SMP */ =20 +/** + * lru_cache_drain_for_folio() - drain LRU caches if the caches might hold + * folio references + * @folio: The folio. + * @extra_refs: Extra folio references held by the caller. + * @drained: Drain status for batch folio processing. + * + * Drain LRU caches if the caches might hold folio references. Start + * with a local LRU cache drain, to then drain LRU caches on all CPUs if + * local draining was insufficient. + * + * This function detects LRU cache references by comparing the folio refco= unt + * with the sum of the expected folio refcount + extra references held by = the + * caller. Note that we cannot rely on PG_lru to reliably detect all LRU + * cache references, and there are rare scenarios (concurrent folio (un)ma= pping) + * where this function might miss detecting LRU cache references. + * + * If @drained is not NULL, the function will avoid re-draining LRU caches + * when processing multiple folios in a row. In that case, the variable + * @drained points at must be initialized to LRU_CACHE_NOT_DRAINED before + * the first invocation by the caller. + */ +void lru_cache_drain_for_folio(const struct folio *folio, + unsigned int extra_refs, enum lru_cache_drained *drained) +{ + if (!folio_may_be_lru_cached(folio)) + return; + + if (!drained || *drained =3D=3D LRU_CACHE_NOT_DRAINED) { + if (folio_ref_count(folio) =3D=3D + folio_expected_ref_count(folio) + extra_refs) + return; + lru_add_drain(); + if (drained) + *drained =3D LRU_CACHE_DRAINED; + } + if (!drained || *drained =3D=3D LRU_CACHE_DRAINED) { + if (folio_ref_count(folio) =3D=3D + folio_expected_ref_count(folio) + extra_refs) + return; + lru_add_drain_all(); + if (drained) + *drained =3D LRU_CACHE_DRAINED_ALL; + } +} + atomic_t lru_disable_count =3D ATOMIC_INIT(0); =20 /* --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6C37A46D554; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=gaPY9ZkesrF2krMAbNxL1HXZs1I+uD6LREZP0lQzfzbMDv497Q2AGAsMcwbgA3z3fhfsIkbf0yZM3YK7r39UImq/VMwhDnWH7V0QZloRn9BWktuEFrFFpsoYsOmEiQUezDcr7ZddEYFHrTTiqwlKAwm+fCO+t/F5thko6V9zl7w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=TkzoIndNGWAz7eMJZIeS00Akw8QP2H+V8GKbGu+OhPY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GNu7gseQ3z92vIm37Z0FL64MWmEvWGJ52RjSD6jXo8+CdGqn+uus+HnROmCagWjP+mN+FiIpnQzr5T0N1QCL8v5acmSo2e+TZPf0KUjG9O702ijBcj1oB88E3eGIFobIEuoiLYkmvI0+4mwf+Bf697+/XQL8id9gR8zfo3WUCUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FLjD6LF7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FLjD6LF7" Received: by smtp.kernel.org (Postfix) with ESMTPS id 1CB93C2BCFA; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=TkzoIndNGWAz7eMJZIeS00Akw8QP2H+V8GKbGu+OhPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FLjD6LF7CmdK9sSRhsqRFy72cX5AQdbHg9Gl/7NkFIrl/CCSM9yBJgZHB/WqJXmIg 9zVspnWnCfoGkk9XU4xt4dv0ojCKW2JaHsKzaptjrgUQ9te1ucdBwxfyTRVYHotQXb hsXbkbKpM6OdbeVbTroe2kT7zk6zfRXrF9rgf8dlqgldxhr8amZ+U46LWAS6PfxdYp TgT8EX+wurZzkD+hy53R22CVQk+i4N+abVS/WFAOU+Zigh8aVrhjwLPJj/32h1fHnD ETYPcSyurHVqU0vD8202HRqss3gQDOpppFFdrAs7pDyH1iAfpPJat33TU40+k7O2lz qqxcdLg8RcZag== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 065F0C5ACD4; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:54 -0700 Subject: [PATCH v10 15/41] KVM: guest_memfd: Handle lru_add fbatch refcounts during conversion safety check Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-15-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , "Vlastimil Babka (SUSE)" X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3762; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=vRHAPnsy/a831M2QO9lXaFqyTG6Mc0Skqo/1hc4/61s=; b=9TIb+ZXbdQMmrXLDC7072TqBL/mub/d5Ks6MUbovt3WcKeDpnixAU2yGfF0KPtDV9N+i5+ZFg hfk34FX6oJiCGmv+DpvAaRMkwVZbxV9kE6Xqd6nBrhbp7s0dXmGD85o X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng A guest_memfd folio is safe for conversion if guest_memfd holds the last references on it. Any other references on the folio may indicate another user, and guest_memfd cannot convert it to private if there may be an existing host user. A folio will have extra refcounts if it is present in a per-CPU lru_add fbatch. guest_memfd does not actually participate in LRU, but freshly-allocated folios are still added to the lru_add fbatch for batch LRU statistics processing. This one known "usage" of the folio is handled by draining the lru_add fbatch. After draining, if the refcount is still elevated, then there's truly some other user of this page, and the page is not safe for conversion. If the page may be dma pinned, DMA is obviously using it and hence not safe for conversions. If the page is still mapped after guest_memfd tried to unmap it earlier in the conversion process, it is also obviously not safe for conversion. Exit early to avoid unnecessary draining in these 2 cases. Provide a drain status to only drain once ever while processing a batch of folios. Acked-by: Vlastimil Babka (SUSE) Suggested-by: David Hildenbrand Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu Reviewed-by: Fuad Tabba --- mm/swap.c | 2 ++ virt/kvm/guest_memfd.c | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/mm/swap.c b/mm/swap.c index 8e965c8ce9aa9..9f511b97ab110 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -37,6 +37,7 @@ #include #include #include +#include =20 #include "internal.h" =20 @@ -995,6 +996,7 @@ void lru_cache_drain_for_folio(const struct folio *foli= o, *drained =3D LRU_CACHE_DRAINED_ALL; } } +EXPORT_SYMBOL_FOR_KVM(lru_cache_drain_for_folio); =20 atomic_t lru_disable_count =3D ATOMIC_INIT(0); =20 diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 896699afcad9d..030af0855f8b0 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -8,6 +8,7 @@ #include #include #include +#include =20 #include "kvm_mm.h" #include "guest_memfd.h" @@ -542,11 +543,26 @@ static int kvm_gmem_mas_preallocate(struct ma_state *= mas, u64 attributes, return mas_preallocate(mas, xa_mk_value(attributes), GFP_KERNEL); } =20 +static bool __folio_safe_for_conversion(struct folio *folio, + enum lru_cache_drained *drained) +{ + const int filemap_get_folios_refcount =3D 1; + + if (folio_maybe_dma_pinned(folio) || folio_mapped(folio)) + return false; + + lru_cache_drain_for_folio(folio, filemap_get_folios_refcount, + drained); + + return folio_ref_count(folio) =3D=3D + folio_nr_pages(folio) + filemap_get_folios_refcount; +} + static bool kvm_gmem_is_safe_for_conversion(struct inode *inode, pgoff_t s= tart, size_t nr_pages, pgoff_t *err_index) { + enum lru_cache_drained drained =3D LRU_CACHE_NOT_DRAINED; struct address_space *mapping =3D inode->i_mapping; - const int filemap_get_folios_refcount =3D 1; pgoff_t last =3D start + nr_pages - 1; struct folio_batch fbatch; bool safe =3D true; @@ -560,9 +576,8 @@ static bool kvm_gmem_is_safe_for_conversion(struct inod= e *inode, pgoff_t start, for (i =3D 0; i < folio_batch_count(&fbatch); ++i) { struct folio *folio =3D fbatch.folios[i]; =20 - if (folio_ref_count(folio) !=3D - folio_nr_pages(folio) + filemap_get_folios_refcount) { - safe =3D false; + safe =3D __folio_safe_for_conversion(folio, &drained); + if (!safe) { *err_index =3D max(start, folio->index); break; } --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8081D46E01C; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=EFYDYZiF9rZSMeFJvWJck8Bo/RRJVb0fMK9FECs+aWA4vdWkkutaVuC4vXsBpPW27XlAoY7okTmKRTernoDFY9bRjEzXgCzc+X13LCdKVlAuUVQupkabW9B+2KkJeP01mu4kW25cXJXAAR5KB6U7iz4HyHTnjdYxKqh6/ZsCtJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=vlMdPByiTSwzUUCngQu0R7QT3mZcq70VQdRClRIO7xE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=O09ARcWj57tDdgac29jx+5Dvaaan24I4qALyqAPsv5M60JyKuC7Tp7hnUMwnrLTSPyHaVz3qEPAcSrMus8LL2WKltI05gN4M4UwwdD+gJXdkshH3bHSCGrdq4uoEn9MKssBKs3NJ/7VQeXId7CeMONkzD09xt0ZbCJImNwIJ8v4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L3e89q+G; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="L3e89q+G" Received: by smtp.kernel.org (Postfix) with ESMTPS id 42F5AC2BCFD; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=vlMdPByiTSwzUUCngQu0R7QT3mZcq70VQdRClRIO7xE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=L3e89q+GDFleJcGjL5VMnUKlaKh0Pmh4Xd8lok7xboM5efF5etd6xaXQElHVXzPIv 36lXYFvxbo8VSx+gsfu5OxDzPfdCri1aArnTBAc3S6Ay0JjVFGTIzuyJK0OdTy9TyH HRDbQNW1MJviiGsJzEtN2rMkp0FSZgF1m1FT0OWAqSbwbAjqT9NbxGj1WdXUKxZBfC xkKj4iX74AoNG+cN6ikIMte1YjbHBnK0ieBJJzkmdeAEjG4ljZhuAgNKJgiIJ2sTKJ u8JqZ3ltOOPxvFjaz0A+2Er0vVt4ON34cWeT7G5m77Xn1V8SLYBEzwjlAuYRZ4lma0 Z9OTdzE1bocUQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1CA1EC5ACDC; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:55 -0700 Subject: [PATCH v10 16/41] KVM: guest_memfd: Zero page while getting pfn Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-16-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2563; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=yJn/ZHgiLozpfiaF3WvTX3dAxLUI4g7cee7UK9m2PVM=; b=l30Jr9f3hi6OTXNRNCJUYvIodwuNAe/9sIlpUlyIylb9JLbckvWkQEC0O3MkF9z/Ad2RJAuKg fQ+UqUROtkeAcqmpEqLAFhsm4pcVQLQgS28LhNijkgBlq/BTWV7VOub X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Move the folio initialization logic from kvm_gmem_get_pfn() into __kvm_gmem_get_pfn() to also zero pages if the page is to be used in kvm_gmem_populate(). With in-place conversion, the existing data in a guest_memfd page can be populated into guest memory through platform-specific ioctls. Without first zeroing the page obtained using __kvm_gmem_get_pfn(), it might contain uninitialized host memory, which would leak to the guest if the populate completes. guest_memfd pages are zeroed at most once in the page's entire lifetime with guest_memfd, and that is tracked using the uptodate flag. Zeroing the page in __kvm_gmem_get_pfn() is chosen over zeroing in kvm_gmem_get_folio() since other flows, such as a future write() syscall, can get a page, write to the page and then set page uptodate without zeroing. This aligns with the concept of zeroing before first use - the other place where zeroing happens is in kvm_gmem_fault_user_mapping(). Don't mark the page uptodate again after populating, since the page would already be marked uptodate before the post_populate() call. Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Reviewed-by: Xiaoyao Li Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu --- virt/kvm/guest_memfd.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 030af0855f8b0..41950c8105b5d 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -1079,6 +1079,11 @@ static struct folio *__kvm_gmem_get_pfn(struct file = *file, return ERR_PTR(-EHWPOISON); } =20 + if (!folio_test_uptodate(folio)) { + clear_highpage(folio_page(folio, 0)); + folio_mark_uptodate(folio); + } + *pfn =3D folio_file_pfn(folio, index); if (max_order) *max_order =3D 0; @@ -1108,11 +1113,6 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_mem= ory_slot *slot, goto out; } =20 - if (!folio_test_uptodate(folio)) { - clear_highpage(folio_page(folio, 0)); - folio_mark_uptodate(folio); - } - #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT if (kvm_gmem_is_private_mem(file_inode(file), index)) r =3D kvm_arch_gmem_make_private(kvm, gfn, *pfn, @@ -1159,8 +1159,6 @@ static long __kvm_gmem_populate(struct kvm *kvm, stru= ct kvm_memory_slot *slot, } =20 ret =3D post_populate(kvm, gfn, pfn, src_page, opaque); - if (!ret) - folio_mark_uptodate(folio); =20 out_put_folio: folio_put(folio); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8E25846EC77; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=LIE7VyOrmdmPUgUmVSrFko+SEK2f1bow2U8LOcNy/IjVtDDKLLCSRULu058vawhlWpOc/lgx/orofcA+7ojGaLXF42IbTcZybyMcb1/RlNthHRyg3/+l9rr3qcIlebw2JOgBFhSmeS9SEieLlHn42tmmPmOwsqvmhyMUClVgUEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=YLkbSQhpDpMycPtWvUxnGRmi6OR/9u7YMYaQaKabGgc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZPD6jNIHMXpZTDe8hdUfpYbjoDkHREp87fULNCQFSXlnlhQJz7vxRysfvoxe2vfJIUpxEPNrFUZtXPaAZR0Ck+GcLXo5FaYBzD7LhSLrJL88ftBYa4Q4xG3fgqy22R+CrxsJE5d4AZiqoEPq0M+02qgg6hepodeo7pJwvhYF09c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=C5MHI5lA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="C5MHI5lA" Received: by smtp.kernel.org (Postfix) with ESMTPS id 56CFEC4AF15; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=YLkbSQhpDpMycPtWvUxnGRmi6OR/9u7YMYaQaKabGgc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=C5MHI5lAd4WHcV83RSWSMUwIcuq1DMdmnnW+xBxBTCudosL+aokFoNP06Qic//xqJ G1lmGjXtQGoNgwWayfgn10YWPcQdLHWkTy+BB9nyXcvU3Z7h7IE8okCKpItEQ7O+BU XCtDc6w4B6qUFg1MWLUSnLt6kXSd5itStTf4djDHZ5+kx4zRKA9RGHhUpf/7cruTTL 75glyqUuD3wrxFLsoElo58sfxNzU2hHMwi+vuxN1JLJQRHKiajiSwQVoqp74ov7d8F 8iokMsI4Dibkb/vNQtiS2oKvQgtDij1nkXSxvB2BDIkP/1K4X1bfGQmPeRyQt+/KlK Kf4U0CU06X9JQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37B57C5ACD3; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:56 -0700 Subject: [PATCH v10 17/41] KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-17-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5596; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=Iifl8NJUsDgSsBpjrwts0t02fef1fqDsec4cScY8f1c=; b=cZ7fBEFP/xuyv8gSTtlch/yP4N5da9RI6xl6mhTKrajA1+LsfZh55074pb/jZTksdexu/WOr9 gcXzEitzx6jDPYdYwYlLRaWoPYBxx79GoUQxwq+dFoqHAlMdkkyiIAs X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Michael Roth Make the source page for populating an SNP guest_memfd instance optional if in-place conversion/population is enabled. If KVM can convert the page in-place, then it's possible for guest memory to be initialized directly from userspace by mmap()'ing the guest_memfd and writing to it while the corresponding GPA ranges are in a 'shared' state, before converting them to the 'private' state expected by KVM_SEV_SNP_LAUNCH_UPDATE. Update the handling/documentation for KVM_SEV_SNP_LAUNCH_UPDATE to allow for 'uaddr' to be set to NULL when in-place conversion is enabled, which SNP_LAUNCH_UPDATE will then use to determine when it should/shouldn't copy in data from a separate memory location. Continue to enforce non-NULL when PRIVATE is tracked per-VM, not per-guest_memfd. Signed-off-by: Michael Roth [Moved condition to snp_launch_update] Signed-off-by: Sean Christopherson Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- Documentation/virt/kvm/x86/amd-memory-encryption.rst | 14 ++++++++++---- arch/x86/kvm/svm/sev.c | 11 ++++++----- virt/kvm/kvm_main.c | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documen= tation/virt/kvm/x86/amd-memory-encryption.rst index bd04a908a8dbd..5977fbe33b98c 100644 --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst @@ -503,7 +503,8 @@ secrets. =20 It is required that the GPA ranges initialized by this command have had the KVM_MEMORY_ATTRIBUTE_PRIVATE attribute set in advance. See the documentati= on -for KVM_SET_MEMORY_ATTRIBUTES for more details on this aspect. +for KVM_SET_MEMORY_ATTRIBUTES/KVM_SET_MEMORY_ATTRIBUTES2 for more details = on +this aspect. =20 Upon success, this command is not guaranteed to have processed the entire range requested. Instead, the ``gfn_start``, ``uaddr``, and ``len`` fields= of @@ -511,9 +512,14 @@ range requested. Instead, the ``gfn_start``, ``uaddr``= , and ``len`` fields of remaining range that has yet to be processed. The caller should continue calling this command until those fields indicate the entire range has been processed, e.g. ``len`` is 0, ``gfn_start`` is equal to the last GFN in the -range plus 1, and ``uaddr`` is the last byte of the userspace-provided sou= rce -buffer address plus 1. In the case where ``type`` is KVM_SEV_SNP_PAGE_TYPE= _ZERO, -``uaddr`` will be ignored completely. +range plus 1, and ``uaddr`` (if specified) is the last byte of the +userspace-provided source buffer address plus 1. + +In the case where ``type`` is KVM_SEV_SNP_PAGE_TYPE_ZERO, ``uaddr`` will be +ignored completely. For all other page types, ``uaddr`` is optional if in-= place +conversion is enabled (i.e. when the data had been written directly to +guest_memfd while the page was in the shared state) and is required if in-= place +conversion is disabled. =20 Parameters (in): struct kvm_sev_snp_launch_update =20 diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index fcb41dfde4c02..f708fccf71307 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2395,7 +2395,7 @@ static int sev_gmem_post_populate(struct kvm *kvm, gf= n_t gfn, kvm_pfn_t pfn, */ if (ret && !snp_page_reclaim(kvm, pfn) && sev_populate_args->type =3D=3D KVM_SEV_SNP_PAGE_TYPE_CPUID && - sev_populate_args->fw_error =3D=3D SEV_RET_INVALID_PARAM) { + sev_populate_args->fw_error =3D=3D SEV_RET_INVALID_PARAM && src_page)= { void *src_vaddr =3D kmap_local_page(src_page); void *dst_vaddr =3D kmap_local_pfn(pfn); =20 @@ -2428,8 +2428,8 @@ static int snp_launch_update(struct kvm *kvm, struct = kvm_sev_cmd *argp) if (copy_from_user(¶ms, u64_to_user_ptr(argp->data), sizeof(params))) return -EFAULT; =20 - pr_debug("%s: GFN start 0x%llx length 0x%llx type %d flags %d\n", __func_= _, - params.gfn_start, params.len, params.type, params.flags); + pr_debug("%s: GFN start 0x%llx length 0x%llx type %d flags %d src %llx\n"= , __func__, + params.gfn_start, params.len, params.type, params.flags, params.uaddr); =20 if (!params.len || !PAGE_ALIGNED(params.len) || params.flags || (params.type !=3D KVM_SEV_SNP_PAGE_TYPE_NORMAL && @@ -2441,7 +2441,8 @@ static int snp_launch_update(struct kvm *kvm, struct = kvm_sev_cmd *argp) =20 if (params.type =3D=3D KVM_SEV_SNP_PAGE_TYPE_ZERO) src =3D NULL; - else if (!params.uaddr || !PAGE_ALIGNED(params.uaddr)) + else if ((!gmem_in_place_conversion && !params.uaddr) || + !PAGE_ALIGNED(params.uaddr)) return -EINVAL; else src =3D u64_to_user_ptr(params.uaddr); @@ -2488,7 +2489,7 @@ static int snp_launch_update(struct kvm *kvm, struct = kvm_sev_cmd *argp) =20 params.gfn_start +=3D count; params.len -=3D count * PAGE_SIZE; - if (params.type !=3D KVM_SEV_SNP_PAGE_TYPE_ZERO) + if (src && params.type !=3D KVM_SEV_SNP_PAGE_TYPE_ZERO) params.uaddr +=3D count * PAGE_SIZE; =20 if (copy_to_user(u64_to_user_ptr(argp->data), ¶ms, sizeof(params))) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c4c09593ef8b9..c8faf1cb82167 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -104,6 +104,7 @@ module_param(allow_unsafe_mappings, bool, 0444); =20 #ifdef kvm_arch_has_private_mem bool __ro_after_init gmem_in_place_conversion =3D false; +EXPORT_SYMBOL_FOR_KVM_INTERNAL(gmem_in_place_conversion); #endif =20 /* --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 99A4B46EC84; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=TvpWKd2A1fMevp7/Ur5TmnPlWL7G1ZSsjpkvGeCUQsYoXSGyuuX0vcCVGuZPK5uPZ/2XdbcwR3dw/dq2y9LtEpoppcgYlOSJ3i5UlyZUWqt3qJjfafDFVl2OSLpfyCV+XX+8rH3fk0mT+boyyH+JFbWaoW9cLhmyMefAwoyGZaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=H5Oy0gF2fAL2oTAVvZmzLgNPhktjGp2oky/braofGkA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LNE3NQkbJX+aHw1p+ML47lAS4xkMf9rKmfIcKRKmvAPhjaYfsw2WyepApR/ig6EfYyCUNsJ2RJL2UyI7tfM1uAVIzs1/atkWnjLT+UJZiKg6xBxdq5SQ7noDOLMJgWBYjt6v9BbaM+z7L2vsGCGDhQdjCbQwFOte/P/DVOgCYq4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sqYM4m6F; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sqYM4m6F" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6CF14C32781; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=H5Oy0gF2fAL2oTAVvZmzLgNPhktjGp2oky/braofGkA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=sqYM4m6FxYF0P6oVPLzdGLuGff4ig1Gl0Zs7QsSaLdgcPpZ0/4+O+cHbZktVlgCXh YvXIKPA/9wd340dbwouV0s/Gln3ySLW5l2R2XuMo91XM/pM3w9XA+68Fn/8r61yp38 BjfVqkWLfKfGsKj1TD5hbn03QcmsrIt6lrqqAHFfwZw06SIatN2LprjtW/KZQh4KlY 4e4AAHTRlqLfp8qG+kSywvi7wNd3jRz1xcEMuKEvy4eYplOo1t9azVlfz+Eiig3zzy nCIq4NZwRYlHwARtKQ/3Zooy+kvuP9xngxNB5f5SvGbg06aN/C7A5IR7lqpF5c8ZVM b1Hqi1Gx7wj6w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 524BAC5ACD1; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:57 -0700 Subject: [PATCH v10 18/41] KVM: TDX: Make source page optional for KVM_TDX_INIT_MEM_REGION Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-18-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3323; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=fww/oL6aOL/zYOalPjjTEuFSWzNlNDgN26Nz/nDPoIw=; b=UsF5OWRfMfq1ob58hfueI4ABe8ND/ASl9ukTcTiCBDkuD3ck+A8QWQy8R4fap+euJOj80T6tM Dq4X1R9/FqCAxtgtlm6ZxM6W3dkxnpeNt8vBhyquk2Og3YAcaafiCzE X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Update tdx_gmem_post_populate() to handle cases where userspace requests "no source page". To handle "no source page", populate (perform TDH.MEM.PAGE.ADD) using memory in-place at the target PFN. Allow "no source page" only when gmem_in_place_conversion is enabled, because retroactively adding support for out-of-place conversion would mean requiring a userspace update for a feature that's being deprecated. Also, KVM supporting "no source page" without in-place conversion would effectively be an obscure zero-page optimization that relies on the page being zeroed when it is allocated by guest_memfd. Rejecting "no source page" without in-place conversion scenario is valuable for KVM developers since it helps newcomers understand what exactly is and isn't possible. Signed-off-by: Sean Christopherson Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: Yan Zhao Reviewed-by: Xiaoyao Li Reviewed-by:Binbin Wu Tested-by: Yan Zhao --- Documentation/virt/kvm/x86/intel-tdx.rst | 4 ++++ arch/x86/kvm/vmx/tdx.c | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Documentation/virt/kvm/x86/intel-tdx.rst b/Documentation/virt/= kvm/x86/intel-tdx.rst index 6a222e9d09541..d8d9409120e61 100644 --- a/Documentation/virt/kvm/x86/intel-tdx.rst +++ b/Documentation/virt/kvm/x86/intel-tdx.rst @@ -158,6 +158,10 @@ KVM_TDX_INIT_MEM_REGION Initialize @nr_pages TDX guest private memory starting from @gpa with user= space provided data from @source_addr. @source_addr must be PAGE_SIZE-aligned. =20 +If guest_memfd in-place conversion is enabled, pass 0 for @source_addr +to represent "no source page". A source page is required if in-place +conversion is not enabled or not supported. + Note, before calling this sub command, memory attribute of the range [gpa, gpa + nr_pages] needs to be private. Userspace can use KVM_SET_MEMORY_ATTRIBUTES to set the attribute. diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index b272c20586a74..7654a9f5fa128 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -3189,7 +3189,7 @@ static int tdx_gmem_post_populate(struct kvm *kvm, gf= n_t gfn, kvm_pfn_t pfn, if (KVM_BUG_ON(kvm_tdx->page_add_src, kvm)) return -EIO; =20 - kvm_tdx->page_add_src =3D src_page; + kvm_tdx->page_add_src =3D src_page ?: pfn_to_page(pfn); ret =3D kvm_tdp_mmu_map_private_pfn(arg->vcpu, gfn, pfn); kvm_tdx->page_add_src =3D NULL; =20 @@ -3235,7 +3235,8 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *= vcpu, struct kvm_tdx_cmd *c if (copy_from_user(®ion, u64_to_user_ptr(cmd->data), sizeof(region))) return -EFAULT; =20 - if (!PAGE_ALIGNED(region.source_addr) || !region.source_addr || + if (!PAGE_ALIGNED(region.source_addr) || + (!gmem_in_place_conversion && !region.source_addr) || !PAGE_ALIGNED(region.gpa) || !region.nr_pages || region.gpa + (region.nr_pages << PAGE_SHIFT) <=3D region.gpa || !vt_is_tdx_private_gpa(kvm, region.gpa) || @@ -3266,7 +3267,8 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *= vcpu, struct kvm_tdx_cmd *c break; } =20 - region.source_addr +=3D PAGE_SIZE; + if (region.source_addr) + region.source_addr +=3D PAGE_SIZE; region.gpa +=3D PAGE_SIZE; region.nr_pages--; =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A9F0A470EAA; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; cv=none; b=sfeh0ab57G5nnX4Rfv44szqf92nYNGGZ4hc/5BBQ5a9X2lNOoKn+e1wIzWpBQH4mTXRNuJmtJBHxWXLFTx1Bezvo06ZS2z6xzgAglHUvnKvI0jUVFccgN49x/7CMselS7O3U92OqTzcKvFKulIjjm5cLlzNS1iMLfq4jCODaZQU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139569; c=relaxed/simple; bh=2EpBA5sGDET0qt2T2epup75WyxodbT/NsUKEpK8prA8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B3AraZwnp3IhGJBknY/uyUHPfcjM9C5HTdgE+HkAwTHH7sVW4rsyxESsYYZmBDMkUFgu+t9/zBtiWW8QxiqbSG/A5tvj5Ctfp+dktaXB4UoxXcWpP5jfpr0eLdTxdHRAT03QZvTqRKaG91qLqMZian/BI+nUTBvlc426u8Dg030= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XoyUtaFO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XoyUtaFO" Received: by smtp.kernel.org (Postfix) with ESMTPS id 87257C2BCB8; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=2EpBA5sGDET0qt2T2epup75WyxodbT/NsUKEpK8prA8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=XoyUtaFOTuS2Be191isNuZ26ETbtz66rE/oCWcdLe5cOnb9gNkjoEZN/Vha8YIFvU tgPlG8hkygbNLamvgLDVFj7DBE7/1oLiJvme/NcpM0BCFDYT16LxsEKlTunf2jF1m5 LHfzKXjp1vAXc8FkgfjLYj7r2PkVo7LukambYNrpsDMvNuZx1nOTwiLYAn7QKlsM8M Q/v4+BX4vcGCuXlqnpYx1PYTgCTuGjLJLLa9ZlnkpBHa0wLGG9slg8HIsAYsPLItXa xYSiKlE4pQ+Kxroc40P9wE+iJii/IfIH/50D818WdCFWZAlQXjapNG5vdMhAb/nHei TJ2wydTWKwHUQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67232C5ACD7; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:58 -0700 Subject: [PATCH v10 19/41] KVM: Move KVM_VM_MEMORY_ATTRIBUTES config definition to x86 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-19-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=1945; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=+JOgNYzvijHAbgsG714d2CFgRX+TpUch731NU30JkJw=; b=qa1RDK48ZoSRufWd3VcENYFdgzxg5WzQA1log0T8jZiNU2/DF9PGN9GgSFYHGl/wJ2CoWclDe SuehuYSCVQNDv2bAvArbWAzQ5d2REkZybveET4JY+WVWBRXal2ObNBE X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Bury KVM_VM_MEMORY_ATTRIBUTES in x86 to discourage other architectures from adding support for per-VM memory attributes, because tracking private vs. shared memory on a per-VM basis is now deprecated in favor of tracking on a per-guest_memfd basis, and while RWX memory attributes are on the horizon, they too are expected to be x86-only. This will also allow modifying KVM_VM_MEMORY_ATTRIBUTES to be user-selectable (in x86) without creating weirdness in KVM's Kconfigs. Now that guest_memfd supports in-place conversions, it's entirely possible to run x86 CoCo VMs without support for KVM_VM_MEMORY_ATTRIBUTES. Leave the code itself in common KVM so that it's trivial to undo this change if new per-VM attributes do come along. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Reviewed-by: Xiaoyao Li Reviewed-by: Binbin Wu Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: David Hildenbrand (Arm) --- arch/x86/kvm/Kconfig | 3 +++ virt/kvm/Kconfig | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 2f8e1b5a8a72c..abb108886733a 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -80,6 +80,9 @@ config KVM_WERROR =20 If in doubt, say "N". =20 +config KVM_VM_MEMORY_ATTRIBUTES + bool + config KVM_SW_PROTECTED_VM bool "Enable support for KVM software-protected VMs" depends on EXPERT diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index df575449d97b5..a0678ef8ee3f5 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -100,9 +100,6 @@ config KVM_ELIDE_TLB_FLUSH_IF_YOUNG config KVM_MMU_LOCKLESS_AGING bool =20 -config KVM_VM_MEMORY_ATTRIBUTES - bool - config KVM_GUEST_MEMFD select XARRAY_MULTI bool --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EDC584746A3; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=aTM6Va9NUs9lE1o+ND+s4vSF6zk8X5ORfPSLIe80Vtttrh6uIN/3RvqpHVNqoZDzjF2yJVCXaqneQ5viE78YS2jry1dJ7UUDkUx49Fc4ZzmysRMW2yku6EP7VMl3L4Hy9se1lQVSqrgKpmAdShCIwOPuGItT/Wr6ZH3n8QcJCs4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=0BBukiFYZw1FttDXc9H2e2gVciDX2jiZZXVLVKwsPdk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EM113THjYBp108oaLVjXNr3M6QZnVFrKZ27wMzet1V9FUQJeIRC7U9zVYI/+Qz6je6TRBBOXxxMrD+jwWF9jUWb5DwkfU+KqYFy73mRQnw1rvRP+7BoHB4PdyLnD46+EUlxIi53MekbGmZdWXhjEXpdxta+3FyGrax81zOGCvx8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gt6Wl9w2; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gt6Wl9w2" Received: by smtp.kernel.org (Postfix) with ESMTPS id C64C8C2BCC7; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=0BBukiFYZw1FttDXc9H2e2gVciDX2jiZZXVLVKwsPdk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=gt6Wl9w2IuXhqUGozOXk2jcbHR09hnfkr0y3OFMoXrkXeeZyfzbor7C117mv3Yomn PVuK+LUlmmWW6UHavq7uvHVf3AGuOH04G1mRYkpIl7g3ksq5w6hk4dnrM9B2wNgho/ a55Fb99ZxLLKGj9kq/VbUzE5neikp+nIH2tFzZ7TOR7rR2Qwau99NzAxZpIALyxsFx bbcQ7HcAvp1Oks23mKkZRDPmIs2wGj3bhzySbaEyLnqHVOyle2Hzc0Iyk7mGYOhecN a2hv/DXSYprq4KqkexgptEVIDTWFQ+RpxqlHeWe1pbBVuvpPb4VCx0siLYjnhHRmXN P1MfpmYIU2pNQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE06CC5ACD1; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:52:59 -0700 Subject: [PATCH v10 20/41] KVM: Let userspace disable per-VM mem attributes, enable per-gmem attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-20-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=4464; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=DoOtiRr7PnjV3LVVxFaOZZNnOLaNAPiMfDiZIxCzkgc=; b=Vfxzcm0J8wZo+2z2ujIp3YnjboO5emv008lB7aJpQWlGiySzlzdGEAqelqa/H8mdYT/D9qdiW VG45PMlv4p4CnBac1/f0encu/BwvslI9Yq/1DE6Rx8Lne4gYrOlqoq2 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Make gmem_in_place_conversion a module parameter so that userspace can configure enable or disable the use of VM-level memory attributes. The module parameter is only available if CONFIG_KVM_VM_MEMORY_ATTRIBUTES is enabled. To avoid inconsistencies in the way memory attributes are tracked in KVM and guest_memfd, the vm_memory_attributes module_param is made read-only (0444). Since selecting CONFIG_KVM_VM_MEMORY_ATTRIBUTES disables in-place conversion, actually make CONFIG_KVM_VM_MEMORY_ATTRIBUTES selectable. Make the config only selectable for (CoCo) VM types that might use vm_memory_attributes. Since memory attributes are trackable in guest_memfd, the concept of having private memory is no longer dependent on CONFIG_KVM_VM_MEMORY_ATTRIBUTES. Define kvm_arch_has_private_mem() based on platform config, so that having private memory is dependent on (CoCo) VM type. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg [Define module_param only if CONFIG_KVM_VM_MEMORY_ATTRIBUTES is enabled] Suggested-by: Xiaoyao Li Reviewed-by: Xiaoyao Li Signed-off-by: Ackerley Tng --- arch/x86/include/asm/kvm_host.h | 4 +++- arch/x86/kvm/Kconfig | 14 ++++++++++---- virt/kvm/kvm_main.c | 5 ++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 497da6aaf2942..bb2c1ade62cf9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1851,7 +1851,9 @@ enum kvm_intr_type { ((vcpu) && (vcpu)->arch.handling_intr_from_guest && \ (!!in_nmi() =3D=3D ((vcpu)->arch.handling_intr_from_guest =3D=3D KVM_HAN= DLING_NMI))) =20 -#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES +#if defined(CONFIG_KVM_SW_PROTECTED_VM) || \ + defined(CONFIG_KVM_INTEL_TDX) || \ + defined(CONFIG_KVM_AMD_SEV) #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) #endif =20 diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index abb108886733a..2c3c22aeafa54 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -81,13 +81,21 @@ config KVM_WERROR If in doubt, say "N". =20 config KVM_VM_MEMORY_ATTRIBUTES - bool + bool "Enable per-VM PRIVATE vs. SHARED attributes (for CoCo VMs)" + depends on KVM_SW_PROTECTED_VM || KVM_INTEL_TDX || KVM_AMD_SEV + help + Enable support for tracking PRIVATE vs. SHARED memory using per-VM + memory attributes. Using per-VM attributes is deprecated in favor of + tracking PRIVATE state in guest_memfd. Select this if you need to run + CoCo VMs using a VMM that doesn't support guest_memfd memory + attributes. + + If unsure, say N. =20 config KVM_SW_PROTECTED_VM bool "Enable support for KVM software-protected VMs" depends on EXPERT depends on KVM_X86 && X86_64 - select KVM_VM_MEMORY_ATTRIBUTES help Enable support for KVM software-protected VMs. Currently, software- protected VMs are purely a development and testing vehicle for @@ -138,7 +146,6 @@ config KVM_INTEL_TDX bool "Intel Trust Domain Extensions (TDX) support" default y depends on INTEL_TDX_HOST - select KVM_VM_MEMORY_ATTRIBUTES select HAVE_KVM_ARCH_GMEM_POPULATE help Provides support for launching Intel Trust Domain Extensions (TDX) @@ -162,7 +169,6 @@ config KVM_AMD_SEV depends on KVM_AMD && X86_64 depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=3Dy && CRYPTO_DEV_CCP_DD=3Dm) select ARCH_HAS_CC_PLATFORM - select KVM_VM_MEMORY_ATTRIBUTES select HAVE_KVM_ARCH_GMEM_CONVERT select HAVE_KVM_ARCH_GMEM_RECLAIM select HAVE_KVM_ARCH_GMEM_INVALIDATE diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c8faf1cb82167..85dfc3f5af805 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -103,7 +103,10 @@ static bool __ro_after_init allow_unsafe_mappings; module_param(allow_unsafe_mappings, bool, 0444); =20 #ifdef kvm_arch_has_private_mem -bool __ro_after_init gmem_in_place_conversion =3D false; +bool __ro_after_init gmem_in_place_conversion =3D !IS_ENABLED(CONFIG_KVM_V= M_MEMORY_ATTRIBUTES); +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES +module_param(gmem_in_place_conversion, bool, 0444); +#endif EXPORT_SYMBOL_FOR_KVM_INTERNAL(gmem_in_place_conversion); #endif =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4112847606D; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=EAbL0WqWpI6RUGnqPbphELzjEsl54OVVpFFlt59Hd9Vx+sOMzELmuas7T/zjXQk90PW0fEq01gfIKOTpeWD8p6BUHYxAdfZ1byPu8W+2X+KbYd8e2mW9/Oz2b00LPNvUHXeSZVKdikcsp4AGOiCR8q2gCiXHiRRsOy/15JVOdcY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=FoI3ZMvAwFhi7kaXsVeKkdELz832DofYJBPVRl9mtgo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TRo9TxU9QPPUTLcWYQmspyxYvZ/UGkSB3h+j+18Eh59dVC5Jg8Vle5t/5+Cam5UIpp5vxhE2/IVD10BGy6H3xlOT95zXMvUOHJNn1anfIDPWz/oCxj9eFI0r1JpM+JtiOtpb3w8MIdS2lufqnKKVuN9c+zOWxfTmaqquimlC1ic= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MZ12nlj4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MZ12nlj4" Received: by smtp.kernel.org (Postfix) with ESMTPS id DC1DAC2BCF7; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139569; bh=FoI3ZMvAwFhi7kaXsVeKkdELz832DofYJBPVRl9mtgo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=MZ12nlj4zg6jc33zJXDKBEAaD/2iRklHNAS3yqR77/cY7X3ZJKAcrJ58VSIp7lhGu ACCJy4wxgey6mcl1O1bfQezwlRgXCE9weYeGS1Bxn5M/OSPMvj/Je7PmCQNt7iGrDE S5hmlbXeV/ypmRrGSir13wZ+hn+H/TNo/ffnLg8fsX7v2CJDSOY9uwYskZzfRq/e4e JNyfbgPDjLv2fI83BbyS0+oKR6WkdWJ9A3yES7p7vG3wELaD/VDZMou/U8gsYdtxHC BK40gZGMnLuCMYH2q9rrdO0a6QC7TIsM+y2Qf6UxXhX98fpJ433AmOOKhmgaZBjtop qqA644ZGh4obA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7290C5ACD4; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:00 -0700 Subject: [PATCH v10 21/41] KVM: guest_memfd: Enable INIT_SHARED on guest_memfd for x86 Coco VMs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-21-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng , Xiaoyao Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=1641; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=5c5dIhQl3iWs3iceAiL8YJI/msPrnkAFg0lQ3bgVOW4=; b=UFZH2wM8ekLm4JtT1xYICDEeZuWmO10XkYOEwLNUAayGVaTkOQFrtplSWoHHOIzAaNHX6v238 KUC3rk4iwceAAxaAu6Ixrfp57qOfaUHTUgYifWYSAeKfD3DcUx7Bej/ X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Now that guest_memfd supports tracking private vs. shared within gmem itself, allow userspace to specify INIT_SHARED on a guest_memfd instance for x86 Confidential Computing (CoCo) VMs, so long as in-place conversion is enabled, i.e. when it's actually possible for a guest_memfd instance to contain shared memory. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Reviewed-by: Xiaoyao Li Tested-by: Shivank Garg Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu --- arch/x86/kvm/x86.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 39968610868fd..1ac60628b4c07 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10631,14 +10631,15 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu) } =20 #ifdef CONFIG_KVM_GUEST_MEMFD -/* - * KVM doesn't yet support initializing guest_memfd memory as shared for V= Ms - * with private memory (the private vs. shared tracking needs to be moved = into - * guest_memfd). - */ bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm) { - return !kvm_arch_has_private_mem(kvm); + /* + * INIT_SHARED is supported if in-place conversion is enabled, or if + * the VM doesn't support private memory. If the VM has private memory + * and in-place conversion is disabled, then guest_memfd can _only_ be + * used for private memory. + */ + return gmem_in_place_conversion || !kvm_arch_has_private_mem(kvm); } =20 #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 241AE4749F0; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=VM+8HUZvh5iwpwfCEClKCx8IkAtktJ2cmWAySeqHcLeKMtnGY0M5dcBZ0LApAIKCpEzVEN6spLV6lVPjdvWK6Epq1S2v0JRQQLSO/mee9wZSIwMG46ZKw6rYKj4sp7MlyFhpvJekNhqya7UtY47bURiE8G4Db9l6hiw6O1G0yow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=syEENkuW3iSW160gl7W1np8DdrGUT2InzYCZ2ecLpOM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uzx5OHCArWdz/tZIkoERMxAY6AS0WVMNZpr71oJDR29zQCdE0Tj+sy0VAYeKzz46z2hELJ8fAjlb6evLXfCCGE9TyAZ0QmgHwna1hpo8895nfqlf9qnkolr3uGpMyJUFGrxzjzkYC669polIBM+/wphY/WYP5KVBLKwQVxg20cg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tOJHYc5X; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tOJHYc5X" Received: by smtp.kernel.org (Postfix) with ESMTPS id F0FB5C2BCFD; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=syEENkuW3iSW160gl7W1np8DdrGUT2InzYCZ2ecLpOM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=tOJHYc5X4n/TSzHqCk60Fb7d1GfAxXCnqBGFYqazVZlKKEPJ9NuHMlhRUF5eXEfUV t1IQZkf9LW0E/z0Z+m3xFsqdS9GtsZQPGvKFHJRFK9BJxd/bbV57W5qV1r3BNwRMoX APD/dSQ8SBp097SKEiMM1A4mXXNter8ELlCHuQqBGOEUQRC0dTr9vsTMDeDNEtIr/Y +jWYJ4hcxQqsYwgH82BOQCapzlCo5XxUG55m533B5Lf1CGSIM3w20JdxSkwe1sL+lU FdOoFhxB52PK1H1iF39eMGPbfE+z5J2vvWqfy6kP+XuKEfOCxso0manlYNQhZZTfY5 Gy9fzZk3IMTEg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC981C5ACD3; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:01 -0700 Subject: [PATCH v10 22/41] KVM: selftests: Create gmem fd before "regular" fd when adding memslot Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-22-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2911; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=isrJvdvrZ/oXl43dBOcqzIaHXdNt/p+tOPS/6/JN0AQ=; b=EgmC8r1wDG2Mg1pWS7R67+sXU4hwHxL7nwb0aPuNPQXugJEXydz3W4gv1xyzzQ9Wz3WFfCLnE RslWm69T9YDDAiOKHi7jBRek2eO2gtL/UQvO3WEr4mMgsCcw/dAnEkT X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson When adding a memslot associated a guest_memfd instance, create/dup the guest_memfd before creating the "normal" backing file. This will allow dup'ing the gmem fd as the normal fd when guest_memfd supports mmap(), i.e. to make guest_memfd the _only_ backing source for the memslot. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/lib/kvm_util.c | 45 +++++++++++++++-----------= ---- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 9ddc047d5c275..3413d45e34faf 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1077,6 +1077,29 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backi= ng_src_type src_type, if (alignment > 1) region->mmap_size +=3D alignment; =20 + if (flags & KVM_MEM_GUEST_MEMFD) { + if (guest_memfd < 0) { + u32 guest_memfd_flags =3D 0; + + TEST_ASSERT(!guest_memfd_offset, + "Offset must be zero when creating new guest_memfd"); + guest_memfd =3D vm_create_guest_memfd(vm, mem_size, guest_memfd_flags); + } else { + /* + * Install a unique fd for each memslot so that the fd + * can be closed when the region is deleted without + * needing to track if the fd is owned by the framework + * or by the caller. + */ + guest_memfd =3D kvm_dup(guest_memfd); + } + + region->region.guest_memfd =3D guest_memfd; + region->region.guest_memfd_offset =3D guest_memfd_offset; + } else { + region->region.guest_memfd =3D -1; + } + region->fd =3D -1; if (backing_src_is_shared(src_type)) region->fd =3D kvm_memfd_alloc(region->mmap_size, @@ -1106,28 +1129,6 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backi= ng_src_type src_type, =20 region->backing_src_type =3D src_type; =20 - if (flags & KVM_MEM_GUEST_MEMFD) { - if (guest_memfd < 0) { - u32 guest_memfd_flags =3D 0; - TEST_ASSERT(!guest_memfd_offset, - "Offset must be zero when creating new guest_memfd"); - guest_memfd =3D vm_create_guest_memfd(vm, mem_size, guest_memfd_flags); - } else { - /* - * Install a unique fd for each memslot so that the fd - * can be closed when the region is deleted without - * needing to track if the fd is owned by the framework - * or by the caller. - */ - guest_memfd =3D kvm_dup(guest_memfd); - } - - region->region.guest_memfd =3D guest_memfd; - region->region.guest_memfd_offset =3D guest_memfd_offset; - } else { - region->region.guest_memfd =3D -1; - } - region->unused_phy_pages =3D sparsebit_alloc(); if (vm_arch_has_protected_memory(vm)) region->protected_phy_pages =3D sparsebit_alloc(); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 302874756C0; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=SV3M05Wo0g1Of8dhbeylCR4QLZcaiP5yiF6G6ICvSM3EMv8DlfEVEUYztEcXQEHUNxCnXXBL6C8YbDVewa9cNVaI138hn13vbJtjiCrktixNRAH6JdpfzROfFFdaZhL+psLAH3T59JzOkkPszm8uycaqdECf7HC0Cs4KCMRyJ2I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=jdgmdee0VIp5GU6o2Un+L0cHI9liYASYll25N6JKH44=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jECFJYPtpcjqVV50cOf13aZ/euEyq3v7iY6x+UuZufz5WP81EHmXJ6qspoqJPeI9xJHyRHEUBGcGzz6HJemssUucXmGagQdGFoGXo30VZJ7ksZwqJBpljenQO2ml3uZdZv5vgZ/jYEf+GX9Elq83i/mwtCBGSBLap8IQds0JY/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZjfO6Sm6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZjfO6Sm6" Received: by smtp.kernel.org (Postfix) with ESMTPS id 147C9C19425; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=jdgmdee0VIp5GU6o2Un+L0cHI9liYASYll25N6JKH44=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ZjfO6Sm62xmwgnMxJc9ejWzS/caZOJeV+132pYA3GfVVdepLWPptuSsaN6fcGKTBN nnudRyYxogtekJe0cKk7oDD+geO0c+doTo6c7OMuwdhL9WDcPmiQm71j+gDr2bzhSr c1Phcyi/Z2pj21TXFm/2R45BtxYQhS7WHsio33O66Asn/meX4+myC8pG7seQVrOH90 N8anA2qyZokMM3yG/BU49sLy5EcdN5HQwD2TVGu4tzcu69MwOneix51pqSl6QL4sqS 1wxwfLrkXu9P/sw16QoVBnQU4L/zvYHZnWpEq503Nyjd3BPIU9BcYrtq6RE53i4TIu cxMRVlSlhaduA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F22B6C5ACD8; Fri, 7 Aug 2026 21:52:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:02 -0700 Subject: [PATCH v10 23/41] KVM: selftests: Rename guest_memfd{,_offset} to gmem_{fd,offset} Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-23-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5047; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=5HKry2PgG3dtuPHsW375sKL/s/MS4E47nwDAYuxF7d0=; b=3Ma1ku5Wd0XPmXUwV09jwFygGRy+GJxC5HBm9OjlCWajYL8bU7jpGRlKWEAc9YOqUyw7oWIH5 6/JlcB0W/bOAQpHQsgT7Uq5eJjRU8MXE6ZOfKd6mlAC3pjGLLLDtOBX X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Rename local variables and function parameters for the guest memory file descriptor and its offset to use a "gmem_" prefix instead of "guest_memfd_". No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 6 +++--- tools/testing/selftests/kvm/lib/kvm_util.c | 26 +++++++++++++---------= ---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 5a7a455b53875..cf49a84de02e8 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -690,17 +690,17 @@ int __vm_set_user_memory_region(struct kvm_vm *vm, u3= 2 slot, u32 flags, gpa_t gpa, u64 size, void *hva); void vm_set_user_memory_region2(struct kvm_vm *vm, u32 slot, u32 flags, gpa_t gpa, u64 size, void *hva, - u32 guest_memfd, u64 guest_memfd_offset); + u32 gmem_fd, u64 gmem_offset); int __vm_set_user_memory_region2(struct kvm_vm *vm, u32 slot, u32 flags, gpa_t gpa, u64 size, void *hva, - u32 guest_memfd, u64 guest_memfd_offset); + u32 gmem_fd, u64 gmem_offset); =20 void vm_userspace_mem_region_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags); void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags, - int guest_memfd_fd, u64 guest_memfd_offset); + int gmem_fd, u64 gmem_offset); =20 #ifndef vm_arch_has_protected_memory static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 3413d45e34faf..af501a27211a2 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -970,7 +970,7 @@ void vm_set_user_memory_region(struct kvm_vm *vm, u32 s= lot, u32 flags, =20 int __vm_set_user_memory_region2(struct kvm_vm *vm, u32 slot, u32 flags, gpa_t gpa, u64 size, void *hva, - u32 guest_memfd, u64 guest_memfd_offset) + u32 gmem_fd, u64 gmem_offset) { struct kvm_userspace_memory_region2 region =3D { .slot =3D slot, @@ -978,8 +978,8 @@ int __vm_set_user_memory_region2(struct kvm_vm *vm, u32= slot, u32 flags, .guest_phys_addr =3D gpa, .memory_size =3D size, .userspace_addr =3D (uintptr_t)hva, - .guest_memfd =3D guest_memfd, - .guest_memfd_offset =3D guest_memfd_offset, + .guest_memfd =3D gmem_fd, + .guest_memfd_offset =3D gmem_offset, }; =20 TEST_REQUIRE_SET_USER_MEMORY_REGION2(); @@ -989,10 +989,10 @@ int __vm_set_user_memory_region2(struct kvm_vm *vm, u= 32 slot, u32 flags, =20 void vm_set_user_memory_region2(struct kvm_vm *vm, u32 slot, u32 flags, gpa_t gpa, u64 size, void *hva, - u32 guest_memfd, u64 guest_memfd_offset) + u32 gmem_fd, u64 gmem_offset) { int ret =3D __vm_set_user_memory_region2(vm, slot, flags, gpa, size, hva, - guest_memfd, guest_memfd_offset); + gmem_fd, gmem_offset); =20 TEST_ASSERT(!ret, "KVM_SET_USER_MEMORY_REGION2 failed, errno =3D %d (%s)", errno, strerror(errno)); @@ -1002,7 +1002,7 @@ void vm_set_user_memory_region2(struct kvm_vm *vm, u3= 2 slot, u32 flags, /* FIXME: This thing needs to be ripped apart and rewritten. */ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags, - int guest_memfd, u64 guest_memfd_offset) + int gmem_fd, u64 gmem_offset) { int ret; struct userspace_mem_region *region; @@ -1078,12 +1078,12 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_back= ing_src_type src_type, region->mmap_size +=3D alignment; =20 if (flags & KVM_MEM_GUEST_MEMFD) { - if (guest_memfd < 0) { - u32 guest_memfd_flags =3D 0; + if (gmem_fd < 0) { + u32 gmem_flags =3D 0; =20 - TEST_ASSERT(!guest_memfd_offset, + TEST_ASSERT(!gmem_offset, "Offset must be zero when creating new guest_memfd"); - guest_memfd =3D vm_create_guest_memfd(vm, mem_size, guest_memfd_flags); + gmem_fd =3D vm_create_guest_memfd(vm, mem_size, gmem_flags); } else { /* * Install a unique fd for each memslot so that the fd @@ -1091,11 +1091,11 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_back= ing_src_type src_type, * needing to track if the fd is owned by the framework * or by the caller. */ - guest_memfd =3D kvm_dup(guest_memfd); + gmem_fd =3D kvm_dup(gmem_fd); } =20 - region->region.guest_memfd =3D guest_memfd; - region->region.guest_memfd_offset =3D guest_memfd_offset; + region->region.guest_memfd =3D gmem_fd; + region->region.guest_memfd_offset =3D gmem_offset; } else { region->region.guest_memfd =3D -1; } --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4255F47607C; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=Qe4ZmcixAiFhkxaezOwLGkR8A99x/LDjmdtXNpeNrk4VsiRStTYkICiqnmZh4GKEr9MXpmQb88Gk73D1RtT7BpW8tyhzg+Fq7US72wH7kkHaB39hQLSfvdhnjurcJa9nKBpU5eExtSheiy907XkvMCEZvQece1yxn+YoN7fzUdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=scg9tFUVSd7SioxMaW3R0EyEJbBVbgyzVXz5qhAsZL0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C9MtpZgYRiiMHWBFIHWNxnOfasOWx0Pu5BwJAJG2Yq8Y34vlTJUMObz4QvnN1uqjkK2Cmn5l947cW7eNolD2mh5WNtBJqkab3ymdmnHcJ6aU4g9k2cIi0t4wxK/p/bPKoBEESamC8UMf1n0F5CGQiuzi3erklACKDAbGw435VdI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=U3Z4g/kJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="U3Z4g/kJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 28176C2BCFC; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=scg9tFUVSd7SioxMaW3R0EyEJbBVbgyzVXz5qhAsZL0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=U3Z4g/kJ1DES/1AaEOyc4cRmWss29QuR8bSwGQbuUX6DeGuTAm+aW/iXoSwUXSpr8 6XZrj3IxV/BNPb0Grrbf4SA251JvMGyJ8B746thg+8IlmcXFlBjFH0Gai8ekc3mNp1 pXo4YmBU3BddsOBaxiWuyr6/rcM9eRAezg5X6iraqEJUQt8cy48k5mvzPz2B5VUmql dz0BT9Oo3V/6XpZWwaOrENlyyzZE8znxTDg+ZIB3/16dHze4pW3p4c9y7n+h8R3E/U 7T71Q19apYO7r49lYkefb+ALLEmKnl2rgv3+u3HTXIgZFtOEFbAkSzgCKjpRwJuvzx sN5UE8jVeszNQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 142D9C5ACDC; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:03 -0700 Subject: [PATCH v10 24/41] KVM: selftests: Add support for mmap() on guest_memfd in core library Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-24-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=6306; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=VBHp/vdMcryEsIZeiWdhhlAw8HGf34l+/e03cVZO2Ek=; b=psXIjFcRaJxdQlWPBmTS90CFkZKsrqIoQuJRSJawiu+/3XoHQaJEwz4gu9S1o5QxuRNjilZrI 2QgaoUilsPOB5AJWlU+WleDpQ3usnY5iYYHYrpqHONe10as+jgd90F4 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Accept gmem_flags in vm_mem_add() to be able to create a guest_memfd within vm_mem_add(). When vm_mem_add() is used to set up a guest_memfd for a memslot, set up the provided (or created) gmem_fd as the fd for the user memory region. This makes it available to be mmap()-ed from just like fds from other memory sources. For guest_memfds, mmap() using gmem_offset instead of 0 all the time. Always use MAP_SHARED if mmap-ing from guest_memfd instead of reading flag from the configured src_type, which doesn't include guest_memfd. Add a kvm_slot_to_fd() helper to provide convenient access to the file descriptor of a memslot. Update existing callers of vm_mem_add() to pass 0 for gmem_flags to preserve existing behavior. Signed-off-by: Sean Christopherson [mmap() with gmem_offset, and always with MAP_SHARED.] Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 7 +++++- tools/testing/selftests/kvm/lib/kvm_util.c | 28 ++++++++++++------= ---- .../kvm/x86/private_mem_conversions_test.c | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index cf49a84de02e8..a091c495442a1 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -700,7 +700,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, gpa_t gpa, u32 slot, u64 npages, u32 flags); void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags, - int gmem_fd, u64 gmem_offset); + int gmem_fd, u64 gmem_offset, u64 gmem_flags); =20 #ifndef vm_arch_has_protected_memory static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm) @@ -732,6 +732,11 @@ void *addr_gva2hva(struct kvm_vm *vm, gva_t gva); gpa_t addr_hva2gpa(struct kvm_vm *vm, void *hva); void *addr_gpa2alias(struct kvm_vm *vm, gpa_t gpa); =20 +static inline int kvm_slot_to_fd(struct kvm_vm *vm, u32 slot) +{ + return memslot2region(vm, slot)->fd; +} + #ifndef vcpu_arch_put_guest #define vcpu_arch_put_guest(mem, val) do { (mem) =3D (val); } while (0) #endif diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index af501a27211a2..08d0bbcd421ea 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1002,12 +1002,14 @@ void vm_set_user_memory_region2(struct kvm_vm *vm, = u32 slot, u32 flags, /* FIXME: This thing needs to be ripped apart and rewritten. */ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags, - int gmem_fd, u64 gmem_offset) + int gmem_fd, u64 gmem_offset, u64 gmem_flags) { int ret; struct userspace_mem_region *region; size_t backing_src_pagesz =3D get_backing_src_pagesz(src_type); + int mmap_flags =3D vm_mem_backing_src_alias(src_type)->flag; size_t mem_size =3D npages * vm->page_size; + off_t mmap_offset =3D 0; size_t alignment =3D 1; =20 TEST_REQUIRE_SET_USER_MEMORY_REGION2(); @@ -1079,8 +1081,6 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backin= g_src_type src_type, =20 if (flags & KVM_MEM_GUEST_MEMFD) { if (gmem_fd < 0) { - u32 gmem_flags =3D 0; - TEST_ASSERT(!gmem_offset, "Offset must be zero when creating new guest_memfd"); gmem_fd =3D vm_create_guest_memfd(vm, mem_size, gmem_flags); @@ -1101,13 +1101,17 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_back= ing_src_type src_type, } =20 region->fd =3D -1; - if (backing_src_is_shared(src_type)) + if (flags & KVM_MEM_GUEST_MEMFD && gmem_flags & GUEST_MEMFD_FLAG_MMAP) { + region->fd =3D kvm_dup(gmem_fd); + mmap_flags =3D MAP_SHARED; + mmap_offset =3D gmem_offset; + } else if (backing_src_is_shared(src_type)) { region->fd =3D kvm_memfd_alloc(region->mmap_size, src_type =3D=3D VM_MEM_SRC_SHARED_HUGETLB); + } =20 - region->mmap_start =3D kvm_mmap(region->mmap_size, PROT_READ | PROT_WRITE, - vm_mem_backing_src_alias(src_type)->flag, - region->fd); + region->mmap_start =3D __kvm_mmap(region->mmap_size, PROT_READ | PROT_WRI= TE, + mmap_flags, region->fd, mmap_offset); =20 TEST_ASSERT(!is_backing_src_hugetlb(src_type) || region->mmap_start =3D=3D align_ptr_up(region->mmap_start, backing_s= rc_pagesz), @@ -1153,10 +1157,10 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_back= ing_src_type src_type, =20 /* If shared memory, create an alias. */ if (region->fd >=3D 0) { - region->mmap_alias =3D kvm_mmap(region->mmap_size, - PROT_READ | PROT_WRITE, - vm_mem_backing_src_alias(src_type)->flag, - region->fd); + region->mmap_alias =3D __kvm_mmap(region->mmap_size, + PROT_READ | PROT_WRITE, + mmap_flags, region->fd, + mmap_offset); =20 /* Align host alias address */ region->host_alias =3D align_ptr_up(region->mmap_alias, alignment); @@ -1167,7 +1171,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, gpa_t gpa, u32 slot, u64 npages, u32 flags) { - vm_mem_add(vm, src_type, gpa, slot, npages, flags, -1, 0); + vm_mem_add(vm, src_type, gpa, slot, npages, flags, -1, 0, 0); } =20 /* diff --git a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c= b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c index 3aa0673f79f33..f3de2a4ab0551 100644 --- a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c @@ -399,7 +399,7 @@ static void test_mem_conversions(enum vm_mem_backing_sr= c_type src_type, u32 nr_v for (i =3D 0; i < nr_memslots; i++) vm_mem_add(vm, src_type, BASE_DATA_GPA + slot_size * i, BASE_DATA_SLOT + i, slot_size / vm->page_size, - KVM_MEM_GUEST_MEMFD, memfd, slot_size * i); + KVM_MEM_GUEST_MEMFD, memfd, slot_size * i, 0); =20 for (i =3D 0; i < nr_vcpus; i++) { gpa_t gpa =3D BASE_DATA_GPA + i * per_cpu_size; --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 57509472782; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=HKmyoqer1zSo3r/rp0iuzfftqlzlhgj14hSo0jP5ckBIzr6s4bNwQZ8nOMYdKloDo5IyNVs3Q5NRgq7/DJLlphwRZe8dItu+XZi9m68/44kkCVidIgDsJyLeXA5leLHVPQNC8tbdilF+GUeVyzJHZVOey50PLn2VfgY1jm0cAjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=C5CVQyQCx6nCpVtedkg6HikJiLO1rkwgWitCM8srGsY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GpjfLraFyHmp+sD04hsYDKStdpCEZSRdlGFbmwBnBFReEjwfmx1yBQ9r3eSyMV0hdj7/0hN9LbKhZsMpHIj0BeLUQ3asAsUZINFQv9FWMutr/Sjl+NiIVyqpQXlL1mnzxulFHRxr7k3xJ8nlDKOOHzMerw+uX+5rqKj1s3V4VAU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fEvezCsY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fEvezCsY" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3D33BC2BD04; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=C5CVQyQCx6nCpVtedkg6HikJiLO1rkwgWitCM8srGsY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=fEvezCsYmyZOutO3WXtcxrr8CONdjwM67HmL91GoXn1HO85SvszGj1L9gQ8EF+wEZ d/Oi6N2VEb7Q3Po/iX2KeJQzIyqRJrTT3+2EPBXwNunKpTdUlrlzLQ0grDvMin3gy2 dMhSbclcQQj4qw6w2n31UIksGY4GRHpgUCksm7xApUEXEj8wRVBJpO9DCc5vEfKhf8 GnviTfbQcn7VFWH2/aEu4FMcy++InvFn1V26TgPf8FI2oekk2/Ky9IJRRcciarrpSY 4k/za8wiYXghgUrUmZdfRpGxAzfIfHFd/9qNQTghskNGdwZcjCqTPaE0W+9RHjKNgw o87z2WXavyYkg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A3ECC5ACD4; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:04 -0700 Subject: [PATCH v10 25/41] KVM: selftests: Add selftests global for guest memory attributes capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-25-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2380; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=3GsT3Q+uzPs3OFHloNtQiW2tkzSuSXtysLhAUwWt/P8=; b=I33/mpDT6f2dWZmUfYdILExsu+k524V3mzokxxFBxqlwcLsoItV2gj57r9VTM33XoZcVk7IL+ xFmO2by1pElB2bRcy5kRmrGwveZe/kWi/2LSvaPOnLbueytk2lcwrLi X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Add a global variable, kvm_has_gmem_attributes, to make the result of checking for KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES available to all tests. kvm_has_gmem_attributes is true if guest_memfd tracks memory attributes, as opposed to VM-level tracking. This global variable is synced to the guest for testing convenience, to avoid introducing subtle bugs when host/guest state is desynced. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/test_util.h | 2 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testin= g/selftests/kvm/include/test_util.h index a6a3e16578959..d5825211f2727 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -116,6 +116,8 @@ struct kvm_random_state { extern u32 kvm_random_seed; extern struct kvm_random_state kvm_rng; =20 +extern bool kvm_has_gmem_attributes; + struct kvm_random_state new_kvm_random_state(u32 seed); u32 kvm_random_u32(struct kvm_random_state *state); =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 08d0bbcd421ea..cd468b2bb8343 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -32,6 +32,8 @@ static void kvm_seed_rng(u32 seed) kvm_rng =3D new_kvm_random_state(kvm_random_seed); } =20 +bool kvm_has_gmem_attributes; + static size_t vcpu_mmap_sz(void); =20 int __open_path_or_exit(const char *path, int flags, const char *enoent_he= lp) @@ -527,6 +529,7 @@ struct kvm_vm *__vm_create(struct vm_shape shape, u32 n= r_runnable_vcpus, kvm_seed_rng(kvm_random_seed); =20 sync_global_to_guest(vm, kvm_rng); + sync_global_to_guest(vm, kvm_has_gmem_attributes); =20 kvm_arch_vm_post_create(vm, nr_runnable_vcpus); =20 @@ -2311,6 +2314,8 @@ void __attribute((constructor)) kvm_selftest_init(voi= d) srandom(time(0)); kvm_seed_rng(random()); =20 + kvm_has_gmem_attributes =3D kvm_has_cap(KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIB= UTES); + kvm_selftest_arch_init(); } =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7174D477294; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=ce8QOXuQ5Hq3kkXBgBbIcxe69ZMRukkLa4HmmHngAAV8u/zy4ojKsfo0difPLNtAUr+f9sPvS+bbEvgjq37mPCcbpHq9L1+J1T75kTQQwTAAdb1B4QvloIL/WTjweDcnEAwNvsWlGzUldwav5O2JV+d1uEUy7oViHSFASnS970k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=An4LoFfCbfkYxKMIjD8JecRW0dhBJE2uKbwzXFHa1d8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BfeChF9A65mfqDtb7pZc1WCuc2TbiMKG4OkwGv+njbDREJU1nhHvbZ96/usRj4YA4WPbaHL0NS20DdIaP+lFfFEKoMYpsqrLhourrytoN3htcpf1ADcmVOZ4NUHroteC+U2yW4X1v0ovzyN2mrDrB2vIEM5H5ZuExt5Q4xkQ4DA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=byQXBm9C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="byQXBm9C" Received: by smtp.kernel.org (Postfix) with ESMTPS id 582D7C19425; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=An4LoFfCbfkYxKMIjD8JecRW0dhBJE2uKbwzXFHa1d8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=byQXBm9Cp6SfRJKQQFLpngbooXY0gH9fn5S7Fnp9O7w+lkiNB4RC2R0i1S7xmUT7o vnDq8WBqmbBTFt0qTHuJzko2TO2buKIvB+uKgGXAnLs9EEEMxVeQH7rPjuvfp/bK3B fotVUr2pyldGx8bCFLz49dXAjCQpg6eUDjPFBu9vA4gmbZIN6Q8TWgGsFKi1ydfkjG 0mmoMGjW9W8nd6LW2p0VqoWMKy6fMtuu+Uz8JignkWvCPL7iC7UYS4h2sOAPfU59wM U3L432szzaTGgs0QrggBQBZPyhZHUQqFoOzfVfTLfVla+XSx05zC3WO1yiidOhi60R s/Cmb+QkTUddg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 401FFC5ACD3; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:05 -0700 Subject: [PATCH v10 26/41] KVM: selftests: Add helpers for calling ioctls on guest_memfd Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-26-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5371; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=8UvBMuLdULVikAkOmOgNwZEpUmR3XOSiX8ZbtcAA7h8=; b=id25AOQXYxAU2fhUjboBx62DxhKQXAQhUqYPjkGYJ1lwXkIzB/jvotUmYQOqQKMcvazqhW/y0 NAlz2QlNDI6CSuUTnGjy3NDs9O45/NCcRJiIRR/Fhqh+bcOCvdhIi4a X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Add helper functions to kvm_util.h to support calling ioctls, specifically KVM_SET_MEMORY_ATTRIBUTES2, on a guest_memfd file descriptor. Introduce gmem_ioctl() and __gmem_ioctl() macros, modeled after the existing vm_ioctl() helpers, to provide a standard way to call ioctls on a guest_memfd. Add gmem_set_memory_attributes() and its derivatives (gmem_set_private(), gmem_set_shared()) to set memory attributes on a guest_memfd region. Also provide "__" variants that return the ioctl error code instead of aborting the test. These helpers will be used by upcoming guest_memfd tests. To avoid code duplication, factor out the check for supported memory attributes into a new macro, TEST_ASSERT_SUPPORTED_ATTRIBUTES, and use it in both the existing vm_set_memory_attributes() and the new gmem_set_memory_attributes() helpers. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 94 ++++++++++++++++++++++= +--- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index a091c495442a1..575032e9791d2 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -392,6 +392,16 @@ static __always_inline void static_assert_is_vcpu(stru= ct kvm_vcpu *vcpu) { } __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (vcpu)->vm); \ }) =20 +#define __gmem_ioctl(gmem_fd, cmd, arg) \ + kvm_do_ioctl(gmem_fd, cmd, arg) + +#define gmem_ioctl(gmem_fd, cmd, arg) \ +({ \ + int ret =3D __gmem_ioctl(gmem_fd, cmd, arg); \ + \ + TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(#cmd, ret)); \ +}) + /* * Looks up and returns the value corresponding to the capability * (KVM_CAP_*) given by cap. @@ -418,8 +428,16 @@ static inline void vm_enable_cap(struct kvm_vm *vm, u3= 2 cap, u64 arg0) vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); } =20 +/* + * KVM_SET_MEMORY_ATTRIBUTES{,2} overwrites _all_ attributes. These + * flows need significant enhancements to support multiple attributes. + */ +#define TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes) \ + TEST_ASSERT(!(attributes) || (attributes) =3D=3D KVM_MEMORY_ATTRIBUTE_PRI= VATE, \ + "Update me to support multiple attributes!") + static inline void vm_set_memory_attributes(struct kvm_vm *vm, gpa_t gpa, - u64 size, u64 attributes) + size_t size, u64 attributes) { struct kvm_memory_attributes attr =3D { .attributes =3D attributes, @@ -428,17 +446,11 @@ static inline void vm_set_memory_attributes(struct kv= m_vm *vm, gpa_t gpa, .flags =3D 0, }; =20 - /* - * KVM_SET_MEMORY_ATTRIBUTES overwrites _all_ attributes. These flows - * need significant enhancements to support multiple attributes. - */ - TEST_ASSERT(!attributes || attributes =3D=3D KVM_MEMORY_ATTRIBUTE_PRIVATE, - "Update me to support multiple attributes!"); + TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes); =20 vm_ioctl(vm, KVM_SET_MEMORY_ATTRIBUTES, &attr); } =20 - static inline void vm_mem_set_private(struct kvm_vm *vm, gpa_t gpa, u64 size) { @@ -451,6 +463,72 @@ static inline void vm_mem_set_shared(struct kvm_vm *vm= , gpa_t gpa, vm_set_memory_attributes(vm, gpa, size, 0); } =20 +static inline int __gmem_set_memory_attributes(int fd, u64 offset, + size_t size, u64 attributes, + u64 *error_offset) +{ + struct kvm_memory_attributes2 attr =3D { + .attributes =3D attributes, + .offset =3D offset, + .size =3D size, + .flags =3D 0, + .error_offset =3D 0, + }; + int r; + + r =3D __gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr); + + /* Copy error_offset regardless of r so caller can check. */ + if (error_offset) + *error_offset =3D attr.error_offset; + + return r; +} + +static inline int __gmem_set_private(int fd, u64 offset, size_t size, + u64 *error_offset) +{ + return __gmem_set_memory_attributes(fd, offset, size, + KVM_MEMORY_ATTRIBUTE_PRIVATE, + error_offset); +} + +static inline int __gmem_set_shared(int fd, u64 offset, size_t size, + u64 *error_offset) +{ + return __gmem_set_memory_attributes(fd, offset, size, 0, + error_offset); +} + +static inline void gmem_set_memory_attributes(int fd, u64 offset, + size_t size, u64 attributes) +{ + struct kvm_memory_attributes2 attr =3D { + .attributes =3D attributes, + .offset =3D offset, + .size =3D size, + .flags =3D 0, + }; + + TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes); + + __TEST_REQUIRE(kvm_check_cap(KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES) > 0, + "No valid attributes for guest_memfd ioctl!"); + + gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr); +} + +static inline void gmem_set_private(int fd, u64 offset, size_t size) +{ + gmem_set_memory_attributes(fd, offset, size, + KVM_MEMORY_ATTRIBUTE_PRIVATE); +} + +static inline void gmem_set_shared(int fd, u64 offset, size_t size) +{ + gmem_set_memory_attributes(fd, offset, size, 0); +} + void vm_guest_mem_fallocate(struct kvm_vm *vm, gpa_t gpa, u64 size, bool punch_hole); =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8D0F747884E; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=QhIVsz+lPjFOP5JtPGWUx6QgZD2wn9FjRRKs0YwIKV3qAfrF4A1KMKaHG18hiVOOOolA2nCBJPpxUyDxS97JH0X8bdNQYIkxMhIzPjVAsdRonI1rSPX4qPK7fnOd0Dk6qiK75dzG98C9cWRCTqnJZ6ErgEuMELlC9vJ79TZbhjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=rJhUYCuZkomqLg/f3nm1Ab0nssnx4ZZWmryG5s8NUPI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CnHY2KwxgYE45GTMaOjWz/MWbgjK+TXoyRSFnGSEpsUWzyzmZR4hRcsTJZCR/VXueriv8Kt4M9FKVRvgDyxfFgrwHCmFF3r2h09etJ44h01cjq4/XsAWlpdz3A6fdcbA7p5N1+9QpAlg0wx2JwVt89KSAuVH+ckBBlKljxuLRzo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bMRuzehk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bMRuzehk" Received: by smtp.kernel.org (Postfix) with ESMTPS id 727AEC2BCF7; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=rJhUYCuZkomqLg/f3nm1Ab0nssnx4ZZWmryG5s8NUPI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=bMRuzehkqPUCCDnyO7M7FESAfG1s5L0To9jFnaN+EifP6TnTyw5k4MmcMl01VP02N KHuAStyn2YGXR8Yg9G+q1FkP98rqzGGhtl0An+sOsyMJHCCJOQUlnCcLhA2KLsFlFI wMfhlLulfYdiohLG0Gol6wPnZ/ZViXd726X178rcOAJubv0uGBJZyDWjb1nRaXEHbK xjs4rPZ+Eagi3DWO5UBgGqps2QRLSC7pBW3v1q+W/x7wCqFT1g/sVwY4B1Ku0ip/y1 q6qpd+aAKuIetFMXUsyd5FqH+qdVJw5VxjeoEKu7jHNFuzQG0ckiieYd7kchqfQE6X /mIcay0rY+c/A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CC98C5ACD4; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:06 -0700 Subject: [PATCH v10 27/41] KVM: selftests: Test basic single-page conversion flow Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-27-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=7821; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=/ioEF4WAcrdUq/WVZjNnIPnEDGY6AwstSZrVFbO6vLk=; b=M1nY/sD/bB5GfnRwV2WI6PXt8Abaqa6MH4yAUZgEW6aRSY4lPirunpO94zq6lzDGngmyZbAEm bMYZ6LJQc9VBtJkjkjcGwFuKKt1aYdJBkAPfEr5jFXMwCA/CE3BbGe/ X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a selftest for the guest_memfd memory attribute conversion ioctls. The test starts the guest_memfd as all-private (the default state), and verifies the basic flow of converting a single page to shared and then back to private. Add infrastructure that supports extensions to other conversion flow tests. This infrastructure will be used in upcoming patches for other conversion tests. Add test as an x86-specific test since guest_memfd's testing vehicle (KVM_X86_SW_PROTECTED_VM) is x86-specific. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- v10: Updated __GMEM_CONVERSION_TEST macro to avoid potential macro argument reuse --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../kvm/x86/guest_memfd_conversions_test.c | 200 +++++++++++++++++= ++++ 2 files changed, 201 insertions(+) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 00123169a190a..049306cf0bb7a 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -155,6 +155,7 @@ TEST_GEN_PROGS_x86 +=3D x86/max_vcpuid_cap_test TEST_GEN_PROGS_x86 +=3D x86/triple_fault_event_test TEST_GEN_PROGS_x86 +=3D x86/recalc_apic_map_test TEST_GEN_PROGS_x86 +=3D x86/aperfmperf_test +TEST_GEN_PROGS_x86 +=3D x86/guest_memfd_conversions_test TEST_GEN_PROGS_x86 +=3D access_tracking_perf_test TEST_GEN_PROGS_x86 +=3D coalesced_io_test TEST_GEN_PROGS_x86 +=3D dirty_log_perf_test diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c new file mode 100644 index 0000000000000..77f95d49349ce --- /dev/null +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Google LLC. + */ +#include +#include + +#include +#include +#include + +#include "kvm_util.h" +#include "kselftest_harness.h" +#include "test_util.h" +#include "ucall_common.h" + +FIXTURE(gmem_conversions) { + struct kvm_vcpu *vcpu; + int gmem_fd; + /* HVA of the first byte of the memory mmap()-ed from gmem_fd. */ + char *mem; +}; + +typedef FIXTURE_DATA(gmem_conversions) test_data_t; + +FIXTURE_SETUP(gmem_conversions) { } + +static size_t page_size; + +static void guest_do_rmw(void); +#define GUEST_MEMFD_SHARING_TEST_GVA 0x90000000ULL + +/* + * Defer setup until the individual test is invoked so that tests can spec= ify + * the number of pages and flags for the guest_memfd instance. + */ +static void gmem_conversions_do_setup(test_data_t *t, int nr_pages, + int gmem_flags) +{ + const struct vm_shape shape =3D { + .mode =3D VM_MODE_DEFAULT, + .type =3D KVM_X86_SW_PROTECTED_VM, + }; + /* + * Use high GPA above APIC_DEFAULT_PHYS_BASE to avoid clashing with + * APIC_DEFAULT_PHYS_BASE. + */ + const gpa_t gpa =3D SZ_4G; + const u32 slot =3D 1; + struct kvm_vm *vm; + + vm =3D __vm_create_shape_with_one_vcpu(shape, &t->vcpu, nr_pages, guest_d= o_rmw); + + vm_mem_add(vm, VM_MEM_SRC_SHMEM, gpa, slot, nr_pages, + KVM_MEM_GUEST_MEMFD, -1, 0, gmem_flags); + + t->gmem_fd =3D kvm_slot_to_fd(vm, slot); + t->mem =3D addr_gpa2hva(vm, gpa); + virt_map(vm, GUEST_MEMFD_SHARING_TEST_GVA, gpa, nr_pages); +} + +static void gmem_conversions_do_teardown(test_data_t *t) +{ + /* No need to close gmem_fd, it's owned by the VM structure. */ + kvm_vm_free(t->vcpu->vm); +} + +FIXTURE_TEARDOWN(gmem_conversions) +{ + gmem_conversions_do_teardown(self); +} + +/* + * In these test definition macros, __nr_pages and nr_pages is used to set= up + * the total number of pages in the guest_memfd under test. This will be + * available in the test definitions as nr_pages. + */ + +#define __GMEM_CONVERSION_TEST(test, __nr_pages, flags) \ +static void __gmem_conversions_##test(test_data_t *t, int nr_pages); \ + \ +TEST_F(gmem_conversions, test) \ +{ \ + const int nr =3D (__nr_pages); \ + \ + gmem_conversions_do_setup(self, nr, flags); \ + __gmem_conversions_##test(self, nr); \ +} \ +static void __gmem_conversions_##test(test_data_t *t, int nr_pages) \ + +#define GMEM_CONVERSION_TEST(test, __nr_pages, flags) \ + __GMEM_CONVERSION_TEST(test, __nr_pages, (flags) | GUEST_MEMFD_FLAG_MMAP) + +#define __GMEM_CONVERSION_TEST_INIT_PRIVATE(test, __nr_pages) \ + GMEM_CONVERSION_TEST(test, __nr_pages, 0) + +#define GMEM_CONVERSION_TEST_INIT_PRIVATE(test) \ + __GMEM_CONVERSION_TEST_INIT_PRIVATE(test, 1) + +struct guest_check_data { + void *mem; + char expected_val; + char write_val; +}; +static struct guest_check_data guest_data; + +static void guest_do_rmw(void) +{ + for (;;) { + char *mem =3D READ_ONCE(guest_data.mem); + + GUEST_ASSERT_EQ(READ_ONCE(*mem), READ_ONCE(guest_data.expected_val)); + WRITE_ONCE(*mem, READ_ONCE(guest_data.write_val)); + + GUEST_SYNC(0); + } +} + +static void run_guest_do_rmw(struct kvm_vcpu *vcpu, u64 pgoff, + char expected_val, char write_val) +{ + struct ucall uc; + int r; + + guest_data.mem =3D (void *)GUEST_MEMFD_SHARING_TEST_GVA + pgoff * page_si= ze; + guest_data.expected_val =3D expected_val; + guest_data.write_val =3D write_val; + sync_global_to_guest(vcpu->vm, guest_data); + + do { + r =3D __vcpu_run(vcpu); + } while (r =3D=3D -1 && errno =3D=3D EINTR); + + TEST_ASSERT_EQ(r, 0); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + case UCALL_SYNC: + break; + default: + TEST_FAIL("Unexpected ucall %lu", uc.cmd); + } +} + +static void host_do_rmw(char *mem, u64 pgoff, char expected_val, + char write_val) +{ + TEST_ASSERT_EQ(READ_ONCE(mem[pgoff * page_size]), expected_val); + WRITE_ONCE(mem[pgoff * page_size], write_val); +} + +static void test_private(test_data_t *t, u64 pgoff, char starting_val, + char write_val) +{ + TEST_EXPECT_SIGBUS(WRITE_ONCE(t->mem[pgoff * page_size], write_val)); + run_guest_do_rmw(t->vcpu, pgoff, starting_val, write_val); + TEST_EXPECT_SIGBUS(READ_ONCE(t->mem[pgoff * page_size])); +} + +static void test_convert_to_private(test_data_t *t, u64 pgoff, + char starting_val, char write_val) +{ + gmem_set_private(t->gmem_fd, pgoff * page_size, page_size); + test_private(t, pgoff, starting_val, write_val); +} + +static void test_shared(test_data_t *t, u64 pgoff, char starting_val, + char host_write_val, char write_val) +{ + host_do_rmw(t->mem, pgoff, starting_val, host_write_val); + run_guest_do_rmw(t->vcpu, pgoff, host_write_val, write_val); + TEST_ASSERT_EQ(READ_ONCE(t->mem[pgoff * page_size]), write_val); +} + +static void test_convert_to_shared(test_data_t *t, u64 pgoff, + char starting_val, char host_write_val, + char write_val) +{ + gmem_set_shared(t->gmem_fd, pgoff * page_size, page_size); + test_shared(t, pgoff, starting_val, host_write_val, write_val); +} + +GMEM_CONVERSION_TEST_INIT_PRIVATE(init_private) +{ + test_private(t, 0, 0, 'A'); + test_convert_to_shared(t, 0, 'A', 'B', 'C'); + test_convert_to_private(t, 0, 'C', 'E'); +} + +int main(int argc, char *argv[]) +{ + TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); + TEST_REQUIRE(kvm_check_cap(KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES) & + KVM_MEMORY_ATTRIBUTE_PRIVATE); + + page_size =3D getpagesize(); + + return test_harness_run(argc, argv); +} --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A60844749DF; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=NEVLmvlvthXn64ma8teOy89rTsavqeckYrbgDPlbdbEf7CoAGxOyJg5knvlTiM2p19K3NB74H8OKmzf7ZlDlGgfugbGO1uIhdXGHC97Nq1a2XGSDnlojaIMnE1nF8QUAWY4vbgYsJcO4/YdNFGKl20VFtz6C3HDAGNWWL6CzvtA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=zMXMT+CDwoTrBMuFmmiwUiagBKEjr4ONLUkzSNsyvXY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d28hWxA1m/qzz/BqY9lkbAUs9EgQysYLTS/7bERw2sj4KuFe2U4I7rKcLoTGgamXM0k4MTyzeJ/XyAR+pROSEpIZR6U9ejnW+Bng9sb5suyc6VRrDvqwg76aWfdH0Ym1fRD1bW64PluyIzRGnxSSqkOW6w6h6JQyypcoM2fAkL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IRwBCpot; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IRwBCpot" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8BC2BC2BCB8; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=zMXMT+CDwoTrBMuFmmiwUiagBKEjr4ONLUkzSNsyvXY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=IRwBCpotsMnRqE/t6vavV+M4sse+zzk7TBSXJwNTqlg1x94Vbeksur0htLnBjMrvM 1SwGLaiJ0o73mnoTwcgUEQaZQSv1y/EdT+2UWYvtm0i0D4KUR4XGYjNvTYBiJqrJaO QoMoGIK3AySjaXRQL6LxeRjJM4RkCc2hyAMnq+sL9qq1lVEkSrU2S+ewYBLzUvH8YB oXF1rnmjkAl9vzvwFCegc1hua66gfVuQPsSVHFIgUjN+DdorY5Dn60ffJ2vMBWkB2s Yxt6yhXfo2cz/SKCdnfN3OtqMhkbIc0S593XUDwor3TSQyj4lyMSgCoFcoLw8k1x73 wroXB1cSBBYeA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7611CC5ACD3; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:07 -0700 Subject: [PATCH v10 28/41] KVM: selftests: Test conversion flow when INIT_SHARED Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-28-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=1820; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=LCMkQdX+H3WVboFtkpu0Izn3eeZarl7aVfYLiu9r/3g=; b=Lg18aCDxNaQup8NnlNTU3r1S8o1MRkDWstNEis+KSXSyH1OUBseYjRh3CJcj4zFmpEdW+XyOJ IxkFnrEGoYoAIKkN6uEs1bKZAjbgT73XPsOUXQEIVLnllJdawedKU53 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a test case to verify that conversions between private and shared memory work correctly when the memory is initially created as shared. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../selftests/kvm/x86/guest_memfd_conversions_test.c | 13 +++++++++= ++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index 77f95d49349ce..4c20d3d8e9349 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -97,6 +97,12 @@ static void __gmem_conversions_##test(test_data_t *t, in= t nr_pages) \ #define GMEM_CONVERSION_TEST_INIT_PRIVATE(test) \ __GMEM_CONVERSION_TEST_INIT_PRIVATE(test, 1) =20 +#define __GMEM_CONVERSION_TEST_INIT_SHARED(test, __nr_pages) \ + GMEM_CONVERSION_TEST(test, __nr_pages, GUEST_MEMFD_FLAG_INIT_SHARED) + +#define GMEM_CONVERSION_TEST_INIT_SHARED(test) \ + __GMEM_CONVERSION_TEST_INIT_SHARED(test, 1) + struct guest_check_data { void *mem; char expected_val; @@ -188,6 +194,13 @@ GMEM_CONVERSION_TEST_INIT_PRIVATE(init_private) test_convert_to_private(t, 0, 'C', 'E'); } =20 +GMEM_CONVERSION_TEST_INIT_SHARED(init_shared) +{ + test_shared(t, 0, 0, 'A', 'B'); + test_convert_to_private(t, 0, 'B', 'C'); + test_convert_to_shared(t, 0, 'C', 'D', 'E'); +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 BF47A47A881; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=NnVaJox6qP/lgeSHWk3GzO3QhS7BboFbRrQjiogLkzvtsFNV3UVZi1IMrRWm0qzHMHxBog85AKm75bycW8escFUd+7HGw+4RuDjh07GW4Thn2eTArppwLgrI2p4qu1CoMrHVPXUWVUH+XgEyJMpL3va+Rx6VtET9NrHgqy68eLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=vGnWVzShNxGcZYSlN1XQqWFKqysFHKcZqPAawHxJEHI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cuNq/n0Jal7EPNz6vpUBvzhLJfgsqYdpva8Jet8zNhwK0c+dfTVWh2BVP058YeI0KbK09MkZ2BLtkRmgnZ8CSfzolgJBz8Vp9rR3IzfQ8KwfcEAbaIiCY1FiX7hXKFegg13okM+u+9kF30XgvGL0gLsqPk0S60i5O0neKCZhJrg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k+E8MSzT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k+E8MSzT" Received: by smtp.kernel.org (Postfix) with ESMTPS id A39F2C2BCFB; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=vGnWVzShNxGcZYSlN1XQqWFKqysFHKcZqPAawHxJEHI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=k+E8MSzT2UJz+CoV1YzWNwOaOmYmc4xLFaAiFY5A5oj7rEtUSzaeXpfLCTlz6D2ZH MlKmHlG73ueo+qzWJ2zQQr4xADO7qFXGuOU7UvxsxGCNPTiU/E95PYE7HhS4ujxvJ2 /R9bGORHVF66SZ5HztutQ4pUpkUzD7JU8dxERq+HUffxNZgu/MrBqroFzTD8GQp+/u fK7qTIYpFtjPAm4Wxe37ieCHpYFFYzM+oVPxgrBbfDf7glZwlNF65T+CdYPWaZXTGc j5ZxnFSA0UyYpROV9gLgDXeUUbo+UobquN6JGSZg116DhAxrSbBO/wIdvRIktK6zeh X7M+lByAl+Ulg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DE03C5AD2B; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:08 -0700 Subject: [PATCH v10 29/41] KVM: selftests: Test conversion precision in guest_memfd Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-29-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=4638; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=kKiOh2nP6kXCIDYZiiw9BDuPZquf+YlONNvXtpCpTSk=; b=j6UiPvLckjIyGe3ldPwpSSVB5A4OrtpmuLr+SrVGh5brvFGaQcnAv90XUtG5FQCSfgORi8OiX cLHvsRgcgMdB9OKPfYrYSlf1/CWG/ac8GN4Px6JgS5wN/qoxjL1InA1 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng The existing guest_memfd conversion tests only use single-page memory regions. This provides no coverage for multi-page guest_memfd objects, specifically whether KVM correctly handles the page index for conversion operations. An incorrect implementation could, for example, always operate on the first page regardless of the index provided. Add a new test case to verify that conversions between private and shared memory correctly target the specified page within a multi-page guest_memfd. This test also verifies the precision of memory conversions by converting a single page an then iterating through all other pages ensure they remain in their original state. To support this test, add a new GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED macro that handles setting up and tearing down the VM for each page iteration. The teardown logic is adjusted to prevent a double-free in this new scenario. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- v10: Update macro GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED to avoid potential macro argument reuse --- .../kvm/x86/guest_memfd_conversions_test.c | 67 ++++++++++++++++++= ++++ 1 file changed, 67 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index 4c20d3d8e9349..a8d89df53e46d 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -61,8 +61,13 @@ static void gmem_conversions_do_setup(test_data_t *t, in= t nr_pages, =20 static void gmem_conversions_do_teardown(test_data_t *t) { + /* Use NULL to avoid second free in FIXTURE_TEARDOWN (multipage tests). */ + if (!t->vcpu) + return; + /* No need to close gmem_fd, it's owned by the VM structure. */ kvm_vm_free(t->vcpu->vm); + t->vcpu =3D NULL; } =20 FIXTURE_TEARDOWN(gmem_conversions) @@ -103,6 +108,30 @@ static void __gmem_conversions_##test(test_data_t *t, = int nr_pages) \ #define GMEM_CONVERSION_TEST_INIT_SHARED(test) \ __GMEM_CONVERSION_TEST_INIT_SHARED(test, 1) =20 +/* + * Repeats test over nr_pages in a guest_memfd of size nr_pages, providing= each + * test iteration with test_page, the index of the page under test in + * guest_memfd. test_page takes values 0..(nr_pages - 1) inclusive. + */ +#define GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(test, __nr_pages) \ +static void __gmem_conversions_multipage_##test(test_data_t *t, int nr_pag= es, \ + const int test_page); \ + \ +TEST_F(gmem_conversions, test) \ +{ \ + const u64 flags =3D GUEST_MEMFD_FLAG_MMAP | GUEST_MEMFD_FLAG_INIT_SHARED;= \ + const int nr =3D (__nr_pages); \ + int i; \ + \ + for (i =3D 0; i < nr; ++i) { \ + gmem_conversions_do_setup(self, nr, flags); \ + __gmem_conversions_multipage_##test(self, nr, i); \ + gmem_conversions_do_teardown(self); \ + } \ +} \ +static void __gmem_conversions_multipage_##test(test_data_t *t, int nr_pag= es, \ + const int test_page) + struct guest_check_data { void *mem; char expected_val; @@ -201,6 +230,44 @@ GMEM_CONVERSION_TEST_INIT_SHARED(init_shared) test_convert_to_shared(t, 0, 'C', 'D', 'E'); } =20 +GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(indexing, 4) +{ + int i; + + /* Get a char that varies with both i and n. */ +#define combine(x, n) (((x) << 4) + (n)) +#define i_(n) (combine(i, n)) +#define t_(n) (combine(test_page, n)) + + /* + * Start with the highest index, to catch any errors when, perhaps, the + * first page is returned even for the last index. + */ + for (i =3D nr_pages - 1; i >=3D 0; --i) + test_shared(t, i, 0, i_(0), i_(2)); + + test_convert_to_private(t, test_page, t_(2), t_(3)); + + for (i =3D 0; i < nr_pages; ++i) { + if (i =3D=3D test_page) + test_private(t, test_page, t_(3), t_(4)); + else + test_shared(t, i, i_(2), i_(3), i_(4)); + } + + test_convert_to_shared(t, test_page, t_(4), t_(5), t_(6)); + + for (i =3D 0; i < nr_pages; ++i) { + char expected =3D i =3D=3D test_page ? t_(6) : i_(4); + + test_shared(t, i, expected, i_(7), i_(8)); + } + +#undef t_ +#undef i_ +#undef combine +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 CE5F147A891; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; cv=none; b=P8ngPiPtjBviO4QaGdmcVfxz6mJSOrbe5MOEXB98dmce8r5yNmHwUqsFUTXGc0TNPjRaeOlKmm2tKBgAGuYHVK7807fRUMfX02f/sH81/nkfoszgZeX55wKjMu3j9fz4+1ShvNpBCoLriuykEU6Pryr5xqhO+HNvs1joQBZzrfY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139570; c=relaxed/simple; bh=Ln1q4lrUFSS7gDCcKwE6OZVftGE9/TNryYAIM2J5wnI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nHj7nm7WIiowUXWg61RTFrko41C9glA8AD0VPwK3MvQMw3yQnuwWY6Hj9vYsiTlJ9pbmG0jzHP/8OlzI6LImkA/bLNPg6EwwiAxoebUefwAm5gl0NGYXYcfMPDPECueyZrt8eq9JkA7ifQqBUEMJAPgna5A3NVQTUtFR0/Ubync= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jzy6weCn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jzy6weCn" Received: by smtp.kernel.org (Postfix) with ESMTPS id B6387C2BCF7; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=Ln1q4lrUFSS7gDCcKwE6OZVftGE9/TNryYAIM2J5wnI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=jzy6weCnau8/ZPn3XJqi4uaeI+Q1Hm62NugnCwW6WTvM7Fi8ZiGJwkF2A02QXp4US WbexHUgr7Nd9eF+4Z6wL2AYZ4Xl5SXgWv0mXStn6yj3wufNBSRSmwQlNmnEmt5gucw mZfF9BKeZ0oXWwQkspnJlXoI44zZUL6Q652KQSpdppYCcUWsdgnB05l9esvS7qUlCc ldKb5xLOLxHO5g++2gOY0bRD7bbi5kfO0a3ix8sopy6++/ucidnN9nqn2gAoApbrXH 1KOAlKLAeHwzUSk8YY0OKAx2gL/U1jtI17ajL4XQ1I5j/QJAhdsR9t4lffyUxuhHKa RTm6oXTmr4MEQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1C13C5ACDC; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:09 -0700 Subject: [PATCH v10 30/41] KVM: selftests: Test conversion before allocation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-30-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=1811; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=YLPoH+UlheGSVuHIZ6ZrndN59zMim3d1nQPb0wA2LUM=; b=zXNVVrQca7C/rG0DVKGmySDl4WfQ3H+varJkKdEvpVYCzZgQHY5/P94gJtrqaORmxh7CShczi 9eNLXP9D7pSBkKjGIE5nv39nqskjscM9o1njNUpPLYwvn++RAQRFE6J X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add two test cases to the guest_memfd conversions selftest to cover the scenario where a conversion is requested before any memory has been allocated in the guest_memfd region. The KVM_SET_MEMORY_ATTRIBUTES2 ioctl can be called on a memory region at any time. If the guest had not yet faulted in any pages for that region, the kernel must record the conversion request and apply the requested state when the pages are eventually allocated. The new tests cover both conversion directions. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../selftests/kvm/x86/guest_memfd_conversions_test.c | 14 ++++++++++= ++++ 1 file changed, 14 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index a8d89df53e46d..f46f1530a94b9 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -268,6 +268,20 @@ GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(indexing, 4) #undef combine } =20 +/* + * Test that even if there are no folios yet, conversion requests are reco= rded + * in guest_memfd. + */ +GMEM_CONVERSION_TEST_INIT_SHARED(before_allocation_shared) +{ + test_convert_to_private(t, 0, 0, 'A'); +} + +GMEM_CONVERSION_TEST_INIT_PRIVATE(before_allocation_private) +{ + test_convert_to_shared(t, 0, 0, 'A', 'B'); +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E297F47ACF5; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=qkdRB0exVNXRDpEyk1FC3qIPPBnXHCV8jDjq9ai3jGS2bU6shH7YRLImqwpUOV8GR/7GZwL0deezKKEkGXi+gw88yMGrcVXV7xN71cSRcnjK6Zj/WBNsO3mojatKvYNU85fy4IU+d0wS/rZozqyio1oxD4GlS4ObIk9zRKlbZHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=AG/91FYLM0DO9+cck1NIO9nDiHcOnSroQ4LfdHp3ioE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dHUP5ieqaoB5tqKRXomoqxTDqciBTl7Z/3W11n851fSnhkvaz1CNwBjtSRPyuvZP9evvSbu5Wg/TwXHyIiaRCEYktjv57IKy0dkmIo8Ld7Hz9ohJksJsQ35ZtY1KjCnbFRseEvytsXydDkE+w+/mg5pq0nk10Zs/59tNbL0x954= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N/SJK8e8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="N/SJK8e8" Received: by smtp.kernel.org (Postfix) with ESMTPS id C9D07C2BCFF; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=AG/91FYLM0DO9+cck1NIO9nDiHcOnSroQ4LfdHp3ioE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=N/SJK8e8lD6KSkxkcOVSrDGMbjIkLh6zoxSiB8vFWdp66hTw3RJuSr8WUOPOPMzvN yRydKoy+VpRZVhPv9TNjQudy4N5Dyb1qNK9IqVo7rvtg9ToIVb7sZ4wdxX3vEcRk7N t6A7bLSsgNr5lV+9XPyBTjNJhQsRqKx4eFqOcXDBXm493vhran5oFhDpLPRSzQ5J2V pVF805v07ZvRww24J0tWtAlyubzUlTxdp4qzkJUJus8o59rA9umKGpSb3VG1bm9a1s /oq/J9XwJycsxhJR2qjMMpyJVqGjHq+vJDhfWF1VcLKDLCYC/FIN09Vb+ZbNjSPVLo 9ZycNMyvDvewg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5935C5AD2C; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:10 -0700 Subject: [PATCH v10 31/41] KVM: selftests: Convert with allocated folios in different layouts Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-31-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2317; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=pR1j4y2LoLWaLX8jxwPGv1VVAKk8ThG0YqF8F3XUFHo=; b=J9+DQkUjkGb4HelYEvW/SqnQ8uNjodN1J6oB6YRe/dxweMyOlALGBr4BZIy70J1AfpWjzSKhk hhXUnozOh3OCYsp/HNPNkKktNV3dEdDQqPSHZtq0SH9crOUZoBUjeTE X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a guest_memfd selftest to verify that memory conversions work correctly with allocated folios in different layouts. By iterating through which pages are initially faulted, the test covers various layouts of contiguous allocated and unallocated regions, exercising conversion with different range layouts. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../kvm/x86/guest_memfd_conversions_test.c | 30 ++++++++++++++++++= ++++ 1 file changed, 30 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index f46f1530a94b9..acdff2d154046 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -282,6 +282,36 @@ GMEM_CONVERSION_TEST_INIT_PRIVATE(before_allocation_pr= ivate) test_convert_to_shared(t, 0, 0, 'A', 'B'); } =20 +/* + * Test that when some of the folios in the conversion range are allocated, + * conversion requests are handled correctly in guest_memfd. Vary the ran= ges + * allocated before conversion, using test_page, to cover various layouts = of + * contiguous allocated and unallocated regions. + */ +GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(unallocated_folios, 8) +{ + const int second_page_to_fault =3D 4; + int i; + + /* + * Fault 2 of the pages to test filemap range operations except when + * test_page =3D=3D second_page_to_fault. + */ + host_do_rmw(t->mem, test_page, 0, 'A'); + if (test_page !=3D second_page_to_fault) + host_do_rmw(t->mem, second_page_to_fault, 0, 'A'); + + gmem_set_private(t->gmem_fd, 0, nr_pages * page_size); + for (i =3D 0; i < nr_pages; ++i) { + char expected =3D (i =3D=3D test_page || i =3D=3D second_page_to_fault) = ? 'A' : 0; + + test_private(t, i, expected, 'B'); + } + + for (i =3D 0; i < nr_pages; ++i) + test_convert_to_shared(t, i, 'B', 'C', 'D'); +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2338747D948; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=h9EtbP5QQHojLwg1ioL+y8/eNpEX5Q8QPt8hpyLhWNOKKnxRPtPXO4JGBGNGL0z5QGEMTTClSfwjs87DRmHp8GsCUeU1EyBqU/kAGj5/ZMGGiG3oTJV5+GN+TOe5VR0CxzRK7FGfcXK3e3St77ZXMbdxx9okBcVfaLW/4Tjw+n0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=oiCZ15D+JnnSDHZXHJ5SlW01WMugZzVHBK5KAb/ZX6s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qL0nWCb4Z3AVTnTyTtP12yhENEenelrJGsLkArW5FuFq4fAXgnAZjUWbnoNqOig04A9RLPo0z3TwtmBtP5idz01C+gSrA0KjGqJwLYse91iIMIdrQynLusddEQnfr72pPH1pXScnwjplySat0IbXFYnEpWKzYTqvjxF0tPvARR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RgyN4ahX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RgyN4ahX" Received: by smtp.kernel.org (Postfix) with ESMTPS id E1840C2BD04; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139570; bh=oiCZ15D+JnnSDHZXHJ5SlW01WMugZzVHBK5KAb/ZX6s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=RgyN4ahX4jtewJsRYEPJqp9Xhd3uhLAJl5j2/nGrN9dVIp1KHOyrL3hIEshk8gbuK vpW3cP61hAKT/Ak6x7y+cavkxW2Lx1Y2jzPbvUGc735VsFcKEnL7adsbz6CFuukfQF +cRrG5tYspEVBYpyJfBMNvZbfvFQFACnsjCs8AMITE+WfDix2F8IMLG0VzsSlVLkBs ROv5Sdg2jr/54NrDh2snLIXP6aqiosbEiiYP2epCZVw/3TTrXrizPyjLZZRvqn7QwU wMzSk7P4UNDf8FEZwSbDFygCcI+20l9wj1Wtqw4fcnb1ERzgdMxAjwVLEUa7aoTjvl DvuLb0431w84g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBAB8C5ACD3; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:11 -0700 Subject: [PATCH v10 32/41] KVM: selftests: Test that truncation does not change shared/private status Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-32-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2066; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=XnrrGORPSG8J5b5Yy/zf/neukgQrtYTrJSAta0tG4eE=; b=dXcTGNf6P61ZUtYXmAhmz6sqd3ry79tRyeA1zpGJGdnTisGO6IFhUDrktN98U1VNcfEgBStuj Uy3aUtM/QxdAt5XSp/kGzwFm7+XJeSjDq9ym+JWPxai/LrpuBDi+HQ6 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a test to verify that deallocating a page in a guest memfd region via fallocate() with FALLOC_FL_PUNCH_HOLE does not alter the shared or private status of the corresponding memory range. When a page backing a guest memfd mapping is deallocated, e.g., by punching a hole or truncating the file, and then subsequently faulted back in, the new page must inherit the correct shared/private status tracked by guest_memfd. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../selftests/kvm/x86/guest_memfd_conversions_test.c | 14 ++++++++++= ++++ 1 file changed, 14 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index acdff2d154046..b7a54d2a90928 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -10,6 +10,7 @@ #include =20 #include "kvm_util.h" +#include "kvm_syscalls.h" #include "kselftest_harness.h" #include "test_util.h" #include "ucall_common.h" @@ -312,6 +313,19 @@ GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(unallocated= _folios, 8) test_convert_to_shared(t, i, 'B', 'C', 'D'); } =20 +/* Truncation should not affect shared/private status. */ +GMEM_CONVERSION_TEST_INIT_SHARED(truncate) +{ + host_do_rmw(t->mem, 0, 0, 'A'); + kvm_fallocate(t->gmem_fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, = page_size); + host_do_rmw(t->mem, 0, 0, 'A'); + + test_convert_to_private(t, 0, 'A', 'B'); + + kvm_fallocate(t->gmem_fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, = page_size); + test_private(t, 0, 0, 'A'); +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3A33347DD59; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=X0YVR1r8K+Qwd7BYMEetkYvL0WIy5Udm2HXalP0POD4ZIxOdIQF0ZI7mnwmwHGB8suoGavLtESYdtcjHJjlu2zwMjugV4jycffEJoj1+Q2GmKSFvKOWGAegUBKyu9w3s9eeD62IR49WIglnK4L966u33BxRK+OstsxmapScQa3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=9/m2jxorN/mpEKB+0ZPDHMOy8YGWYwwh289K8iE9S8Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eQkgbd1DdyFFtBBg5FFpD4lLUx0A0BKr0J6bbzGvnJFHKnSW7XIE7myl8ESEy7WD2t1eK2phplbXMbeYQ2FQuncRPFBGxOF/uT2nsBUi86qCnAb2EBU4wJPp4T7nwUMZzccSCD+GN77BDoJ9Lajwh6OvvRXQoy//Rbx/46dh9LU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HYk4XNP6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HYk4XNP6" Received: by smtp.kernel.org (Postfix) with ESMTPS id 038D1C2BCFA; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=9/m2jxorN/mpEKB+0ZPDHMOy8YGWYwwh289K8iE9S8Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=HYk4XNP6WcB3voorCYEt9HWu65TvP5LOmDMD8qRaZLEzx2ayWooIfmg2YOYZfc+ur 5jLW9Uzmr2kJeiFee7GFmIqPBjd24vSGZlqkP1/CbrMz1OIOFA3UzcxFBCk4ddGHaw 0dSWKmqfHm6ni63LH56/9oQ+hlRbA4jSHQ/XEKrl09KxUzuI3Pzs68yloF3EJtjgPG P07fiM0ZPtx4YT0arK932gKsf9uOIm6C2pvFmFt06Eoiivrs8UvIxyQYkMhhLTpUiR O+wSMGvTPE5Z9UQr06D1lIE4bv3SVCMV/k3db9OMfQnPe71/1EqGp0Nu90vsByxk8z o9JpNQh5mGdOw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E063EC5AD2B; Fri, 7 Aug 2026 21:52:50 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:12 -0700 Subject: [PATCH v10 33/41] KVM: selftests: Test that shared/private status is consistent across processes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-33-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5042; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=Ms+Uf3765Ivoa4b0Xh9VZFehp7g2sgcWofOdWHtIXiQ=; b=c6u1WfppRWCKD7i14xOqzWZctHUQCeSAD2vB1tMd8H8ffRAIjeADz4RVPXWO4m1EiMTPF5Xw4 gixah2IQwpCCXkFvbLunj/SQn9fKtGcTGMJZJ0Vkbf5QRsv9aJCBlU0 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Add a test to verify that a guest_memfd's shared/private status is consistent across processes, and that any shared pages previously mapped in any process are unmapped from all processes. The test forks a child process after creating the shared guest_memfd region so that the second process exists alongside the main process for the entire test. The processes then take turns to access memory to check that the shared/private status is consistent across processes. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng --- .../kvm/x86/guest_memfd_conversions_test.c | 118 +++++++++++++++++= ++++ 1 file changed, 118 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index b7a54d2a90928..a972a09c5c6e5 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -2,7 +2,9 @@ /* * Copyright (c) 2024, Google LLC. */ +#include #include +#include #include =20 #include @@ -326,6 +328,122 @@ GMEM_CONVERSION_TEST_INIT_SHARED(truncate) test_private(t, 0, 0, 'A'); } =20 +/* Test that shared/private memory protections work and are seen from any = process. */ +GMEM_CONVERSION_TEST_INIT_SHARED(forked_accesses) +{ + enum test_state { + STATE_INIT, + STATE_CHECK_SHARED, + STATE_DONE_CHECKING_SHARED, + STATE_CHECK_PRIVATE, + STATE_DONE_CHECKING_PRIVATE, + }; + + struct sync_state { + pthread_mutex_t mutex; + pthread_cond_t cond; + enum test_state step; + } *sync; + + pthread_mutexattr_t mattr; + pthread_condattr_t cattr; + pid_t child_pid, parent_pid; + int status; + + sync =3D kvm_mmap(sizeof(*sync), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1); + + pthread_mutexattr_init(&mattr); + pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&sync->mutex, &mattr); + pthread_mutexattr_destroy(&mattr); + + pthread_condattr_init(&cattr); + pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); + pthread_cond_init(&sync->cond, &cattr); + pthread_condattr_destroy(&cattr); + + sync->step =3D STATE_INIT; + +#define TEST_STATE_AWAIT(__state) \ + do { \ + pthread_mutex_lock(&sync->mutex); \ + while (sync->step !=3D (__state)) { \ + struct timespec ts, stop; \ + int ret; \ + \ + clock_gettime(CLOCK_REALTIME, &ts); \ + stop =3D timespec_add_ns(ts, 100 * 1000000UL); \ + \ + ret =3D pthread_cond_timedwait(&sync->cond, &sync->mutex, &stop); \ + if (ret =3D=3D ETIMEDOUT) { \ + bool alive =3D (child_pid =3D=3D 0) ? \ + (getppid() =3D=3D parent_pid) : \ + (waitpid(child_pid, NULL, WNOHANG) =3D=3D 0); \ + TEST_ASSERT(alive, "Other process exited prematurely"); \ + } else { \ + TEST_ASSERT(!ret, "pthread_cond_timedwait failed"); \ + } \ + } \ + pthread_mutex_unlock(&sync->mutex); \ + } while (0) + +#define TEST_STATE_SET(__state) \ + do { \ + pthread_mutex_lock(&sync->mutex); \ + sync->step =3D (__state); \ + pthread_cond_broadcast(&sync->cond); \ + pthread_mutex_unlock(&sync->mutex); \ + } while (0) + + parent_pid =3D getpid(); + child_pid =3D fork(); + TEST_ASSERT(child_pid !=3D -1, "fork failed"); + + if (child_pid =3D=3D 0) { + const char inconsequential =3D 0xdd; + + TEST_STATE_AWAIT(STATE_CHECK_SHARED); + + /* + * This maps the pages into the child process as well, and tests + * that the conversion process will unmap the guest_memfd memory + * from all processes. + */ + host_do_rmw(t->mem, 0, 0xB, 0xC); + + TEST_STATE_SET(STATE_DONE_CHECKING_SHARED); + TEST_STATE_AWAIT(STATE_CHECK_PRIVATE); + + TEST_EXPECT_SIGBUS(READ_ONCE(t->mem[0])); + TEST_EXPECT_SIGBUS(WRITE_ONCE(t->mem[0], inconsequential)); + + TEST_STATE_SET(STATE_DONE_CHECKING_PRIVATE); + exit(0); + } + + test_shared(t, 0, 0, 0xA, 0xB); + + TEST_STATE_SET(STATE_CHECK_SHARED); + TEST_STATE_AWAIT(STATE_DONE_CHECKING_SHARED); + + test_convert_to_private(t, 0, 0xC, 0xD); + + TEST_STATE_SET(STATE_CHECK_PRIVATE); + TEST_STATE_AWAIT(STATE_DONE_CHECKING_PRIVATE); + + TEST_ASSERT_EQ(waitpid(child_pid, &status, 0), child_pid); + TEST_ASSERT(WIFEXITED(status) && WEXITSTATUS(status) =3D=3D 0, + "Child exited with unexpected status"); + + pthread_mutex_destroy(&sync->mutex); + pthread_cond_destroy(&sync->cond); + kvm_munmap(sync, sizeof(*sync)); + +#undef TEST_STATE_SET +#undef TEST_STATE_AWAIT +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 50F1847ECC7; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=bFXXuln33el3nCfDYsIq2y7nECymY8O23oe82eTdL6iixaT/WaVC51zcbPBDH411+MMSTLUJa9XraCsJFfoM9nsXs8t/J8CAMab79Yb0ZaRVu6oQvhmOynqDaJ+6figkrTDJaRsKr51tODoROq7SeYu4FCGxiqk641EJRWhimoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=ja9kgTXKp8MbX00Y/A8nmdYFnNNk9zdQafFLcm0bclI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UHm26juRFRjypkx2uuUkdE7W5GGdi3L39K01u84oj2K7+ecHjUnvJP/GUrJt6ZaJUEbn2H5SS2uR0YZdyINB5GM+wpQr7MYuiW02ntOK28O9Z5YMyAevh16G5fFHn4R04BXC9BLujdOFgjm1toFnMWDR/O4oiDW7XIwy42oIO2M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HmySTGsR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HmySTGsR" Received: by smtp.kernel.org (Postfix) with ESMTPS id 254EAC4AF51; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=ja9kgTXKp8MbX00Y/A8nmdYFnNNk9zdQafFLcm0bclI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=HmySTGsRTcnihovYOPx1lxO/Ls40k2h2IAJ8TQlBfnR9z2KNBGwixBjawbcMG0bNe Nd2Hvy+1nGRU1kOymNzytkzJWDQMCeNg5uavp1EM4X9GcP7g4cjMkxhRPslm8uk2NZ oPUN3j52wuvWdDdzzs9+nfsWSqNAVZ7wk38M3BcCcku/aQ4KqKobwO1jaruiRKUPOM 2f3VGcaML/YTvl7V3xS9mKZwPp6nEkB22BmmBCNKGE+wsZdLv3bD1Ja4QzBUEsXPYt rH4eObflxWbB6/dWi+63V/R81A9ClRBtmQag1sxc3Lku8ndkJq+uyZ+k1JA0YzxXVp Dz3lMN6HSmDyQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01091C5ACDC; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:13 -0700 Subject: [PATCH v10 34/41] KVM: selftests: Add helpers to pin pages with CONFIG_GUP_TEST Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-34-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2727; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=hcW1DlqCdnSzmI45o3LcgBosQ7tTRCZf45DfrB9G7us=; b=D/7W5Lg+H24nvcVwXqYHutKeJIxMyV63gfZOGX1T6+gdFLZZ9D28ih82o1BmY8o8nFoq89D/n K2P0seUgnSjCPz3zEhqVM2qdMNqrM3HR/dEYV4zwyHiGOF6w0Es1Ifb X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add helper functions to allow KVM selftests to pin memory using CONFIG_GUP_TEST. This is useful for testing scenarios where some page has an increased refcount. such as in guest_memfd in-place conversion tests. The helpers open /sys/kernel/debug/gup_test and invoke the PIN_LONGTERM_TEST_START and PIN_LONGTERM_TEST_STOP ioctls. Since this functionality depends on the kernel being built with CONFIG_GUP_TEST, provide stub implementations that trigger a test failure if the configuration is missing. Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 3 +++ tools/testing/selftests/kvm/lib/kvm_util.c | 25 ++++++++++++++++++++++= +++ 2 files changed, 28 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 575032e9791d2..3cfe243d7c8b0 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -1206,6 +1206,9 @@ static inline int pin_self_to_any_cpu(void) return pin_task_to_any_cpu(pthread_self()); } =20 +void pin_pages(void *vaddr, uint64_t size); +void unpin_pages(void); + void kvm_print_vcpu_pinning_help(void); void kvm_parse_vcpu_pinning(const char *pcpus_string, u32 vcpu_to_pcpu[], int nr_vcpus); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index cd468b2bb8343..b1456ed76e27e 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -19,6 +19,8 @@ #include #include =20 +#include "../../../../../mm/gup_test.h" + #define KVM_UTIL_MIN_PFN 2 =20 u32 kvm_random_seed; @@ -645,6 +647,29 @@ int __pin_task_to_cpu(pthread_t task, int cpu) return pthread_setaffinity_np(task, sizeof(cpuset), &cpuset); } =20 +static int gup_test_fd =3D -1; + +void pin_pages(void *vaddr, uint64_t size) +{ + const struct pin_longterm_test args =3D { + .addr =3D (uint64_t)vaddr, + .size =3D size, + .flags =3D PIN_LONGTERM_TEST_FLAG_USE_WRITE, + }; + + gup_test_fd =3D __open_path_or_exit("/sys/kernel/debug/gup_test", O_RDWR, + "Is CONFIG_GUP_TEST enabled?"); + + TEST_ASSERT_EQ(ioctl(gup_test_fd, PIN_LONGTERM_TEST_START, &args), 0); +} + +void unpin_pages(void) +{ + TEST_ASSERT_EQ(ioctl(gup_test_fd, PIN_LONGTERM_TEST_STOP), 0); + + kvm_free_fd(gup_test_fd); +} + static u32 parse_pcpu(const char *cpu_str, const cpu_set_t *allowed_mask) { u32 pcpu =3D atoi_non_negative("CPU number", cpu_str); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 61A8947F2CB; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=vFVgEU/EOo2w0ANxH972v1Z5o+7LOXWwPnso9MApjhiVRXFbz6bQ1Ez+6FDTwuzKM/l9fOprQSTByuGay7KribO131677VIiP3vdN2vcIBZPbMUMBecp7mNl3f1EhrQV0lP1/pfij0MjX4nniqwxzUb4QWwfytuMg6Pd/0jPY/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=WDKsrZiZJlDXKakS3Ne8GBtkCp6v0E/NVwWuKGbd0VM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W1e+0EkoQyEiyLlqJZQ0JiutmFeSkpS0Rgl55fiH9LrJRs7DK9homH6zVQcH92jLnZpc+kyzkkUC+KdQJgoeJIRs3APeN9O8arKtHniWGpjDktavk5Qjl55gWVjDZuccA/Ad9jq8xkaAheMPJx7kmJlksjGIYyOOk7ADEEe+QHQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IlYmzrk2; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IlYmzrk2" Received: by smtp.kernel.org (Postfix) with ESMTPS id 36B7BC4AF0F; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=WDKsrZiZJlDXKakS3Ne8GBtkCp6v0E/NVwWuKGbd0VM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=IlYmzrk27RXsohQeDwRNay7ZQU+ma58MaqvkUR9EW6lcvx2xUS4XrNIJUwzLTlarT aqPlOvSgc2XFefyozygfmHURJp8Hqjf8Flsz15USr6vMGrKZ+zFqLkcuC0ZrnzP3Zh /EGnI2gpnuhIpOblMaq3ti1l1eSDUHa1F3cM5p9dgLtD5l751WcPmGq9RL64E+/vdW B+UtrKeF+RrKIj0yuqvd6ayBIKXKOitfjCDXSo9LG+iGouurFk1igNwSeRQqJTIbk9 c2PNXI+I16j1HLQ29YJKRRZ+qqsVzhTN6Eq3e3NA7L/EUHRsIvg+jbtv5GibwNXTZB uHYMdDzpcfuPA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19FD5C5AD2C; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:14 -0700 Subject: [PATCH v10 35/41] KVM: selftests: Test conversion with elevated page refcount Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-35-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3125; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=p2RZydKvg888n0XoOUjxbRa4guxOTSCM2qo+J0sXmYw=; b=jhnjesMtPkRy9w4qr83aPYgjzv9dcXLfod9ioti8LuuCqLHmGkcD+pPXy/JArMEhXvYNmQKjh s5ce18SW2lFA+PIFSNYHYakT4GaWXk1LNmCYqBn93k3nIj9DmABvRo8 X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Add a selftest to verify that converting a shared guest_memfd page to a private page fails if the page has an elevated reference count. When KVM converts a shared page to a private one, it expects the page to have a reference count equal to the reference counts taken by the filemap. If another kernel subsystem holds a reference to the page, the conversion must be aborted. The test asserts that both bulk and single-page conversion attempts correctly fail with EAGAIN for the pinned page. After the page is unpinned, the test verifies that subsequent conversions succeed. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../kvm/x86/guest_memfd_conversions_test.c | 56 ++++++++++++++++++= ++++ 1 file changed, 56 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c= b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c index a972a09c5c6e5..e1c84df0f0596 100644 --- a/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c @@ -444,6 +444,62 @@ GMEM_CONVERSION_TEST_INIT_SHARED(forked_accesses) #undef TEST_STATE_AWAIT } =20 +static void test_convert_to_private_fails(test_data_t *t, u64 pgoff, + size_t nr_pages, + u64 expected_error_offset) +{ + /* +1 to make it anything but expected_error_offset. */ + u64 error_offset =3D expected_error_offset + 1; + u64 offset =3D pgoff * page_size; + int ret; + + do { + ret =3D __gmem_set_private(t->gmem_fd, offset, + nr_pages * page_size, &error_offset); + } while (ret =3D=3D -1 && errno =3D=3D EINTR); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EAGAIN, + "Wanted EAGAIN on page %lu, got %d (ret =3D %d)", pgoff, + errno, ret); + TEST_ASSERT_EQ(error_offset, expected_error_offset); +} + +GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED(elevated_refcount, 4) +{ + int i; + + pin_pages(t->mem + test_page * page_size, page_size); + + for (i =3D 0; i < nr_pages; i++) + test_shared(t, i, 0, 'A', 'B'); + + /* + * Converting in bulk should fail as long any page in the range has + * unexpected refcounts. + */ + test_convert_to_private_fails(t, 0, nr_pages, test_page * page_size); + + for (i =3D 0; i < nr_pages; i++) { + /* + * Converting page-wise should also fail as long any page in the + * range has unexpected refcounts. + */ + if (i =3D=3D test_page) + test_convert_to_private_fails(t, i, 1, test_page * page_size); + else + test_convert_to_private(t, i, 'B', 'C'); + } + + unpin_pages(); + + gmem_set_private(t->gmem_fd, 0, nr_pages * page_size); + + for (i =3D 0; i < nr_pages; i++) { + char expected =3D i =3D=3D test_page ? 'B' : 'C'; + + test_private(t, i, expected, 'D'); + } +} + int main(int argc, char *argv[]) { TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 725E447F2FA; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=NneSF3eckyOaUwcczkzwysjptAn+i2AEkAUuG6K56EhD24590eaNfZUmhxI92PphIKaH+E07luoJu0rZ4HSw54A5OAwA5+e4dVNnaOOqyaFuSmN1VynjdiwO92M26+NXSHJvkgtJ/Nf4S/PLBbmVi466DFIlT6roaIV0qQFNPjM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=qqzdiyNUgHYhFJAhz2OLTx3xm0dCCGWmIe3EV7o9RvU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kKgq4WdyHZ9zU9FQFY5dpVeGnN4d9NSYbgyBPuVhGexi8KDgz1jxIEuxeQdX8b3REnsmfYu2Ape2fK3JeNke3DPqz4rtbOisL4msO68tgMBVGiqLGbsctXUEafXxYhCgEx28vTQVtK+F7oNkUBhaRsvj4LmyaNEueJogSvO8BLo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JJDA5EKz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JJDA5EKz" Received: by smtp.kernel.org (Postfix) with ESMTPS id 52C96C4AF52; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=qqzdiyNUgHYhFJAhz2OLTx3xm0dCCGWmIe3EV7o9RvU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=JJDA5EKzDkEVpIFwaqK+GBznZFtMm+NkAQXGGtzqoZ9e8nAndBIZqjUdDpjn/QQtB B0fcTB/uztCdVzuyQCx4ZaFN4TvLTLfgq1Cy8zkcK0pLrWhdftqxRsuc1po5TkqPpY jIVFa/lPH7Y0Zx4gu0wlcqqyEayvVCz3vh6+rBzTipL33RXO9HgkDhL2LV4l6Mb0fH xPiDRJA4Rk0JgG/6j0hQiXVPoigp9HqAcoa3rJzl3pEFGVLVGAnyfyC4b3xOAuOWV4 NJ2jnUU7HPoiHw40omUiDenTp6D2QyMHVhL1UjvNofTSxCWOf8uLSNW7jwlL0TQnh1 hM4P66OZT+IIA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 308BDC5AD44; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:15 -0700 Subject: [PATCH v10 36/41] KVM: selftests: Reset shared memory after hole-punching Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-36-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2579; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=8D4fZWoQ61fs10P4wW1NWAab+kfHlzlVCGaPrK13txo=; b=SszwThQ1P/kLbfeBg41IjKPAR4N6GnShBqcO1dZvZxJT+Hz6+KdLfcFuRLAhHEL8ubXBszGre tfZdFUYbGbtByPo9jXn86svXQxTJzOB0LlrhT+0Wrj+3oj+THtZz1/L X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng private_mem_conversions_test used to reset the shared memory that was used for the test to an initial pattern at the end of each test iteration. Then, it would punch out the pages, which would zero memory. Without in-place conversion, the resetting would write shared memory, and hole-punching will zero private memory, hence resetting the test to the state at the beginning of the for loop. With in-place conversion, resetting writes memory as shared, and hole-punching zeroes the same physical memory, hence undoing the reset done before the hole punch. Move the resetting after the hole-punching, and reset the entire PER_CPU_DATA_SIZE instead of just the tested range. With in-place conversion, this zeroes and then resets the same physical memory. Without in-place conversion, the private memory is zeroed, and the shared memory is reset to init_p. This is sufficient since at each test stage, the memory is assumed to start as shared, and private memory is always assumed to start zeroed. Conversion zeroes memory, so the future test stages will work as expected. Fixes: 43f623f350ce1 ("KVM: selftests: Add x86-only selftest for private me= mory conversions") Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/x86/private_mem_conversions_test.c | 9 ++++++-= -- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c= b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c index f3de2a4ab0551..cf50e9a332c5b 100644 --- a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c @@ -202,15 +202,18 @@ static void guest_test_explicit_conversion(u64 base_g= pa, bool do_fallocate) guest_sync_shared(gpa, size, p3, p4); memcmp_g(gpa, p4, size); =20 - /* Reset the shared memory back to the initial pattern. */ - memset((void *)gpa, init_p, size); - /* * Free (via PUNCH_HOLE) *all* private memory so that the next * iteration starts from a clean slate, e.g. with respect to * whether or not there are pages/folios in guest_mem. */ guest_map_shared(base_gpa, PER_CPU_DATA_SIZE, true); + + /* + * Hole-punching above zeroed private memory. Reset shared + * memory in preparation for the next GUEST_STAGE. + */ + memset((void *)base_gpa, init_p, PER_CPU_DATA_SIZE); } } =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8091547F781; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; cv=none; b=UYM3YJ/uIMT5vlqvEUouE4zhAWMY6g/IhRJy3HS7x4pUyVZGJuykbWUy+gTtkeTh9M+KbbKCeJtXQj0pUkqJ1W3satVHaz7XSM+HXoBFw8zv0AxosVkYbJq0MMJ0kwzmJ2hyUA+uxSgGCD1pkdHa7cKyB4wm4ofA6/3o1JUNR3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139571; c=relaxed/simple; bh=OGHjw3gqd8Gw/UtDSEmTOdDh610hKejY8AY6SlCRJw4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VBA1Ig0PYD/YhAJn5jeBqwWKnXjdFxhSvlsBspI8/LhkeGPXZv8YWcqyp8gp7Ae4dtQgCPes1ZsAGIfp+URwD8C9eKpg+8aa/MND5yt56vdauDoIWNXF7Iymuvm41M74EvX0yJm3k1rbu6prlOM0tcXp66rj+jhK8RJ6wsctSXA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E2OJ5DuU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E2OJ5DuU" Received: by smtp.kernel.org (Postfix) with ESMTPS id 60B80C4AF67; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=OGHjw3gqd8Gw/UtDSEmTOdDh610hKejY8AY6SlCRJw4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=E2OJ5DuUgF1tbkDn2eG5IV75+lg9bcWoGNskxe5xG/3kx9Gt1AXH5feMNA3RZcjN4 flMEaamYTsfQ1aBUFKIb3E6i0n6zX9Qh4xlcdVffPF8oYt5Gbs5oVS/CXgGU8HCYjo oyYLMV1nYUGY3bAen//myTdplLWUoADgFjUQhopRdASXAXfZkPQ0oFn1vijiCOgDLj I/BaDfHapOhoBO7bfuEz58Ud1tALKKVu4vbhm+cBpSumDStunW/1cpGqxqcv3qDflc cwhbu3RH5AimEgthzRWeJ4ZulEol7PqYhKJ+awcbZj0fXrIRCoOKHHMcUCdAMXmEMi k0fRtj+r7euzQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48441C5AD46; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:16 -0700 Subject: [PATCH v10 37/41] KVM: selftests: Provide function to look up guest_memfd details from gpa Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-37-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3994; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=nqVYNMaLLaXl0sqbjsCrLje7Yj2R93B42zAkuyAcDYE=; b=7nSV7pH1KcuwHuhDciDwmMBz12jLIK2P5ubeWQ/gQXDWkJZMzA/PmWfmc5gWbC2w4UoTpSF42 YGKfZhiQH5sANXGTr++Xb9kLsjRgLJW+yDYkcQ02RRmeGlCJsRyeigg X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Introduce a new helper, kvm_gpa_to_guest_memfd(), to find the guest_memfd-related details of a memory region that contains a given guest physical address (GPA). The function returns the file descriptor for the memfd, the offset into the file that corresponds to the GPA, and the number of bytes remaining in the region from that GPA. kvm_gpa_to_guest_memfd() was factored out from vm_guest_mem_fallocate(); refactor vm_guest_mem_fallocate() to use the new helper. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 3 +++ tools/testing/selftests/kvm/lib/kvm_util.c | 37 ++++++++++++++++------= ---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 3cfe243d7c8b0..795c9eb311071 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -428,6 +428,9 @@ static inline void vm_enable_cap(struct kvm_vm *vm, u32= cap, u64 arg0) vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); } =20 +int kvm_gpa_to_guest_memfd(struct kvm_vm *vm, gpa_t gpa, off_t *fd_offset, + size_t *nr_bytes); + /* * KVM_SET_MEMORY_ATTRIBUTES{,2} overwrites _all_ attributes. These * flows need significant enhancements to support multiple attributes. diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index b1456ed76e27e..1188d0a6c0a5f 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1332,27 +1332,20 @@ void vm_guest_mem_fallocate(struct kvm_vm *vm, u64 = base, u64 size, bool punch_hole) { const int mode =3D FALLOC_FL_KEEP_SIZE | (punch_hole ? FALLOC_FL_PUNCH_HO= LE : 0); - struct userspace_mem_region *region; u64 end =3D base + size; - gpa_t gpa, len; off_t fd_offset; - int ret; + int fd, ret; + size_t len; + gpa_t gpa; =20 for (gpa =3D base; gpa < end; gpa +=3D len) { - u64 offset; - - region =3D userspace_mem_region_find(vm, gpa, gpa); - TEST_ASSERT(region && region->region.flags & KVM_MEM_GUEST_MEMFD, - "Private memory region not found for GPA 0x%lx", gpa); + fd =3D kvm_gpa_to_guest_memfd(vm, gpa, &fd_offset, &len); + len =3D min(end - gpa, len); =20 - offset =3D gpa - region->region.guest_phys_addr; - fd_offset =3D region->region.guest_memfd_offset + offset; - len =3D min_t(u64, end - gpa, region->region.memory_size - offset); - - ret =3D fallocate(region->region.guest_memfd, mode, fd_offset, len); + ret =3D fallocate(fd, mode, fd_offset, len); TEST_ASSERT(!ret, "fallocate() failed to %s at %lx (len =3D %lu), fd =3D= %d, mode =3D %x, offset =3D %lx", punch_hole ? "punch hole" : "allocate", gpa, len, - region->region.guest_memfd, mode, fd_offset); + fd, mode, fd_offset); } } =20 @@ -1689,6 +1682,22 @@ void *addr_gpa2alias(struct kvm_vm *vm, gpa_t gpa) return (void *) ((uintptr_t) region->host_alias + offset); } =20 +int kvm_gpa_to_guest_memfd(struct kvm_vm *vm, gpa_t gpa, off_t *fd_offset, + size_t *nr_bytes) +{ + struct userspace_mem_region *region; + gpa_t gpa_offset; + + region =3D userspace_mem_region_find(vm, gpa, gpa); + TEST_ASSERT(region && region->region.flags & KVM_MEM_GUEST_MEMFD, + "guest_memfd memory region not found for GPA 0x%lx", gpa); + + gpa_offset =3D gpa - region->region.guest_phys_addr; + *fd_offset =3D region->region.guest_memfd_offset + gpa_offset; + *nr_bytes =3D region->region.memory_size - gpa_offset; + return region->region.guest_memfd; +} + /* Create an interrupt controller chip for the specified VM. */ void vm_create_irqchip(struct kvm_vm *vm) { --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 1198B481235; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; cv=none; b=NJqYtWeNw8VZm9sOEEi7hxowcJL57sop8FSzO6laFahuId/o/SD5D6/yMzDOcNrOdGsVtuFm7mZJSXMZ/GZCpeDyD7b6oHCLCNnvGskFiDvEINRPZPKzzU7jGeE7ssD4ZVR7umSo1V3UZfqmJinC2p0c9upBWsVgD/+RZ2IriIc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; c=relaxed/simple; bh=YFbrmMd/qfinectFQbLr654cT8Cy/bdXVL7tUQSmXeI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LEEIqEzWA8ODkpC0zQ/kDX43oR7CdZbfSBnFETdO2mS8+VX0SQ3Z38Cot7OKLS4feQjdQNNLUxxUFmPGwgMlObopjh1yl0BJthwN1IMd9XlgwoygM0wiPwMscvuTjPt4Q69QQmLK6cDoRjnSgjuKT7Mchii+krtERA7ppLXgJIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rVtJqcmq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rVtJqcmq" Received: by smtp.kernel.org (Postfix) with ESMTPS id 957B3C2BCFA; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=YFbrmMd/qfinectFQbLr654cT8Cy/bdXVL7tUQSmXeI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rVtJqcmq9bkLtwzs/sbn/drAeHqIHXm3CgG9CyTMP5Htt3mSfq15S1I8PqmB9vKEo Ow1dzTWcEpu0Cr5nMM6bLigDgaGC0RaanxxJpiVq50/OWCDhu7jk+3xSCyEImxYtdY NXFTIv6GqtiLzIWSnuz+znl9AqxYXTj1HOw29Ie39gRIYM/MDwegThP7KcaZM7JXXy 48dSv30S0hi9PUO6zUhtd/VLAIIxddakQTZgeMACI3fKAWj8Kq79Jtb+PncEmq2/L5 ppGGiLD076WwT6/+CyVWPSM7grVQHZDfDapH3qmrSca0DOmoryB/03OJpCH1hNIlp1 HO8EwfmRbuOLA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B97DC5AD2C; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:17 -0700 Subject: [PATCH v10 38/41] KVM: selftests: Provide common function to set memory attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-38-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=2853; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=xdN4ZWQbdwlWeMCPJmORdL69HRo7nJ3JUs6mr0GsFGA=; b=J3yaYIhg2jIJJRWFKdwmOsIyDJ+SH+Kn8SuUKsMZFCpJw3ZimQOG+05L/TtwXsEHYGOsRTh0N J7xNFvIddtEDnXye5qlJSO8GpoSBijHGfw80dk1AxzUzj6TG56zbHlY X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Introduce vm_mem_set_memory_attributes(), which handles setting of memory attributes for a range of guest physical addresses, regardless of whether the attributes should be set via guest_memfd or via the memory attributes at the VM level. Refactor existing vm_mem_set_{shared,private} functions to use the new function. Opportunistically update the size parameter to use size_t instead of u64. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/kvm_util.h | 46 +++++++++++++++++++---= ---- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 795c9eb311071..777fa3dbf88d6 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -454,18 +454,6 @@ static inline void vm_set_memory_attributes(struct kvm= _vm *vm, gpa_t gpa, vm_ioctl(vm, KVM_SET_MEMORY_ATTRIBUTES, &attr); } =20 -static inline void vm_mem_set_private(struct kvm_vm *vm, gpa_t gpa, - u64 size) -{ - vm_set_memory_attributes(vm, gpa, size, KVM_MEMORY_ATTRIBUTE_PRIVATE); -} - -static inline void vm_mem_set_shared(struct kvm_vm *vm, gpa_t gpa, - u64 size) -{ - vm_set_memory_attributes(vm, gpa, size, 0); -} - static inline int __gmem_set_memory_attributes(int fd, u64 offset, size_t size, u64 attributes, u64 *error_offset) @@ -532,6 +520,40 @@ static inline void gmem_set_shared(int fd, u64 offset,= size_t size) gmem_set_memory_attributes(fd, offset, size, 0); } =20 +static inline void vm_mem_set_memory_attributes(struct kvm_vm *vm, gpa_t g= pa, + size_t size, u64 attrs) +{ + if (kvm_has_gmem_attributes) { + gpa_t end =3D gpa + size; + off_t fd_offset; + gpa_t addr; + size_t len; + int fd; + + for (addr =3D gpa; addr < end; addr +=3D len) { + fd =3D kvm_gpa_to_guest_memfd(vm, addr, &fd_offset, &len); + len =3D min(end - addr, len); + + gmem_set_memory_attributes(fd, fd_offset, len, attrs); + } + } else { + vm_set_memory_attributes(vm, gpa, size, attrs); + } +} + +static inline void vm_mem_set_private(struct kvm_vm *vm, gpa_t gpa, + size_t size) +{ + vm_mem_set_memory_attributes(vm, gpa, size, + KVM_MEMORY_ATTRIBUTE_PRIVATE); +} + +static inline void vm_mem_set_shared(struct kvm_vm *vm, gpa_t gpa, + size_t size) +{ + vm_mem_set_memory_attributes(vm, gpa, size, 0); +} + void vm_guest_mem_fallocate(struct kvm_vm *vm, gpa_t gpa, u64 size, bool punch_hole); =20 --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 11846480DF1; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; cv=none; b=ljiSK0bFfgXKztGbcA6g05N5JGTbFcR71lhuhP8N2vhL2MtQX7vCZoPyDBhhFk4nAfMXveXBxwKGyvHOefCQvD1BRO7sbIpZ7Alo4nfK16pTMNsswyyIuIdnfuPr0pH4zBU6SrZzUhlxUhCdYkxKbNpAoC/sGrBcAwW6206eV/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; c=relaxed/simple; bh=3bvT48KSuQuZEHWe6t2FkyUOr6Jhx1D1LjQIlvlcTtU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ojE1NfmeWy++z5wSpTkEa7eydmCWfQZmV/0gQqgbRxSY1p+GtPY+2i4eRdlHBSGq8yeDJ60OpUPwNVxHRpZnIrw0bAFPQUwXfKwQNI1QAvzLjDD+r5BvhIrF32nI3XZ6EtfbXAdl9o5r3zT73TTVwGFqh8Pt5cWqp7677ioE2Q0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WdJTfsJG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WdJTfsJG" Received: by smtp.kernel.org (Postfix) with ESMTPS id B63E3C2BCB8; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=3bvT48KSuQuZEHWe6t2FkyUOr6Jhx1D1LjQIlvlcTtU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=WdJTfsJG+dviAG3RpV0CgPtWg+/VNrUTW0NJYk8oX+SgFQFIAO1rOl5AIM6ACz5Zn EYdrEn6ydG+bQdk5GMZH5/Q4cpybmmIfEPW/DBFKCkObpS6Una4D464+lkVwRD26Ka dF7RJvT8yEirNx8DGYzs4JddG5VjxYOq5XXRAVAizSVJeOSnO1RMM1IZ1n6DINvvel 0kHcEX5TImpjIiaImDKikvOqflP7lItXoH4k6eTLgJrmyDx60q8Z5rfM7MxbYvwOkP 1lAegE9S1RHQobE12Asn5dhNBjUnoXlQFjzjh9vc3SZ0/HxHxTMhh/aWQ5Lojd/GTW l+nYDZjuZgeLA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9066FC5AD2B; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:18 -0700 Subject: [PATCH v10 39/41] KVM: selftests: Make TEST_EXPECT_SIGBUS thread-safe Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-39-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5394; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=tdU5z+LCXvOvQLzia0/gtEnbi1rv7w6X4GxPcoXkDW4=; b=/LaLYdALqs1rtnp+ml2diPZISBcqycwNWeMqXcNyFESxKEKCOIvzxikPb87fFQPXSBkE+Dqdy 1/f52M8rhAxC5UTBLPF4g+28/4/M2oK9t+1o+17obcLvoqRwLgE/euG X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng The TEST_EXPECT_SIGBUS macro is not thread-safe as it uses a global sigjmp_buf and installs a global SIGBUS signal handler. If multiple threads execute the macro concurrently, they will race on installing the signal handler and stomp on other threads' jump buffers, leading to incorrect test behavior. Make TEST_EXPECT_SIGBUS thread-safe with the following changes: Share the KVM tests' global signal handler. sigaction() applies to all threads; without sharing a global signal handler, one thread may have removed the signal handler that another thread added, hence leading to unexpected signals. The alternative of layering signal handlers was considered, but calling sigaction() within TEST_EXPECT_SIGBUS() necessarily creates a race. To avoid adding new setup and teardown routines to do sigaction() and keep usage of TEST_EXPECT_SIGBUS() simple, share the KVM tests' global signal handler. Opportunistically rename report_unexpected_signal to catchall_signal_handler. To continue to only expect SIGBUS within specific regions of code, use a thread-specific variable, expecting_sigbus, to replace installing and removing signal handlers. Make the execution environment for the thread, sigjmp_buf, a thread-specific variable. As part of TEST_EXPECT_SIGBUS(), assert the prerequisite for this setup, that the current signal handler is the catchall_signal_handler. Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/include/test_util.h | 32 +++++++++++++--------= ---- tools/testing/selftests/kvm/lib/kvm_util.c | 18 ++++++++++---- tools/testing/selftests/kvm/lib/test_util.c | 7 ------ 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testin= g/selftests/kvm/include/test_util.h index d5825211f2727..75e98ec14107f 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -83,21 +83,23 @@ do { \ __builtin_unreachable(); \ } while (0) =20 -extern sigjmp_buf expect_sigbus_jmpbuf; -void expect_sigbus_handler(int signum); - -#define TEST_EXPECT_SIGBUS(action) \ -do { \ - struct sigaction sa_old, sa_new =3D { \ - .sa_handler =3D expect_sigbus_handler, \ - }; \ - \ - sigaction(SIGBUS, &sa_new, &sa_old); \ - if (sigsetjmp(expect_sigbus_jmpbuf, 1) =3D=3D 0) { \ - action; \ - TEST_FAIL("'%s' should have triggered SIGBUS", #action); \ - } \ - sigaction(SIGBUS, &sa_old, NULL); \ +extern __thread sigjmp_buf expect_sigbus_jmpbuf; +extern __thread volatile sig_atomic_t expecting_sigbus; +void catchall_signal_handler(int signum); + +#define TEST_EXPECT_SIGBUS(action) \ +do { \ + struct sigaction __sa =3D {}; \ + \ + TEST_ASSERT_EQ(sigaction(SIGBUS, NULL, &__sa), 0); \ + TEST_ASSERT_EQ(__sa.sa_handler, &catchall_signal_handler); \ + \ + expecting_sigbus =3D true; \ + if (sigsetjmp(expect_sigbus_jmpbuf, 1) =3D=3D 0) { \ + action; \ + TEST_FAIL("'%s' should have triggered SIGBUS", #action);\ + } \ + expecting_sigbus =3D false; \ } while (0) =20 size_t parse_size(const char *size); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 1188d0a6c0a5f..cac5624e99774 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2316,13 +2316,20 @@ __weak void kvm_selftest_arch_init(void) { } =20 -static void report_unexpected_signal(int signum) +__thread sigjmp_buf expect_sigbus_jmpbuf; +__thread volatile sig_atomic_t expecting_sigbus; + +void catchall_signal_handler(int signum) { + switch (signum) { + case SIGBUS: { + if (expecting_sigbus) + siglongjmp(expect_sigbus_jmpbuf, 1); + + TEST_FAIL("Unexpected SIGBUS (%d)\n", signum); + } #define KVM_CASE_SIGNUM(sig) \ case sig: TEST_FAIL("Unexpected " #sig " (%d)\n", signum) - - switch (signum) { - KVM_CASE_SIGNUM(SIGBUS); KVM_CASE_SIGNUM(SIGSEGV); KVM_CASE_SIGNUM(SIGILL); KVM_CASE_SIGNUM(SIGFPE); @@ -2334,12 +2341,13 @@ static void report_unexpected_signal(int signum) void __attribute((constructor)) kvm_selftest_init(void) { struct sigaction sig_sa =3D { - .sa_handler =3D report_unexpected_signal, + .sa_handler =3D catchall_signal_handler, }; =20 /* Tell stdout not to buffer its content. */ setbuf(stdout, NULL); =20 + expecting_sigbus =3D false; sigaction(SIGBUS, &sig_sa, NULL); sigaction(SIGSEGV, &sig_sa, NULL); sigaction(SIGILL, &sig_sa, NULL); diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/se= lftests/kvm/lib/test_util.c index 4dff72f6bd346..89d6d1b572959 100644 --- a/tools/testing/selftests/kvm/lib/test_util.c +++ b/tools/testing/selftests/kvm/lib/test_util.c @@ -19,13 +19,6 @@ #include "test_util.h" #include "kvm_syscalls.h" =20 -sigjmp_buf expect_sigbus_jmpbuf; - -void __attribute__((used)) expect_sigbus_handler(int signum) -{ - siglongjmp(expect_sigbus_jmpbuf, 1); -} - /* * Random number generator that is usable from guest code. This is the * Park-Miller LCG using standard constants. --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 12443481236; Fri, 7 Aug 2026 21:52:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; cv=none; b=WkBC1jF8GWWXeeAQh/00qS7pwGdRzRGvvRaFD0ZWCkShBw+TIfs4dM5tInjalu1zRFX8VqphLOcfxwbpWUKBbc4luIaHG2QPgZTHKG6VZleWkzVjWvXJ/Z6hyXO0awp8VN22QI+oun+SrZil/7w5BmwBRC19vKdt2uYGS3aEl5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; c=relaxed/simple; bh=GHSWZYSLno8Msa2SPYrlHj9df32+GxqTJOwRUqze0iE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ltJzCbBE8TMmQ2xMKB9c21EUP0QNCGlkqwC3HLx8n4owcmdyICORGvOBLrwn+0ut+dHlmTRRQG1RJqVkhQ+vUt/VeXG5DISVYqazHWl42q/36RHY1s8VmQaQf1aSSln5PakHQJ0rBFl9YSNrYrPWW1B0ObgnrAx7VvlYmmKMjcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aC2E1zsf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aC2E1zsf" Received: by smtp.kernel.org (Postfix) with ESMTPS id C87BFC2BCF7; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=GHSWZYSLno8Msa2SPYrlHj9df32+GxqTJOwRUqze0iE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=aC2E1zsfzrFQE9RxSweGEbZiA5AysFxQuaTloOQ1GpYKP9a65YYZwR7ADEx/na7wn tbKK/nsRHfTGo1nfdvx2VBM9u2HodDt5f4zvh9G9uGf7Thy90Bx4/pPpiy/Dk3YBVz gAlnDBX9fhiv/5qiLFZ67J45wFJqRkrQ4pFgpNwx29iWlDjt8ARbGGPf5x3Viper4e zOFk5fuxlz+iUccEWmLnr/q2Toof84LaojpVC+9+hUIm8VkL9yzryXwzr1n7GEGpS4 7KdsNDMVq7Eg1puTV92lVVhcOkyt6MyDv/y8mC6OChwYsjAJ9MIEI0bDyqRFwSObVa No9RonnZOP04Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8934C5AD44; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:19 -0700 Subject: [PATCH v10 40/41] KVM: selftests: Update private_mem_conversions_test to mmap() guest_memfd Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-40-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=5301; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=xs7fMwhgiH9Gq4d5OQ8oMbU9kMWBZd1SpkQeGjCZdt0=; b=xP2hZKeAJgSYqRy2w9Lz3AIrUj/JbXRETp2w1AQAHaWJdlfgRuY4D3v8O108f4UCAr37nhXB1 bmZHa7GmumwCY5zwoFF7pOTmIg20oysrFZ+iq5GiWk8se8Fz4Guzsbv X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Ackerley Tng Update the private memory conversions selftest to also test conversions that are done "in-place" via per-guest_memfd memory attributes. In-place conversions require the host to be able to mmap() the guest_memfd so that the host and guest can share the same backing physical memory. This includes several updates, that are conditioned on the system supporting per-guest_memfd attributes (kvm_has_gmem_attributes): 1. Set up guest_memfd requesting MMAP and INIT_SHARED. 2. With in-place conversions, the host's mapping points directly to the guest's memory. When the guest converts a region to private, host access to that region is blocked. Update the test to expect a SIGBUS when attempting to access the host virtual address (HVA) of private memory. 3. Use vm_mem_set_memory_attributes(), which chooses how to set memory attributes based on whether kvm_has_gmem_attributes. Restrict the test to using VM_MEM_SRC_SHMEM because guest_memfd's required mmap() flags and page sizes happens to align with those of VM_MEM_SRC_SHMEM. As long as VM_MEM_SRC_SHMEM is used for src_type, vm_mem_add() works as intended. Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../kvm/x86/private_mem_conversions_test.c | 44 ++++++++++++++++++= ---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c= b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c index cf50e9a332c5b..2af8d41963816 100644 --- a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c @@ -306,9 +306,12 @@ static void handle_exit_hypercall(struct kvm_vcpu *vcp= u) if (do_fallocate) vm_guest_mem_fallocate(vm, gpa, size, map_shared); =20 - if (set_attributes) - vm_set_memory_attributes(vm, gpa, size, - map_shared ? 0 : KVM_MEMORY_ATTRIBUTE_PRIVATE); + if (set_attributes) { + u64 attrs =3D map_shared ? 0 : KVM_MEMORY_ATTRIBUTE_PRIVATE; + + vm_mem_set_memory_attributes(vm, gpa, size, attrs); + } + run->hypercall.ret =3D 0; } =20 @@ -352,8 +355,20 @@ static void *__test_mem_conversions(void *__vcpu) size_t nr_bytes =3D min_t(size_t, vm->page_size, size - i); u8 *hva =3D addr_gpa2hva(vm, gpa + i); =20 - /* In all cases, the host should observe the shared data. */ - memcmp_h(hva, gpa + i, uc.args[3], nr_bytes); + /* + * When using per-guest_memfd memory attributes, + * i.e. in-place conversion, host accesses will + * point at guest memory and should SIGBUS when + * guest memory is private. When using per-VM + * attributes, i.e. separate backing for shared + * vs. private, the host should always observe + * the shared data. + */ + if (kvm_has_gmem_attributes && + uc.args[0] =3D=3D SYNC_PRIVATE) + TEST_EXPECT_SIGBUS(READ_ONCE(*hva)); + else + memcmp_h(hva, gpa + i, uc.args[3], nr_bytes); =20 /* For shared, write the new pattern to guest memory. */ if (uc.args[0] =3D=3D SYNC_SHARED) @@ -382,6 +397,7 @@ static void test_mem_conversions(enum vm_mem_backing_sr= c_type src_type, u32 nr_v const size_t slot_size =3D memfd_size / nr_memslots; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; pthread_t threads[KVM_MAX_VCPUS]; + u64 gmem_flags; struct kvm_vm *vm; int memfd, i; =20 @@ -397,12 +413,17 @@ static void test_mem_conversions(enum vm_mem_backing_= src_type src_type, u32 nr_v =20 vm_enable_cap(vm, KVM_CAP_EXIT_HYPERCALL, (1 << KVM_HC_MAP_GPA_RANGE)); =20 - memfd =3D vm_create_guest_memfd(vm, memfd_size, 0); + if (kvm_has_gmem_attributes) + gmem_flags =3D GUEST_MEMFD_FLAG_MMAP | GUEST_MEMFD_FLAG_INIT_SHARED; + else + gmem_flags =3D 0; + + memfd =3D vm_create_guest_memfd(vm, memfd_size, gmem_flags); =20 for (i =3D 0; i < nr_memslots; i++) vm_mem_add(vm, src_type, BASE_DATA_GPA + slot_size * i, BASE_DATA_SLOT + i, slot_size / vm->page_size, - KVM_MEM_GUEST_MEMFD, memfd, slot_size * i, 0); + KVM_MEM_GUEST_MEMFD, memfd, slot_size * i, gmem_flags); =20 for (i =3D 0; i < nr_vcpus; i++) { gpa_t gpa =3D BASE_DATA_GPA + i * per_cpu_size; @@ -452,17 +473,24 @@ static void usage(const char *cmd) =20 int main(int argc, char *argv[]) { - enum vm_mem_backing_src_type src_type =3D DEFAULT_VM_MEM_SRC; + enum vm_mem_backing_src_type src_type; u32 nr_memslots =3D 1; u32 nr_vcpus =3D 1; int opt; =20 TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_V= M)); =20 + src_type =3D kvm_has_gmem_attributes ? VM_MEM_SRC_SHMEM : + DEFAULT_VM_MEM_SRC; + while ((opt =3D getopt(argc, argv, "hm:s:n:")) !=3D -1) { switch (opt) { case 's': src_type =3D parse_backing_src_type(optarg); + TEST_ASSERT(!kvm_has_gmem_attributes || + src_type =3D=3D VM_MEM_SRC_SHMEM, + "Testing in-place conversions, only %s mem_type supported\n", + vm_mem_backing_src_alias(VM_MEM_SRC_SHMEM)->name); break; case 'n': nr_vcpus =3D atoi_positive("nr_vcpus", optarg); --=20 2.55.0.654.g21b8a5bc05-goog From nobody Wed Sep 30 13:54:33 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3009A48167A; Fri, 7 Aug 2026 21:52:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; cv=none; b=OOZoVkNi+Aj+jkRoWZsIiZiR7f4M7A6KvapKJI5tOKPaW0qOIqLgHamMzMmeATIvs+I6YekpTUk7AXV5DfA65m+DUApVFD4vu7dbhwmin1GvVKeN9QcAlTN2bQWOnhx/Kfu/lb67BfSF7dDhyQsoUHWQSpWfIcue/0jh91C+pfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786139572; c=relaxed/simple; bh=vTCEVKZlUYGO1D+z51D5hocvKIebLL912PEubVOUuJY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b7T9GCoGby95UUU4yy7a1cIUXlmjoYr2jDTXhbmboacekDE5In/xl739RVXe+zLiagFKoi7ICbPB/58tEH0kiiNQYYyPVRgtNgpMNF2Grj/EXVgwxWFowODH7gp8hma2O+53p626lum7mROEo6kxoi2sbcZSchC52teycIUmbEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q6k+aRHy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q6k+aRHy" Received: by smtp.kernel.org (Postfix) with ESMTPS id D77C2C2BCFF; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786139571; bh=vTCEVKZlUYGO1D+z51D5hocvKIebLL912PEubVOUuJY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Q6k+aRHy/8bmQ4Ezu6BObDrvY1H53BJJ932ktoEJCl5oedyReWQGnyPs2KEYHLgFT WUH+v96gxMjmcsUcrs0vuFYx/KGgKTiJLq2pTJtA1ut42GpTjG9uGqt1/vqL87Wu2p idOM5kcbg6r+rjFxfHsUZnwrJM6iOWlrxWvyjE8HQtwLTMgCzHeNC5elR1e73WnSjP Q0XtYxNwDimp50R53tvWS5AvEbzpwYT/h2Wqc55+KVD+0IJhhmsUwryl8tilQ9ULTO bRsqtlROQ4R0ALCGNyLX4rPcxu5T81v9p2QADwH4HsuxQJID76bqbwXHqvUMy25omK 3/SJc+O28xa7A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0A3EC5AD48; Fri, 7 Aug 2026 21:52:51 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Fri, 07 Aug 2026 14:53:20 -0700 Subject: [PATCH v10 41/41] KVM: selftests: Update private memory exits test to work with per-gmem attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260807-gmem-inplace-conversion-v10-41-2fc18ee6d3ba@google.com> References: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> In-Reply-To: <20260807-gmem-inplace-conversion-v10-0-2fc18ee6d3ba@google.com> To: aik@amd.com, andrew.jones@linux.dev, binbin.wu@linux.intel.com, brauner@kernel.org, chao.p.peng@linux.intel.com, david@kernel.org, jmattson@google.com, jthoughton@google.com, michael.roth@amd.com, oupton@kernel.org, pankaj.gupta@amd.com, qperret@google.com, rick.p.edgecombe@intel.com, rientjes@google.com, shivankg@amd.com, steven.price@arm.com, tabba@google.com, willy@infradead.org, wyihan@google.com, yan.y.zhao@intel.com, forkloop@google.com, pratyush@kernel.org, suzuki.poulose@arm.com, aneesh.kumar@kernel.org, liam@infradead.org, Paolo Bonzini , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , Shuah Khan , Vishal Annapurve , Andrew Morton , Chris Li , Kairui Song , Kemeng Shi , Nhat Pham , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Youngjun Park , Qi Zheng , Shakeel Butt , Kiryl Shutsemau , Baoquan He , Jason Gunthorpe , John Hubbard , Peter Xu , tarunsahu@google.com, Jason Gunthorpe , Vlastimil Babka , Baoquan He Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-coco@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786139565; l=3875; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=lUvT16Y2a9GQsXboRcAXXwS4SVcVvLUE9PQbscannXc=; b=RHgI6k3Qdcn2KcFNrAue0i6g/CNiZUlSD125Ql3KxD4G4Y+EqRZTNa9NXQvYC6mjhDdbURQ1i hreDiZbMWy9BQrYjVxBBA36GyD9KdbNAuCR/uoQvC6duAUACoi+C4L+ X-Developer-Key: i=ackerleytng@google.com; a=ed25519; pk=sAZDYXdm6Iz8FHitpHeFlCMXwabodTm7p8/3/8xUxuU= X-Endpoint-Received: by B4 Relay for ackerleytng@google.com/20260225 with auth_id=649 X-Original-From: Ackerley Tng Reply-To: ackerleytng@google.com From: Sean Christopherson Skip setting memory to private in the private memory exits test when using per-gmem memory attributes, as memory is initialized to private by default for guest_memfd, and using vm_mem_set_private() on a guest_memfd instance requires creating guest_memfd with GUEST_MEMFD_FLAG_MMAP (which is totally doable, but would need to be conditional and is ultimately unnecessary). Expect an emulated MMIO instead of a memory fault exit when attributes are per-gmem, as deleting the memslot effectively drops the private status, i.e. the GPA becomes shared and thus supports emulated MMIO. Skip the "memslot not private" test entirely, as private vs. shared state for x86 software-protected VMs comes from the memory attributes themselves, and so when doing in-place conversions there can never be a disconnect between the expected and actual states. Signed-off-by: Sean Christopherson Reviewed-by: Fuad Tabba Tested-by: Shivank Garg Signed-off-by: Ackerley Tng --- .../selftests/kvm/x86/private_mem_kvm_exits_test.c | 36 ++++++++++++++++++= ---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c b= /tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c index e6d16e9d61200..f7228e0f1ac61 100644 --- a/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c +++ b/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c @@ -62,8 +62,9 @@ static void test_private_access_memslot_deleted(void) =20 virt_map(vm, EXITS_TEST_GVA, EXITS_TEST_GPA, EXITS_TEST_NPAGES); =20 - /* Request to access page privately */ - vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE); + /* Request to access page privately. */ + if (!kvm_has_gmem_attributes) + vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE); =20 kvm_pthread_create(&vm_thread, NULL, (pthread_fn_t)run_vcpu_get_exit_reason, (void *)vcpu); @@ -73,10 +74,26 @@ static void test_private_access_memslot_deleted(void) kvm_pthread_join(vm_thread, &thread_return); exit_reason =3D (u32)(u64)thread_return; =20 - TEST_ASSERT_EQ(exit_reason, KVM_EXIT_MEMORY_FAULT); - TEST_ASSERT_EQ(vcpu->run->memory_fault.flags, KVM_MEMORY_EXIT_FLAG_PRIVAT= E); - TEST_ASSERT_EQ(vcpu->run->memory_fault.gpa, EXITS_TEST_GPA); - TEST_ASSERT_EQ(vcpu->run->memory_fault.size, EXITS_TEST_SIZE); + /* + * If attributes are tracked per-gmem, deleting the memslot that points + * at the gmem instance effectively makes the memory shared, and so the + * read should trigger emulated MMIO. + * + * If attributes are tracked per-VM, deleting the memslot shouldn't + * affect the private attribute, and so KVM should generate a memory + * fault exit (emulated MMIO on private GPAs is disallowed). + */ + if (kvm_has_gmem_attributes) { + TEST_ASSERT_EQ(exit_reason, KVM_EXIT_MMIO); + TEST_ASSERT_EQ(vcpu->run->mmio.phys_addr, EXITS_TEST_GPA); + TEST_ASSERT_EQ(vcpu->run->mmio.len, sizeof(u64)); + TEST_ASSERT_EQ(vcpu->run->mmio.is_write, false); + } else { + TEST_ASSERT_EQ(exit_reason, KVM_EXIT_MEMORY_FAULT); + TEST_ASSERT_EQ(vcpu->run->memory_fault.flags, KVM_MEMORY_EXIT_FLAG_PRIVA= TE); + TEST_ASSERT_EQ(vcpu->run->memory_fault.gpa, EXITS_TEST_GPA); + TEST_ASSERT_EQ(vcpu->run->memory_fault.size, EXITS_TEST_SIZE); + } =20 kvm_vm_free(vm); } @@ -87,6 +104,13 @@ static void test_private_access_memslot_not_private(voi= d) struct kvm_vcpu *vcpu; u32 exit_reason; =20 + /* + * Accessing non-private memory as private with a software-protected VM + * isn't possible when doing in-place conversions. + */ + if (kvm_has_gmem_attributes) + return; + vm =3D vm_create_shape_with_one_vcpu(protected_vm_shape, &vcpu, guest_repeatedly_read); =20 --=20 2.55.0.654.g21b8a5bc05-goog