v12 2026-08-31

guest_memfd就地转换 · v12

v12共45个补丁完善KVM guest_memfd:转换开销优化、per-gmem属性、私有内存支持等。

原始补丁链接

子 Patch(45)

1/45
KVM: guest_memfd: Optimize away conversion overheads via dead-code elimination
引入kvm_arch_has_gmem_convert()宏来守卫guest_memfd调用arch转换钩子,x86只有一半需要运行时钩子,通过死代码消除去掉空调开销,并提供kvm_arch_gmem_make_private声明。
2/45
KVM: guest_memfd: Use kvm_mem_is_private() when populating guest_memfd memory
在kvm_gmem_populate()中用kvm_mem_is_private()替代等价的open-coded判断,简化当前逻辑并可避免将来提供range-based gmem查找API。
3/45
KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings
为guest_memfd引入maple树跟踪每inode的private/shared属性,用filemap_invalidate_lock保护;在kvm_gmem_get_pfn中先释放folio引用再解锁,避免转换请求看到陈旧高refcount。
4/45
KVM: Rename KVM_GENERIC_MEMORY_ATTRIBUTES to KVM_VM_MEMORY_ATTRIBUTES
将KVM_GENERIC_MEMORY_ATTRIBUTES Kconfig改名为KVM_VM_MEMORY_ATTRIBUTES,明确其per-VM属性语义,为后续引入guest_memfd独立内存属性追踪做准备,无功能变化。
5/45
KVM: Enumerate support for PRIVATE memory iff kvm_arch_has_private_mem is defined
报告KVM_MEMORY_ATTRIBUTE_PRIVATE支持改为仅当kvm_arch_has_private_mem宏定义时,去除与CONFIG_KVM_VM_MEMORY_ATTRIBUTES的耦合,防止arm64在系统范围检查时误报PRIVATE支持。
6/45
KVM: Rename memory attribute APIs to prepare for in-place gmem conversion
将内存属性API重命名加入vm_前缀,如kvm_vm_set_mem_attributes()改为kvm_set_vm_mem_attributes(),以区分未来guest_memfd自身的属性来源,trace函数同步更新。
7/45
KVM: Rename kvm_mem_is_private() to kvm_is_private_gfn()
把kvm_mem_is_private()改名为kvm_is_private_gfn(),为将来kvm_vm_is_private_gfn()和kvm_gmem_is_private_gfn()两个查询函数提供一致的命名前缀。
8/45
KVM: Provide generic interface for checking memory private/shared status
用static call提供通用kvm_is_private_gfn()接口,运行时选择实现;现有基于VM属性的检查改名为kvm_vm_is_private_gfn(),为切换gmem查找做准备。
9/45
KVM: guest_memfd: Stub in ability to enable in-place shared<=>private conversion
新增全局变量gmem_in_place_conversion用于启用in-place转换,并将__kvm_is_private_gfn() static call指向guest_memfd版本,后续会暴露为模块参数。
10/45
KVM: Consolidate private memory and guest_memfd ifdeffery in kvm_host.h
在kvm_host.h中整理private memory与guest_memfd相关#ifdeffery,把kvm_arch_has_private_mem() stub和相关函数声明移到已有条件编译块内,代码聚类无功能变化。
11/45
KVM: guest_memfd: Invalidate both SHARED and PRIVATE mappings for in-place conversions
in-place转换启用时,从guest_memfd移除folio需同时invalidate SHARED和PRIVATE映射;但per-VM追踪模式下只能zap对应类型,否则PUNCH_HOLE会误伤VMA映射。
12/45
KVM: guest_memfd: Always fault from guest_memfd if in-place conversion is enabled
in-place转换启用时强制设置KVM_MEMSLOT_GMEM_ONLY,使guest_memfd成为shared和private内存唯一backing源,简化stage2失效;userspace_addr仍用于kvm_read_guest等但需用户保证一致。
13/45
KVM: guest_memfd: Pass mapping type filter to invalidation helper
让invalidation start helper接受mapping type filter参数,调用者可指定只失效shared、private或两者;下一步转换将只zap与目标状态不同的映射。
14/45
KVM: guest_memfd: Add base support for KVM_SET_MEMORY_ATTRIBUTES2
新增KVM_SET_MEMORY_ATTRIBUTES2 ioctl和struct,具备R/W语义,支持部分转换时记录失败offset,struct预留padding,并用KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES宣传能力。
15/45
KVM: guest_memfd: Ensure pages are not in use before conversion
转换到private前检查folio refcount以确保无其他使用者;新增error_offset字段,安全检查失败返回-EAGAIN并复制偏移给用户,便于重试或处理。
16/45
KVM: guest_memfd: Call arch make_shared callback for to-shared conversion
PRIVATE到SHARED转换时立即调用arch make_shared回调以更新硬件元数据,避免按需更新;to-private不主动调用因为需要确切GFN且必须在fault时按需处理。
17/45
KVM: guest_memfd: Return early if range already has requested attributes
增加函数检查gmem范围是否已具备请求的属性,设置内存属性时若整个范围已满足则提前返回,避免无谓的转换和invalidation操作。
18/45
KVM: guest_memfd: Handle lru_add fbatch refcounts during conversion safety check
转换安全检查前调用lru_cache_drain_for_folio()排空lru_add和mlock fbatch可能附加的refcount,之后若refcount仍高则视为真正在用;folio_maybe_dma_pinned()作为DMA引用判断。
19/45
KVM: guest_memfd: Zero page while getting pfn
将folio初始化逻辑移到__kvm_gmem_get_pfn(),使kvm_gmem_populate()路径也能先清零页面,用uptodate标志保证只零一次,避免未初始化主机内存泄漏给guest。
20/45
KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE
SNP_LAUNCH_UPDATE在in-place转换启用时允许uaddr为NULL,让用户先mmap guest_memfd写shared内存再转换private;per-VM属性模式下仍强制非NULL源地址。
21/45
KVM: TDX: Make source page optional for KVM_TDX_INIT_MEM_REGION
TDX的tdx_gmem_post_populate()支持无源页场景,直接在目标PFN上原地执行TDH.MEM.PAGE.ADD;仅当in-place转换启用时允许,否则拒绝以避免晦涩优化。
22/45
KVM: Move KVM_VM_MEMORY_ATTRIBUTES config definition to x86
将KVM_VM_MEMORY_ATTRIBUTES Kconfig移到x86专属,因为per-VM属性追踪已被弃用,防止其他架构引入;公共代码保留在common KVM方便将来撤销。
23/45
KVM: Let userspace disable per-VM mem attributes, enable per-gmem attributes
新增Kconfig选项和条件模块参数,让用户可禁用per-VM属性并启用per-gmem in-place转换;模块加载后禁止动态切换以避免同一KVM实例混合两种追踪模式。
24/45
KVM: guest_memfd: Enable INIT_SHARED on guest_memfd for x86 Coco VMs
在x86 CoCo VM且启用in-place转换时,允许用户为guest_memfd指定INIT_SHARED标志,使实例初始化即为shared内存。
25/45
KVM: selftests: Create gmem fd before "regular" fd when adding memslot
selftests添加memslot时先创建guest_memfd再创建普通backing fd,以便后续当guest_memfd支持mmap时可直接复用gmem fd作为唯一内存来源。
26/45
KVM: selftests: Rename guest_memfd{,_offset} to gmem_{fd,offset}
将selftests中guest_memfd相关变量和参数统一改名为gmem_fd/gmem_offset,去除冗长前缀,无功能变化。
27/45
KVM: selftests: Add support for mmap() on guest_memfd in core library
vm_mem_add()支持传入gmem_flags创建guest_memfd并作为内存槽fd;mmap guest_memfd时使用gmem_offset且固定MAP_SHARED,新增kvm_slot_to_fd()辅助获取fd。
28/45
KVM: selftests: Add selftests global for guest memory attributes capability
新增全局变量kvm_has_gmem_attributes表示guest_memfd自身跟踪内存属性而非VM级,并在selftests中同步到guest以避免host/guest状态不一致。
29/45
KVM: selftests: Add helpers for calling ioctls on guest_memfd
新增gmem_ioctl宏和gmem_set_memory_attributes()系列helpers,__变体返回错误码而非abort;抽取TEST_ASSERT_SUPPORTED_ATTRIBUTES宏供新旧属性设置函数复用。
30/45
KVM: selftests: Test basic single-page conversion flow
新增guest_memfd单页转换selftest,验证默认private状态经private->shared->private的基本流程,并搭建可扩展的转换测试基础设施,测试限定x86。
31/45
KVM: selftests: Test conversion flow when INIT_SHARED
在guest_memfd转换selftest中增加INIT_SHARED场景用例,验证内存初始为shared时private/shared转换仍能正确工作。
32/45
KVM: selftests: Test conversion precision in guest_memfd
From: Ackerley Tng ackerleytng@google.com The existing guest_memfd conversion tests only use single-page memory regions. This provides no coverage for multi-page guest_memfd objects, specifically w
33/45
KVM: selftests: Test conversion before allocation
新增两个转换先于内存分配的测试用例,覆盖guest_memfd区域尚未分配时的两种转换方向,验证内核记录属性请求并在后续分配时应用。
34/45
KVM: selftests: Convert with allocated folios in different layouts
From: Ackerley Tng ackerleytng@google.com Add a guest_memfd selftest to verify that memory conversions work correctly with allocated folios in different layouts. By iterating through which pages a
35/45
KVM: selftests: Test that truncation does not change shared/private status
From: Ackerley Tng ackerleytng@google.com 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
36/45
KVM: selftests: Test that shared/private status is consistent across processes
From: Sean Christopherson seanjc@google.com 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 proces
37/45
KVM: selftests: Add helpers to pin pages with CONFIG_GUP_TEST
From: Ackerley Tng ackerleytng@google.com Add helper functions to allow KVM selftests to pin memory using CONFIG_GUP_TEST. This is useful for creating test scenarios where some page has an increase
38/45
KVM: selftests: Test conversion with elevated page refcount
From: Ackerley Tng ackerleytng@google.com 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
39/45
KVM: selftests: Reset shared memory after hole-punching
From: Ackerley Tng ackerleytng@google.com 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 w
40/45
KVM: selftests: Provide function to look up guest_memfd details from gpa
From: Ackerley Tng ackerleytng@google.com 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 (
41/45
KVM: selftests: Provide common function to set memory attributes
From: Sean Christopherson seanjc@google.com Introduce vm_mem_set_memory_attributes(), which handles setting of memory attributes for a range of guest physical addresses, regardless of whether the a
42/45
KVM: selftests: Make TEST_EXPECT_SIGBUS thread-safe
From: Ackerley Tng ackerleytng@google.com 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
43/45
KVM: selftests: Set up page size and alignment independently for guest_memfd
From: Ackerley Tng ackerleytng@google.com Currently, vm_mem_add derives the backing source page size, alignment padding, and mmap size from the backing source type upfront before checking if guest_
44/45
KVM: selftests: Update private_mem_conversions_test for in-place conversions
From: Ackerley Tng ackerleytng@google.com Update private_mem_conversions_test for in-place conversions. In-place conversions support is detected in selftests with kvm_has_gmem_attributes. With in-
45/45
KVM: selftests: Update private memory exits test to work with per-gmem attributes
From: Sean Christopherson seanjc@google.com 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