From mboxrd@z Thu Jan 1 00:00:00 1970 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 0B4A519CC14; Fri, 19 Jun 2026 00:31:46 +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=1781829107; cv=none; b=BVBWaHxWdwck+NFcvfR7yXr9DWKSmAMYK97qMicf83kdn3tDy5rDNWSaZ4wBjYty18vxnXBBENxoiPEsRNHF6pgdtVocMBpJUaLvXGdSzm0cLzpLk5CysRo8lNNhenCEV3u+J4dR4bWTDVpzuFeJNNAwMD3oh+9chKf0F6GbqP0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781829107; c=relaxed/simple; bh=DmHNL9HxSc5i2u3ht7onNcHWKGGg3Cvj27v8XN2B4Aw=; h=From:Subject:Date:Message-Id:MIME-Version:Content-Type:To:Cc; b=F1fhDjGe9Hg6EXSK1cX2wtBe8K5XAiG3xF7Op6e+eOsOmaJgnAsMfFvzprwDmJ5dhqjMbKZhwuTpZshF/i3l5L5MlvhaW4pL9eVjkyhYxNunZBESd4Hq/vYX679ZzGmGyNjl2aokfBh3ErGaA5voKUjBz/09N3Vdz2osS3cyhmA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hKvGwGw/; 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="hKvGwGw/" Received: by smtp.kernel.org (Postfix) with ESMTPS id B6C03C2BCC6; Fri, 19 Jun 2026 00:31:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1781829106; bh=DmHNL9HxSc5i2u3ht7onNcHWKGGg3Cvj27v8XN2B4Aw=; h=From:Subject:Date:To:Cc:Reply-To:From; b=hKvGwGw/ob0U0hveEirgB0m42RfrDrohMgophiUN/7SsKvW6aJR+tooxTgBucoi4z YVSKxRH5PVjYMK4QtviHRZ25RshTQGhXXFae0mQgST2ahPKL9gGhNKAuvCGxMp4N7m ieV2HHCmhVTZlG5yWtcEFSmBUn9VnDn4wGtdAnLCOWzvi0YQ+s/7ZWbS6fEGXprCBB obdGygzcISP97ZOMPIHnaMG+AItiqy/beV19vyDllCrN7KKeWGxnE5wsxn7/hlbKxa uRr/kxp4enIZpMBzTm59/GdsIEYFw1t4K1luphr08+HgMl4ER6W1WUtHl0gxQj1FTU Btuetpk8sRAkg== 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 8E630CD98F0; Fri, 19 Jun 2026 00:31:46 +0000 (UTC) From: Ackerley Tng via B4 Relay Subject: [PATCH v8 00/46] guest_memfd: In-place conversion support Date: Thu, 18 Jun 2026 17:31:37 -0700 Message-Id: <20260618-gmem-inplace-conversion-v8-0-9d2959357853@google.com> 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: 7bit X-B4-Tracking: v=1; b=H4sIAOqNNGoC/3XRS26DMBAG4KtEXtetsfErq96j6sKPMVgNkBqKU kW5e4ewSCrEcuSZb6z5r2SEkmEkx8OVFJjzmIceC/NyIKF1fQM0R6wJZ1wxziVtOuho7s8nF4C GoZ+hLDPURxZ9FFZL4QhOnwukfLnLH59YezcC9cX1oV28r7l76+EyLa1tHqeh/N7/MItlYF0nK rG7bhaUUZlCxZ1mEIx9b4ahOcFrGDqy7JvrJ4irfahGCLAtgZUspbiB5AOqudmHJELRKGZCSMF xvoHUA5JM70MKIVs5L53xlXX1BtJPEOf7kEaIJ5Yc1FZJwf5BtzWkAt8/mPq0JrXGhO9dno4Hr 5MH6yqfLIAKVmlIWkehVHDSBIH3T5UxGrHbHw/lk/dKAgAA X-Change-ID: 20260225-gmem-inplace-conversion-bd0dbd39753a 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 , 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=1781829104; l=10113; i=ackerleytng@google.com; s=20260225; h=from:subject:message-id; bh=DmHNL9HxSc5i2u3ht7onNcHWKGGg3Cvj27v8XN2B4Aw=; b=Fphn+UWGofkr9D7C0HN4P2Rzn1gYU/RvmfDEDLBaB854QD3We/tF+yrWMsjXXZR3P/7AIXLB7 sOU1ochoQAbCZJHbWnZ3wqbYF3FzCYhR4LCLdK6gZn+kjUwXbIyi6Tu 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 This is v8 of guest_memfd in-place conversion support. Up till now, guest_memfd supports the entire inode worth of memory being used as all-shared, or all-private. CoCo VMs may request guest memory to be converted between private and shared states, and the only way to support that currently would be to have the userspace VMM provide two sources of backing memory from completely different areas of physical memory. pKVM has a use case for in-place sharing: the guest and host may be cooperating on given data, and pKVM doesn't protect data through encryption, so copying that given data between different areas of physical memory as part of conversions would be unnecessary work. This series also serves as a foundation for guest_memfd huge page support. Now, guest_memfd only supports PAGE_SIZE pages, so if two sources of backing memory are used, the userspace VMM could maintain a steady total memory utilized by punching out the pages that are not used. When huge pages are available in guest_memfd, even if the backing memory source supports hole punching within a huge page, punching out pages to maintain the total memory utilized by a VM would be introducing lots of fragmentation. In-place conversion avoids fragmentation by allowing the same physical memory to be used for both shared and private memory, with guest_memfd tracks the shared/private status of all the pages at a per-page granularity. The central principle, which guest_memfd continues to uphold, is that any guest-private page will not be mappable to host userspace. All pages will be mmap()-able in host userspace, but accesses to guest-private pages (as tracked by guest_memfd) will result in a SIGBUS. This series introduces a guest_memfd ioctl (not kvm, vm or vcpu, but guest_memfd ioctl) that allows userspace to set memory attributes (shared/private) directly through the guest_memfd. This is the appropriate interface because shared/private-ness is a property of memory and hence the request should be sent directly to the memory provider - guest_memfd. Tested with both CONFIG_KVM_VM_MEMORY_ATTRIBUTES enabled and disabled: + tools/testing/selftests/kvm/guest_memfd_test.c + tools/testing/selftests/kvm/pre_fault_memory_test.c + tools/testing/selftests/kvm/x86/guest_memfd_conversions_test.c + tools/testing/selftests/kvm/x86/private_mem_conversions_test.c + tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c Updates for this revision: + Updated the series to _not_ deprecate all of VM memory attributes, but only deprecate tracking of the PRIVATE attributes in VM memory attributes. This takes into account upcoming RWX attributes support, which will be tracked at the VM level. + Reshuffled the earlier commits that deal with preparing KVM to stop seeing VM memory attributes as the only source of attributes. + Addressed comments from v7 TODOs + Retest with TDX selftests. v7 was tested with TDX [12], but the setup there was wrong. Conversions were successful (no errors), but the shared memory being tested is actually in a completely different host physical page. + Retest with SNP selftests. v6 was tested with SNP, I ported that to v7 and those ran fine too. Just need to double-check for v8. This series is based on kvm-x86/next, and here's the tree for your convenience: https://github.com/googleprodkernel/linux-cc/commits/guest_memfd-inplace-conversion-v8 Older series: + RFCv7 is at [11] + RFCv6 is at [10] + RFCv5 is at [8] + RFCv4 is at [7] + RFCv3 is at [6] + RFCv2 is at [5] + RFCv1 is at [4] + Previous versions of this feature, part of other series, are available at [1][2][3]. [1] https://lore.kernel.org/all/bd163de3118b626d1005aa88e71ef2fb72f0be0f.1726009989.git.ackerleytng@google.com/ [2] https://lore.kernel.org/all/20250117163001.2326672-6-tabba@google.com/ [3] https://lore.kernel.org/all/b784326e9ccae6a08388f1bf39db70a2204bdc51.1747264138.git.ackerleytng@google.com/ [4] https://lore.kernel.org/all/cover.1760731772.git.ackerleytng@google.com/T/ [5] https://lore.kernel.org/all/cover.1770071243.git.ackerleytng@google.com/T/ [6] https://lore.kernel.org/r/20260313-gmem-inplace-conversion-v3-0-5fc12a70ec89@google.com/T/ [7] https://lore.kernel.org/all/20260326-gmem-inplace-conversion-v4-0-e202fe950ffd@google.com/T/ [8] https://lore.kernel.org/r/20260428-gmem-inplace-conversion-v5-0-d8608ccfca22@google.com [9] https://lore.kernel.org/all/20260414-selftest-global-metadata-v1-0-fd223922bc57@google.com/T/ [10] https://lore.kernel.org/r/20260507-gmem-inplace-conversion-v6-0-91ab5a8b19a4@google.com [11] https://lore.kernel.org/r/20260522-gmem-inplace-conversion-v7-0-2f0fae496530@google.com [12] https://lore.kernel.org/all/20260605134153.204152-1-ackerleytng@google.com/ Signed-off-by: Ackerley Tng --- Ackerley Tng (27): KVM: Make CONFIG_KVM_VM_MEMORY_ATTRIBUTES selectable KVM: Enumerate support for PRIVATE memory iff kvm_arch_has_private_mem is defined KVM: guest_memfd: Introduce function to check GFN private/shared status KVM: guest_memfd: Only prepare folios for private pages KVM: guest_memfd: Add base support for KVM_SET_MEMORY_ATTRIBUTES2 KVM: guest_memfd: Ensure pages are not in use before conversion KVM: guest_memfd: Call arch invalidate hooks on conversion KVM: guest_memfd: Return early if range already has requested attributes KVM: guest_memfd: Advertise KVM_SET_MEMORY_ATTRIBUTES2 ioctl KVM: guest_memfd: Handle lru_add fbatch refcounts during conversion safety check KVM: guest_memfd: Use actual size for invalidation in kvm_gmem_release() KVM: guest_memfd: Determine invalidation filter from memory attributes KVM: guest_memfd: Zero page while getting pfn KVM: TDX: Make source page optional for KVM_TDX_INIT_MEM_REGION KVM: guest_memfd: Make in-place conversion the default KVM: selftests: Test basic single-page conversion flow KVM: selftests: Test conversion flow when INIT_SHARED KVM: selftests: Test conversion precision in guest_memfd KVM: selftests: Test conversion before allocation KVM: selftests: Convert with allocated folios in different layouts KVM: selftests: Test that truncation does not change shared/private status KVM: selftests: Add helpers to pin pages with CONFIG_GUP_TEST KVM: selftests: Test conversion with elevated page refcount KVM: selftests: Reset shared memory after hole-punching KVM: selftests: Provide function to look up guest_memfd details from gpa KVM: selftests: Make TEST_EXPECT_SIGBUS thread-safe KVM: selftests: Update private_mem_conversions_test to mmap() guest_memfd Michael Roth (1): KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE Sean Christopherson (18): KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings KVM: Rename KVM_GENERIC_MEMORY_ATTRIBUTES to KVM_VM_MEMORY_ATTRIBUTES KVM: Move KVM_VM_MEMORY_ATTRIBUTES config definition to x86 KVM: Decouple kvm_has_arch_private_mem from CONFIG_KVM_VM_MEMORY_ATTRIBUTES KVM: Rename memory attribute APIs to prepare for in-place gmem conversion KVM: Provide generic interface for checking memory private/shared status KVM: guest_memfd: Wire up core private/shared attribute interfaces KVM: Consolidate private memory and guest_memfd ifdeffery in kvm_host.h KVM: guest_memfd: Enable INIT_SHARED on guest_memfd for x86 Coco VMs KVM: selftests: Create gmem fd before "regular" fd when adding memslot KVM: selftests: Rename guest_memfd{,_offset} to gmem_{fd,offset} KVM: selftests: Add support for mmap() on guest_memfd in core library KVM: selftests: Add selftests global for guest memory attributes capability KVM: selftests: Add helpers for calling ioctls on guest_memfd KVM: selftests: Test that shared/private status is consistent across processes KVM: selftests: Provide common function to set memory attributes KVM: selftests: Check fd/flags provided to mmap() when setting up memslot KVM: selftests: Update private memory exits test to work with per-gmem attributes Documentation/virt/kvm/api.rst | 78 +++- .../virt/kvm/x86/amd-memory-encryption.rst | 13 +- Documentation/virt/kvm/x86/intel-tdx.rst | 4 + arch/x86/include/asm/kvm_host.h | 4 +- arch/x86/kvm/Kconfig | 15 +- arch/x86/kvm/mmu/mmu.c | 8 +- arch/x86/kvm/svm/sev.c | 16 +- arch/x86/kvm/vmx/tdx.c | 11 +- arch/x86/kvm/x86.c | 15 +- include/linux/kvm_host.h | 74 +-- include/trace/events/kvm.h | 4 +- include/uapi/linux/kvm.h | 16 + mm/swap.c | 2 + tools/testing/selftests/kvm/Makefile.kvm | 1 + tools/testing/selftests/kvm/include/kvm_util.h | 139 +++++- tools/testing/selftests/kvm/include/test_util.h | 34 +- tools/testing/selftests/kvm/lib/kvm_util.c | 164 ++++--- tools/testing/selftests/kvm/lib/test_util.c | 7 - .../kvm/x86/guest_memfd_conversions_test.c | 509 +++++++++++++++++++++ .../kvm/x86/private_mem_conversions_test.c | 53 ++- .../selftests/kvm/x86/private_mem_kvm_exits_test.c | 36 +- virt/kvm/Kconfig | 4 +- virt/kvm/guest_memfd.c | 474 +++++++++++++++++-- virt/kvm/kvm_main.c | 86 +++- 24 files changed, 1547 insertions(+), 220 deletions(-) --- base-commit: b7fbe9a1bf9ee6c967ef77d366ca58c35fcf1887 change-id: 20260225-gmem-inplace-conversion-bd0dbd39753a Best regards, -- Ackerley Tng