On Fri, 7 Aug 2026 at 23:52, Ackerley Tng via B4 Relay <[email protected]> wrote: > > From: Ackerley Tng <[email protected]> > > Before conversion, a guest_memfd could be either all shared, or all > private, configured at creation time using the INIT_SHARED flag. Hence, > when zapping pages from stage 2 page tables, guest_memfd can filter which > to zap based on the initial shared/private state. > > With conversion, guest_memfd tracks shared/private state on a per-page > level, so a range can contain both private and shared pages. Zap both > private and shared pages for simplicity. > > An alternative would be to iterate guest_memfd attributes and only zap both > if shared and private pages exist within the range. Setting both the shared > and private filters lets the zapping logic do that iteration instead. > > Reviewed-by: Suzuki K Poulose <[email protected]> > Signed-off-by: Ackerley Tng <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > virt/kvm/guest_memfd.c | 24 ++++++++---------------- > 1 file changed, 8 insertions(+), 16 deletions(-) > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index 75979c885e030..b1537226e5adf 100644 > --- a/virt/kvm/guest_memfd.c > +++ b/virt/kvm/guest_memfd.c > @@ -136,14 +136,6 @@ static struct folio *kvm_gmem_get_folio(struct inode > *inode, pgoff_t index) > return folio; > } > > -static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct inode > *inode) > -{ > - if (GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED) > - return KVM_FILTER_SHARED; > - > - return KVM_FILTER_PRIVATE; > -} > - > static void __kvm_gmem_invalidate_start(struct gmem_file *f, pgoff_t start, > pgoff_t end, > enum kvm_gfn_range_filter attr_filter) > @@ -186,15 +178,13 @@ static void __kvm_gmem_invalidate_start(struct > gmem_file *f, pgoff_t start, > } > > static void kvm_gmem_invalidate_start(struct inode *inode, pgoff_t start, > - pgoff_t end) > + pgoff_t end, > + enum kvm_gfn_range_filter filter) > { > - enum kvm_gfn_range_filter attr_filter; > struct gmem_file *f; > > - attr_filter = kvm_gmem_get_invalidate_filter(inode); > - > kvm_gmem_for_each_file(f, inode) > - __kvm_gmem_invalidate_start(f, start, end, attr_filter); > + __kvm_gmem_invalidate_start(f, start, end, filter); > } > > static void __kvm_gmem_invalidate_end(struct gmem_file *f, pgoff_t start, > @@ -229,7 +219,8 @@ static long kvm_gmem_punch_hole(struct inode *inode, > loff_t offset, loff_t len) > */ > filemap_invalidate_lock(inode->i_mapping); > > - kvm_gmem_invalidate_start(inode, start, end); > + kvm_gmem_invalidate_start(inode, start, end, > + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); > > truncate_inode_pages_range(inode->i_mapping, offset, offset + len - > 1); > > @@ -344,7 +335,7 @@ static int kvm_gmem_release(struct inode *inode, struct > file *file) > * memory, as its lifetime is associated with the inode, not the file. > */ > __kvm_gmem_invalidate_start(f, 0, -1ul, > - kvm_gmem_get_invalidate_filter(inode)); > + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); > __kvm_gmem_invalidate_end(f, 0, -1ul); > > list_del(&f->entry); > @@ -525,7 +516,8 @@ static int kvm_gmem_error_folio(struct address_space > *mapping, struct folio *fol > start = folio->index; > end = start + folio_nr_pages(folio); > > - kvm_gmem_invalidate_start(mapping->host, start, end); > + kvm_gmem_invalidate_start(mapping->host, start, end, > + KVM_FILTER_SHARED | KVM_FILTER_PRIVATE); > > /* > * Do not truncate the range, what action is taken in response to the > > -- > 2.55.0.654.g21b8a5bc05-goog > >
