On Wed, Apr 01, 2026 at 07:05:16AM -0700, Ackerley Tng wrote: > Ackerley Tng <[email protected]> writes: > > > All-shared guest_memfd used to be only supported for non-CoCo VMs where > > preparation doesn't apply. INIT_SHARED is about to be supported for > > non-CoCo VMs in a later patch in this series. > > > > In addition, KVM_SET_MEMORY_ATTRIBUTES2 is about to be supported in > > guest_memfd in a later patch in this series. > > > > This means that the kvm fault handler may now call kvm_gmem_get_pfn() on a > > shared folio for a CoCo VM where preparation applies. > > > > Add a check to make sure that preparation is only performed for private > > folios. > > > > Preparation will be undone on freeing (see kvm_gmem_free_folio()) and on > > conversion to shared. > > > > Signed-off-by: Ackerley Tng <[email protected]> > > --- > > virt/kvm/guest_memfd.c | 9 ++++++--- > > 1 file changed, 6 insertions(+), 3 deletions(-) > > > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > > index b6ffa8734175d..d414ebfcb4c19 100644 > > --- a/virt/kvm/guest_memfd.c > > +++ b/virt/kvm/guest_memfd.c > > @@ -900,6 +900,7 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct > > kvm_memory_slot *slot, > > int *max_order) > > { > > pgoff_t index = kvm_gmem_get_index(slot, gfn); > > + struct inode *inode; > > struct folio *folio; > > int r = 0; > > > > @@ -907,7 +908,8 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct > > kvm_memory_slot *slot, > > if (!file) > > return -EFAULT; > > > > - filemap_invalidate_lock_shared(file_inode(file)->i_mapping); > > + inode = file_inode(file); > > + filemap_invalidate_lock_shared(inode->i_mapping); > > > > folio = __kvm_gmem_get_pfn(file, slot, index, pfn, max_order); > > if (IS_ERR(folio)) { > > @@ -920,7 +922,8 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct > > kvm_memory_slot *slot, > > folio_mark_uptodate(folio); > > } > > > > - r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio); > > + if (kvm_gmem_is_private_mem(inode, index)) > > + r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio); > > Michael, I might have misunderstood you at the last guest_memfd call: > sev_gmem_prepare() doesn't prepare a page for being a shared page, > right? Does this work? That prepare is only called to "make private"?
Hmm, I guess your guest_memfd-inplace-conversion-v4 branch is out of sync with these patches? I have the below local patch based on top of that for SNP-specific enablement, which is basically identically, so suffice to say: yes, this should work for SNP :) If any architecture pops up that needs to do some prep in advance of mapping shared pages, then we could potentially plumb the shared/private flag through to the arch-specific prep hook, as was also suggested on the call, but it doesn't seem like that's needed by any users for now. -Mike Author: Michael Roth <[email protected]> Date: Mon Oct 27 07:58:32 2025 -0500 KVM: guest_memfd: Don't prepare shared folios In the current guest_memfd logic, "preparation" is only used currently to describe the additional work of putting a guest_memfd page into an architecturally-defined "private" state, such as updating RMP table entries for SEV-SNP guests. As such, there's no input to the corresponding kvm_arch_gmem_prepare() hooks as to whether a page is being prepared/accessed as shared or as private, so "preparation" will end up being erroneously done on pages that were supposed to remain in a shared state. Rather than plumb through the additional information needed to distinguish between shared vs. private preparation, just continue to only do preparation on private pages, as was the case prior to support for GUEST_MEMFD_FLAG_MMAP being introduced. Signed-off-by: Michael Roth <[email protected]> diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 3acc6d983449..4869e59e4fc5 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -1249,7 +1249,8 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, folio_mark_uptodate(folio); } - r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio); + if (!kvm_gmem_is_shared_mem(file_inode(file), index)) + r = kvm_gmem_prepare_folio(kvm, slot, gfn, folio); folio_unlock(folio); > > > > > folio_unlock(folio); > > > > @@ -930,7 +933,7 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct > > kvm_memory_slot *slot, > > folio_put(folio); > > > > out: > > - filemap_invalidate_unlock_shared(file_inode(file)->i_mapping); > > + filemap_invalidate_unlock_shared(inode->i_mapping); > > return r; > > } > > EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_get_pfn); > > > > -- > > 2.53.0.1018.g2bb0e51243-goog
