v9 2026-07-29

guest_memfd就地转换 · v9

引入guest_memfd ioctl和maple tree实现私有/共享状态就地转换,支持KVM。

原始补丁链接

子 Patch(41)

1/41
KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings
为guest_memfd添加per-inode内存属性(maple树),替代原有per-VM属性,支撑in-place转换;使用filemap invalidation lock保护。
2/41
KVM: Rename KVM_GENERIC_MEMORY_ATTRIBUTES to KVM_VM_MEMORY_ATTRIBUTES
重命名Kconfig宏KVM_GENERIC_MEMORY_ATTRIBUTES为KVM_VM_MEMORY_ATTRIBUTES,明确其为VM级别属性,无功能变化。
3/41
KVM: Enumerate support for PRIVATE memory iff kvm_arch_has_private_mem is defined
修改KVM_MEMORY_ATTRIBUTE_PRIVATE支持检测,必须依赖kvm_arch_has_private_mem定义,避免架构未定义时误报。
4/41
KVM: Rename memory attribute APIs to prepare for in-place gmem conversion
重命名kvm_vm_set_mem_attributes()为kvm_set_vm_mem_attributes()及相关trace事件,为区分VM和gmem属性做准备。
5/41
KVM: Provide generic interface for checking memory private/shared status
添加通用kvm_mem_is_private()静态调用接口,重命名原有VM属性检查为kvm_vm_mem_is_private(),支持运行时选择实现。
6/41
KVM: guest_memfd: Introduce function to check GFN private/shared status
为 KVM guest_memfd 引入函数检查 GFN 的私有/共享状态。
7/41
KVM: guest_memfd: Wire up core private/shared attribute interfaces
On 7/29/2026 8:35 AM, Ackerley Tng via B4 Relay wrote: > diff –git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index 33c9830190e2e..89cf922232920 100644 > — a/virt/kvm/guest_memfd.c > +++ b
8/41
KVM: Consolidate private memory and guest_memfd ifdeffery in kvm_host.h
在kvm_host.h中重新组织#ifdeffery,将私有内存和guest_memfd相关代码聚集到同一#ifdef区域,无功能变化。
9/41
KVM: guest_memfd: Filter both shared and private when invalidating
修改guest_memfd无效化时同时清除共享和私有属性映射,因为per-page转换后范围可能混合两者,简化实现。
10/41
KVM: guest_memfd: Add base support for KVM_SET_MEMORY_ATTRIBUTES2
添加KVM_SET_MEMORY_ATTRIBUTES2 ioctl,支持部分转换并上报错误偏移,引入新capability,扩展API文档。
11/41
KVM: guest_memfd: Ensure pages are not in use before conversion
在guest_memfd转换前检查页refcount,确保无额外引用(如DMA),否则返回-EAGAIN并记录偏移,避免并发访问。
12/41
KVM: guest_memfd: Call arch make_shared callback for to-shared conversion
在guest_memfd私有转共享时,遍历folio调用kvm_arch_gmem_invalidate(),以清理硬件元数据或加密状态。
13/41
KVM: guest_memfd: Return early if range already has requested attributes
提取kvm_gmem_range_has_attrs(),在设置属性时先检查是否已满足,避免不必要操作。
14/41
mm: swap: Introduce lru_add_drain_progressive()
创建lru_add_drain_progressive()函数,实现逐步drain本地/全局CPU批处理,供guest_memfd转换检查引用时调用。
15/41
KVM: guest_memfd: Handle lru_add fbatch refcounts during conversion safety check
在guest_memfd转换引用检查中,调用lru_add_drain_progressive()清除可能存在的lru_add fbatch引用,避免误报。
16/41
KVM: guest_memfd: Zero page while getting pfn
在__kvm_gmem_get_pfn()中执行页面清零(通过uptodate标记保证仅一次),避免未初始化内存泄漏给guest。
17/41
KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE
允许KVM_SEV_SNP_LAUNCH_UPDATE的uaddr为NULL(需in-place转换使能),表示从guest_memfd就地初始化,无需额外拷贝。
18/41
KVM: TDX: Make source page optional for KVM_TDX_INIT_MEM_REGION
让tdx_gmem_post_populate()支持无源页情况,直接从目标PFN进行in-place填充(TDH.MEM.PAGE.ADD)。
19/41
KVM: Move KVM_VM_MEMORY_ATTRIBUTES config definition to x86
将KVM_VM_MEMORY_ATTRIBUTES Kconfig限制为x86,因为per-VM属性已折旧,期望架构使用guest_memfd属性。
20/41
KVM: Let userspace disable per-VM mem attributes, enable per-gmem attributes
添加模块参数控制是否启用per-VM内存属性;当禁用时使用guest_memfd属性;仅对CoCo VM类型有效。
21/41
KVM: guest_memfd: Enable INIT_SHARED on guest_memfd for x86 Coco VMs
放开对x86 CoCo VM指定INIT_SHARED的限制(需in-place转换),使得guest_memfd可包含共享内存。
22/41
KVM: selftests: Create gmem fd before "regular" fd when adding memslot
在vm_mem_add中调整创建顺序:先dup gmem fd再创建普通backing fd,便于后续将gmem mmap作为唯一源。
23/41
KVM: selftests: Rename guest_memfd{,_offset} to gmem_{fd,offset}
将测试代码中guest_memfd相关变量名统一改为gmem_前缀,提高一致性,无功能变化。
24/41
KVM: selftests: Add support for mmap() on guest_memfd in core library
扩展kvm_util库,使guest_memfd可作为mmap源,支持gmem_offset和MAP_SHARED,添加slot到fd的辅助函数。
25/41
KVM: selftests: Add selftests global for guest memory attributes capability
引入kvm_has_gmem_attributes全局变量,标识KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES状态,供测试使用。
26/41
KVM: selftests: Add helpers for calling ioctls on guest_memfd
封装gmem ioctl调用宏和设置属性/私有/共享的辅助函数,并添加TEST_ASSERT_SUPPORTED_ATTRIBUTES宏。
27/41
KVM: selftests: Test basic single-page conversion flow
新增guest_memfd_conversions_test,验证单页从私有转共享再转回私有的基本流程。
28/41
KVM: selftests: Test conversion flow when INIT_SHARED
增加测试用例:在INIT_SHARED模式下验证私有/共享转换的正确性。
29/41
KVM: selftests: Test conversion precision in guest_memfd
添加多页测试,验证转换仅影响指定页面,其他页状态不变,并增加GMEM_CONVERSION_MULTIPAGE_TEST_INIT_SHARED宏。
30/41
KVM: selftests: Test conversion before allocation
添加测试,在无页面分配时调用KVM_SET_MEMORY_ATTRIBUTES2,验证后续分配页继承正确的私有/共享状态。
31/41
KVM: selftests: Convert with allocated folios in different layouts
通过迭代初始fault不同页面组合,测试各种分配布局下的转换正确性。
32/41
KVM: selftests: Test that truncation does not change shared/private status
验证打洞后重新分配的页保持原有的私有/共享属性,不受物理内存释放影响。
33/41
KVM: selftests: Test that shared/private status is consistent across processes
测试跨进程共享/私有状态一致性,确保共享页被转换后从所有进程的映射中unmap。
34/41
KVM: selftests: Add helpers to pin pages with CONFIG_GUP_TEST
引入pin_page/unpin_page辅助,依赖CONFIG_GUP_TEST,用于模拟页被固定时的转换失败测试。
35/41
KVM: selftests: Test conversion with elevated page refcount
验证共享转私有时若页被pin则返回EAGAIN,unpin后转换成功,确保安全检查有效。
36/41
KVM: selftests: Reset shared memory after hole-punching
调整private_mem_conversions_test中reset和hole-punch顺序,确保在in-place转换下每次迭代初始状态正确。
37/41
KVM: selftests: Provide function to look up guest_memfd details from gpa
添加kvm_gpa_to_guest_memfd()辅助,从GPA获取guest_memfd文件描述符和偏移;重构fallocate函数。
38/41
KVM: selftests: Provide common function to set memory attributes
新增 vm_mem_set_memory_attributes() 统一处理 guest_memfd 和 VM 级内存属性设置,重构现有函数并将 size 参数改为 size_t。
39/41
KVM: selftests: Make TEST_EXPECT_SIGBUS thread-safe
修复 TEST_EXPECT_SIGBUS 多线程竞态:通过共享全局信号处理器和线程局部变量 expecting_sigb 确保信号处理安全。
40/41
KVM: selftests: Update private_mem_conversions_test to mmap() guest_memfd
扩展私有内存转换测试:使用 guest_memfd 的 mmap 和 per-guest_memfd 属性进行原地转换,验证 host 访问私有内存时触发 SIGBUS。
41/41
KVM: selftests: Update private memory exits test to work with per-gmem attributes
调整测试用例适配per-gmem属性:跳过显式设置私有内存,默认私有;GPA变为共享时预期emulated MMIO而非memory fault;跳过memslot不私有测试。