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.

Signed-off-by: Ackerley Tng <[email protected]>
---
 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 89cf922232920..6cbd96e2a99d3 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -135,14 +135,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)
@@ -185,15 +177,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,
@@ -228,7 +218,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);
 
@@ -343,7 +334,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);
@@ -530,7 +521,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.508.g3f0d502094-goog



Reply via email to