Re: [PATCH v8 21/46] KVM: guest_memfd: Zero page while getting pfn
From: Ackerley Tng
Date: Wed Jun 24 2026 - 18:30:34 EST
Yan Zhao <yan.y.zhao@xxxxxxxxx> writes:
> On Thu, Jun 18, 2026 at 05:31:58PM -0700, Ackerley Tng via B4 Relay wrote:
>> From: Ackerley Tng <ackerleytng@xxxxxxxxxx>
>>
>> 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().
>>
>> Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
>> ---
>> virt/kvm/guest_memfd.c | 10 +++++-----
>> 1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
>> index 90bc1a26512b6..86c9f5b0863cb 100644
>> --- a/virt/kvm/guest_memfd.c
>> +++ b/virt/kvm/guest_memfd.c
>> @@ -1137,6 +1137,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);
>> + }
> Note:
> In the __kvm_gmem_populate() path, this folio_mark_uptodate() call makes the
> later one after post_populate() pointless.
>
> __kvm_gmem_populate
> |1.__kvm_gmem_get_pfn
> | |->folio = kvm_gmem_get_folio()
> | | if (!folio_test_uptodate(folio))
> | | folio_mark_uptodate(folio);
> |2. ret = post_populate()
> |3. if (!ret)
> | folio_mark_uptodate(folio);
>
Good point! I'll remove the folio_mark_uptodate() in the populate path
then. Thanks!
>>
>> [...snip...]
>>