Re: [PATCH v9 16/41] KVM: guest_memfd: Zero page while getting pfn
Xiaoyao Li <[email protected]> Fri, 31 Jul 2026 16:49:52 +0800
| Newsgroups | dev.linux.lists.linux-coco,org.kernel.vger.kvm,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-trace-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On 7/29/2026 8:35 AM, Ackerley Tng via B4 Relay wrote: > From: Ackerley Tng <[email protected]> > > Move the folio initialization logic from kvm_gmem_get_pfn() into > __kvm_gmem_get_pfn() to also zero pages if the page is to be used in > kvm_gmem_populate(). > > With in-place conversion, the existing data in a guest_memfd page can be > populated into guest memory through platform-specific ioctls. > > Without first zeroing the page obtained using __kvm_gmem_get_pfn(), it > might contain uninitialized host memory, which would leak to the guest if > the populate completes. > > guest_memfd pages are zeroed at most once in the page's entire lifetime > with guest_memfd, and that is tracked using the uptodate flag. > > Zeroing the page in __kvm_gmem_get_pfn() is chosen over zeroing in > kvm_gmem_get_folio() since other flows, such as a future write() syscall, > can get a page, write to the page and then set page uptodate without > zeroing. > > This aligns with the concept of zeroing before first use - the other place > where zeroing happens is in kvm_gmem_fault_user_mapping(). > > Don't mark the page uptodate again after populating, since the page would > already be marked uptodate before the post_populate() call. > > Reviewed-by: Fuad Tabba <[email protected]> > Tested-by: Shivank Garg <[email protected]> > Signed-off-by: Ackerley Tng <[email protected]> Reviewed-by: Xiaoyao Li <[email protected]> > --- > virt/kvm/guest_memfd.c | 12 +++++------- > 1 file changed, 5 insertions(+), 7 deletions(-) > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index 505bb6747620b..ea2752989f8bd 100644 > --- a/virt/kvm/guest_memfd.c > +++ b/virt/kvm/guest_memfd.c > @@ -1078,6 +1078,11 @@ static struct folio *__kvm_gmem_get_pfn(struct file *file, > return ERR_PTR(-EHWPOISON); > } > > + if (!folio_test_uptodate(folio)) { > + clear_highpage(folio_page(folio, 0)); > + folio_mark_uptodate(folio); > + } > + > *pfn = folio_file_pfn(folio, index); > if (max_order) > *max_order = 0; > @@ -1107,11 +1112,6 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, > goto out; > } > > - if (!folio_test_uptodate(folio)) { > - clear_highpage(folio_page(folio, 0)); > - folio_mark_uptodate(folio); > - } > - > #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT > if (kvm_gmem_is_private_mem(file_inode(file), index)) > r = kvm_arch_gmem_make_private(kvm, gfn, *pfn, > @@ -1171,8 +1171,6 @@ static long __kvm_gmem_populate(struct kvm *kvm, struct kvm_memory_slot *slot, > } > > ret = post_populate(kvm, gfn, pfn, src_page, opaque); > - if (!ret) > - folio_mark_uptodate(folio); > > out_put_folio: > folio_put(folio); >