From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1792711701; b=wJKNXixzmph5INYACP/86u9nPMAbgBwZdpZ7UTyDYI+JhBUS9n7VanRfJg7h1ySBObaL 8nQOOAvNSK5F4w9cIYnQTFDhb1xJB1BTPpwUGKcQQy82ONSh9RhCFQOA9uZ673+V5gp6y nJbfgpDGA4GI7ivhBksw+2HptFs6IHBxcP1v/kiPVfOIzuTcUpzTusJfH9Oawmepn1wTC dfFDTjEE4t28VQ2oOBtjpKtZEAQErdAogheQTmA/OdZwJbxLaHi6H2P+dkJy12VJK/6Av UBPJPVewrpyJbjNAHXclgHhRG52WbSCNPGCB5cIznbaPlBWwYdneCRR3Fup18VvRGMA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792711701; h=Received:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=wQV3qQ3k9uCjoMdvwJYY0xKD7Do9569EVepxRPPnbCc=; b=HWHHbH5aGLzGoPrF3xyZQEauQ1KCrz3VS+0dWrOTih9XdqRetaVVVq8veqw7PFKf33Rq kDhNtQMJZ/+kb2/la2RBJiWveNdMATOScHnUg6uDBRAAlfbBoYk7J/4tSF10czeizTjrl 6BJ/1M6Fr89HAVQDsIlGHK6z+9xCV9lQrOQlb6ceuo/da4PWRDG5qHZyvyRkTHNRPHY6d jaLQXGx64tmqRIHbcf1fqXtqiRt6wxM1hxAOM5yAEp+chDpgavPjpeUPwwISz4wEjRp2x 9jI18Sdc13f9N4HvMCVFIBpdZPHbDH2VF1tokw0t74ar9WrPrxTlGNBKCpKU9tMYIhA== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=lN0x9ppN; arc=pass header.oldest-pass=0 smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E5A3606AA52; Thu, 22 Oct 2026 23:28:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=lN0x9ppN Authentication-Results: smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 ARC-Seal: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; cv=none; t=1792711701; b=BQZabtI2ZET+iUXjaDtrRzn26GfKmQPO/N2J+gKIocNpc+FI0Yn9byyeD/ZOoCYws06l y+tqrmQtvp+qlRnyfI1CVv9xkLghtGNUEfQCORmhYUR0IZC/OO+NVepq1tUNDc3osA6l/ dQtICKAMjgMf4yIflCTvi5rghPBM6Qywou9hzoy4qvO+EKL0nsVSlgF4wIYQYlO/9Myai r79zu8ilQTPXsLwevX2O+IQXCSi3FK4/WHXVP59lpBg93xdPSUqnmLGEgyBBUWYjYE+G0 HFelUmHgMwSF+a6KzWZquRroIBX//4W8EQ7hpDnUuvrOcEsDXacrONaAsx7Umxs+H2g== ARC-Message-Signature: i=1; d=kernel.org; s=arc20260519; a=rsa-sha256; c=relaxed/relaxed; t=1792711701; h=DKIM-Signature:Received:From:Date:Subject:MIME-Version:Content-Type: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key:X-Endpoint-Received: X-Original-From:Reply-To:Content-Transfer-Encoding; bh=wQV3qQ3k9uCjoMdvwJYY0xKD7Do9569EVepxRPPnbCc=; b=ybqmtpsqyxJtm9vPfcza55mVhuD2ib4pJT8JJFrex2U6lM9q896T0Uw+rGquPOX0Z31R uu/B/nPd5VhV30oO+N5sBmmQUuc8Jlgix3KxQAWfgeStM5HJdV6ZHpPasuqA2sOEcKnPj 7jXZVWxXb/Q0pk8QuVyCW4dQ3uYYkBIkZCF2oCcXMm1YC5aMGPMSbZesfdSA45yRkAf86 2WtgdIc5eJyRiLlVupukx+hl/0gOJTpftICmmkg6qmW437cZ1tY+PUfxx78MDCz7Kf8R+ 0pKwjf7fOs8AZ7qFfrp0mEqk2oHCOnSy51FfWq8VvlvHbwVH2dwgGz5VziSVj+0P4hQ== ARC-Authentication-Results: i=1; smtp.kernel.org; arc=none smtp.remote-ip=100.80.115.77 Received: from lkml.kernel.org (nexus.subspace.kernel.org [100.80.115.77]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.kernel.org (Postfix) with ESMTPS id 8FC461F011BD; Thu, 22 Oct 2026 23:28:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792711701; bh=wQV3qQ3k9uCjoMdvwJYY0xKD7Do9569EVepxRPPnbCc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To; b=lN0x9ppNPS44uy+ho+SdOpER4/D1FSzCTpjESm1KrU0LKAltU6hxv/854A00vrQEa NCRfwcQFu3qiksEBhbd+RRaC2nhiTkKwzOPy87lWWFAdghkxLRMguk5i+oFmS1homG 5SygOBk5wb6j802l/cnsvlyrmEnK/IemHgJ71S26gFeCMAPWHxcIellK5VVrauQ+9j upIR2kCwu2NXVX3h8PCyAgcWB/ljNWe+6nK39o6gPaHQsHaoSTsR4TR5AofE3jWIUi eua0g7icM3KC1wmrkTFCLhef2S7rIQcHcp6/o10peO0q/47BHCYef6UwLSga80sNip SinU2y5mNbxgw== Received: from nexus.subspace.kernel.org (localhost [IPv6:::1]) by lkml.kernel.org (Postfix) with ESMTP id D6DCC420C8; Thu, 22 Oct 2026 23:27:49 +0000 (UTC) From: Ackerley Tng via B4 Relay Date: Thu, 22 Oct 2026 16:28:05 -0700 Subject: [PATCH RFC v2 33/50] KVM: guest_memfd: Support mmap and user fault handling in PFN mode X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Message-Id: <20261022-gmem-alternative-providers-v2-33-5dd1dc6c660a@google.com> References: <20261022-gmem-alternative-providers-v2-0-5dd1dc6c660a@google.com> In-Reply-To: <20261022-gmem-alternative-providers-v2-0-5dd1dc6c660a@google.com> To: Alex Williamson , Alexander Graf , Alexander Viro , Alexey Kardashevskiy , Andrew Morton , "Aneesh Kumar K.V" , Ashish Kalra , Baolin Wang , Baolu Lu , Bill Wendling , Borislav Petkov , Catalin Marinas , Christian Brauner , =?utf-8?q?Christian_K=C3=B6nig?= , Connor Williamson , Dave Hansen , Dave Jiang , David Hildenbrand , David Rientjes , David Woodhouse , Erdem Aktas , Frank van der Linden , Fred Griffoul , Fred Griffoul , Gregory Price , "H. Peter Anvin" , Hugh Dickins , Ingo Molnar , Jacob Pan , James Houghton , Jan Kara , Jason Gunthorpe , Jianxiong Gao , Joerg Roedel , Joey Gouly , John Starks , Jonathan Corbet , Justin Stitt , Kevin Tian , Lorenzo Stoakes , Marc Zyngier , Michael Roth , Mike Rapoport , Nathan Chancellor , Nick Desaulniers , Nicolin Chen , Oliver Upton , Paolo Bonzini , Pratyush Yadav , Randy Dunlap , Robin Murphy , Samiullah Khawaja , Sean Christopherson , Shuah Khan , Steffen Eiden , Steven Price , Suzuki K Poulose , Tarun Sahu , Thomas Gleixner , Tom Lendacky , Tycho Andersen , Vishal Annapurve , Vlastimil Babka , Will Deacon , Xu Yilun , Yan Zhao , Zenghui Yu , x86@kernel.org, Shuah Khan , Fuad Tabba Cc: kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, llvm@lists.linux.dev, Ackerley Tng X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=ed25519-sha256; t=1792711665; l=3706; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=elLIGBYw0BUJ9IbNw0ScjqZOWht3JZnml1/BafVIxxA=; b=VW4cbdmPxp6Pao5q+UBf9fgRtR76zuJjTkAk5Ko45CrogkVItmv81as/Lvua8wCNXiykVR6H/ c7oDGQMzSZXBixMwnUcjgTlSfcnS1H0bfnLQ5pnFxQgPtZqsEOfFJds 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 Content-Transfer-Encoding: 7bit From: Ackerley Tng In PFN mode, guest_memfd memory is backed by raw PFNs rather than page-cache folios. Mark the VMA with VM_PFNMAP when setting up the VMA in PFN mode, and insert the PFN into the user page tables during fault handling. In folio mode, the fault handler obtains a locked folio under the shared filemap invalidation lock and returns with the folio still locked so the core fault handler installs the PTE before unlocking the folio. Any concurrent truncation or invalidation must wait on the folio lock before unmapping and removing the folio. In PFN mode, there is no folio lock to bridge the gap after dropping the shared filemap invalidation lock. If the lock were dropped before inserting the PFN into the page tables, a concurrent hole punch or provider-driven revocation could acquire the exclusive filemap invalidation lock, unmap existing mappings (missing the not-yet-mapped PTE), and reclaim the backing memory, only for the fault handler to subsequently install a stale PTE pointing to the revoked PFN. Keep the shared filemap invalidation lock held across PFN insertion so that obtaining the PFN and installing the PTE are atomic with respect to operations holding the exclusive filemap invalidation lock. For provider-driven revocation to safely tear down mappings without races, the provider must first mark the range unavailable so new faults fail, and then invoke revocation, which acquires the exclusive filemap invalidation lock to wait for any in-flight faults to finish installing their PTEs before unmapping them. This also requires providers not to hold any lock across revocation that is also acquired during PFN lookup. Signed-off-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 8588912cb0b82..50031e191968b 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -562,8 +562,10 @@ static bool kvm_gmem_supports_mmap(struct inode *inode) static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) { struct inode *inode = file_inode(vmf->vma->vm_file); + struct gmem_inode *gi = GMEM_I(inode); vm_fault_t ret = VM_FAULT_LOCKED; struct folio *folio = NULL; + kvm_pfn_t pfn; int r = 0; if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode)) @@ -572,6 +574,10 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) filemap_invalidate_lock_shared(inode->i_mapping); if (!kvm_gmem_is_shared_mem(inode, vmf->pgoff)) { r = -EACCES; + } else if (kvm_gmem_is_pfn_mode(gi)) { + r = gmem_provider_get_pfn(gi, vmf->pgoff, &pfn, NULL); + if (!r) + ret = vmf_insert_pfn(vmf->vma, vmf->address, pfn); } else { folio = kvm_gmem_get_folio(inode, vmf->pgoff); if (IS_ERR(folio)) @@ -586,6 +592,9 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) return vmf_error(r); } + if (kvm_gmem_is_pfn_mode(gi)) + return ret; + if (WARN_ON_ONCE(folio_test_large(folio))) { ret = VM_FAULT_SIGBUS; goto out_folio; @@ -646,6 +655,8 @@ static const struct vm_operations_struct kvm_gmem_vm_ops = { static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) { + struct gmem_inode *gi = GMEM_I(file_inode(file)); + if (!kvm_gmem_supports_mmap(file_inode(file))) return -ENODEV; @@ -654,6 +665,9 @@ static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } + if (kvm_gmem_is_pfn_mode(gi)) + vm_flags_set(vma, VM_PFNMAP); + vma->vm_ops = &kvm_gmem_vm_ops; return 0; -- 2.56.0.257.gf7497c7d27-goog