summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAckerley Tng <ackerleytng@google.com>2026-09-10 16:55:41 -0700
committerSean Christopherson <seanjc@google.com>2026-09-22 07:28:29 -0700
commitdcde2f853ff46836aa2b2d6530a47ba164cb49ab (patch)
treec3874d1b6e7f1f993be12d6b947a16da4eadbaef /include
parent799c9fadc639949beeab9328930f99fbf873d01a (diff)
downloadlinux-next-dcde2f853ff46836aa2b2d6530a47ba164cb49ab.tar.gz
linux-next-dcde2f853ff46836aa2b2d6530a47ba164cb49ab.zip
KVM: guest_memfd: Ensure pages are not in use before conversion
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 any outstanding references to determine whether a page is still in use. The only expected references after unmapping the range requested for conversion are those that are held by guest_memfd itself. A folio will have outstanding references 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. A folio may also have extra refcounts if it is on the mlock fbatch. These two known usages of the folio are handled by draining both the lru_add and mlock fbatches for the folio. After draining, if the refcount is still elevated, then there are truly outstanding references. If the page may be DMA-pinned, DMA is using it and hence there are outstanding references. Checking if the page may be DMA-pinned can have false positives, but that is only with a significant number of refcounts, at which point draining LRU is not going to move the needle - it can still be concluded that the folio has outstanding references. If the page is still mapped after guest_memfd tried to unmap it earlier in the conversion process, it also has outstanding references. Exit early to avoid unnecessary draining in these two cases. If an outstanding reference is detected, stop scanning, record the failing offset, and return immediately. Track the drain status to avoid repeatedly draining LRU caches across multiple folios while scanning the requested range. Update the kvm_memory_attributes2 structure to include an error_offset field. This allows KVM to report the exact offset where a conversion failed. 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. Report error_offset if preallocating memory to track attributes fails with -ENOMEM as well, in which case the start offset of the range is returned. Update documentation to document the error_offset field and the possible -EAGAIN error. Suggested-by: David Hildenbrand <david@kernel.org> Co-developed-by: Vishal Annapurve <vannapurve@google.com> Signed-off-by: Vishal Annapurve <vannapurve@google.com> Signed-off-by: Ackerley Tng <ackerleytng@google.com> Tested-by: Shivank Garg <shivankg@amd.com> Reviewed-by: Fuad Tabba <tabba@google.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Tested-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://patch.msgid.link/20260910-gmem-inplace-conversion-v13-15-dd6fbf94f4e1@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'include')
-rw-r--r--include/uapi/linux/kvm.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index ac371a50041c..8dff2fc1972e 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1665,7 +1665,8 @@ struct kvm_memory_attributes2 {
__u64 size;
__u64 attributes;
__u64 flags;
- __u64 reserved[12];
+ __u64 error_offset;
+ __u64 reserved[11];
};
#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)