Re: [PATCH v4 18/18] KVM: guest_memfd: Combine .gmem_prepare()+.gmem_invalidate() into .gmem_convert()
From: Yan Zhao
Date: Wed Aug 05 2026 - 04:31:23 EST
On Fri, Jul 24, 2026 at 11:15:27AM -0700, Sean Christopherson wrote:
> On Fri, Jul 24, 2026, Ackerley Tng wrote:
> > Yan Zhao <yan.y.zhao@xxxxxxxxx> writes:
> >
> > > On Thu, Jul 23, 2026 at 11:47:42AM -0700, Sean Christopherson wrote:
> > >> On Wed, Jul 22, 2026, Yan Zhao wrote:
> > >> > On Tue, Jul 21, 2026 at 11:57:06AM -0700, Sean Christopherson wrote:
> > >> > > > Asking this also because there is a .gmem_convert() for TDX huge pages [1].
> > >> > > > In [1], .gmem_convert() is invoked to emulate a to-shared conversion in
> > >> > > > kvm_gmem_punch_hole(). However, the per-gmem memory attribute for the range to
> > >> > > > convert may not be shared after the punch hole. Is it acceptable?
> > >> > > > (To me, the .gmem_convert() in [1] behaves more like .gmem_prezap()).
> > >> > >
> > >> > > Ya, these concerns got raised by others. pKVM on arm64 in particular wants to
> > >> > > hook reclaim but not conversion. The plan is to keep the reclaim and end up with
> > >> > > this implementation for x86:
> > >> > >
> > >> > > #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT
> > >> > > int kvm_arch_gmem_make_private(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
> > >> > > kvm_pfn_t nr_pages, int max_order)
> > >> > > {
> > >> > > return kvm_x86_call(gmem_make_private)(kvm, gfn, pfn, nr_pages, max_order);
> > >> > > }
> > >> > > int kvm_arch_gmem_make_shared(kvm_pfn_t pfn, kvm_pfn_t nr_pages, int max_order,
> > >> > > bool to_private)
> > >> > > {
> > >> > > kvm_x86_call(gmem_make_shared)(pfn, nr_pages, max_order);
> > >> > > return 0;
> > >> > > }
> > >> > For TDX huge pages, if we want to trigger private huge page splitting before
> > >> > converting to shared, should we invoke the hooks like this?
> > >> >
> > >> > __kvm_gmem_set_attributes(to shared)
> > >> > |->kvm_arch_gmem_make_shared
> > >> > |->kvm_x86_call(gmem_make_shared)(pfn, nr_pages, max_order);
> > >> >
> > >> > But TDX needs kvm pointer, and splitting pages may fail.
> > >>
> > >> Ya, but those are very solvable problems. They just don't need to be addressed
> > >> today, because SNP is the only user of the conversion APIs.
> > > Ok. I'm ok with the change for today's usages. My concern is regarding future
> > > TDX huge page support, as I am currently preparing TDX huge page v4. :)
> > >
> > > Sorry for the confusion -- I should have stated my intention more clearly.
> > >
> > > Previously, for TDX huge pages, you suggested introducing .gmem_convert() to
> > > trigger splitting before zapping S-EPT.
> > > With this new direction, should TDX huge pages instead leverage the
> > > .gmem_make_shared() op for that purpose?
> > >
> > > If so, should we introduce a CONFIG_HAVE_KVM_ARCH_GMEM_PREZAP guard around the
> > > .gmem_make_shared() invocation to serve TDX's splitting purpose, in order to
> > > keep the two use cases (SNP and TDX) clearly separated?
> > >
> >
> > Another thing we need to figure out is the ordering... You mentioned
> > that the S-EPT splitting can fail, and I remember you were suggesting
> > that we merge the S-EPTs back on error, something like that?
> >
> > We'd have to figure out either a point-of-no-return, or some rollback
I think you were referring to the previous issue in hugetlb-based gmem, where
(a) splitting the backend huge folios was performed before (b) zapping secondary
MMU mappings. I previously addressed the issue in patch [1] by performing (b)
first, and then invoking S-EPT splitting before (b).
While Vishal noted in [3] that performing (a) before (b) could prevent
unnecessary zapping of private mappings, S-EPT splitting (the prezap phase) is
still better placed before (a) to avoid the need to rollback and merge backend
folios in the error path, given that S-EPT splitting may fail due to memory
allocation failure.
This is why I think splitting S-EPT deserves a separate .gmem_prezap() callback
rather than reusing .gmem_make_shared().
[1] https://github.com/intel-staging/tdx/commit/a8aedac2df44e29247773db3444bc65f7100daa1
[2] https://lore.kernel.org/all/20260106102250.25194-1-yan.y.zhao@xxxxxxxxx/
[3] https://lore.kernel.org/all/CAGtprH-eEUzHDUB0CK2V162HHqvE8kT3bAacb6d3xDYJPwBiYA@xxxxxxxxxxxxxx/
> > mechanism anyway, so that kind of depends on conversions and the
> > guest_memfd hugepage series. Probably good to defer this discussion to
> > later, when we have more certainty of how it looks like. :)
>
> +1. Even with my series, I'm getting a wee bit too far into trying to predict
> the future.
Ok. Then I'll first have the TDX huge pages register to .gmem_prezap() (instead
of .gmem_convert() or .gmem_make_shared()).
We can discuss the naming later.