From: Ackerley Tng When userspace punches a hole via fallocate, the VFS only validates that the offset and length do not overflow the superblock maximum file size, allowing ranges that extend past the end of the guest_memfd inode. In folio mode, truncating page cache folios past the end of the inode is a fast no-op because the page cache xarray has no entries beyond the inode size. Prepare for PFN mode by clamping the hole punch range to the inode size and returning early if the starting offset is at or beyond the end of the file. This avoids, in PFN mode, iterating across a potentially huge punched range where the provider isn't even providing that memory to guest_memfd. For folios, no functional change intended. Signed-off-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index f0c5162cc7a7f..206b90646c743 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -382,8 +382,15 @@ static void kvm_gmem_invalidate_end(struct inode *inode, pgoff_t start, static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t len) { enum kvm_gfn_range_filter filter = kvm_gmem_get_all_gfns_filter(inode); - pgoff_t start = offset >> PAGE_SHIFT; - pgoff_t end = (offset + len) >> PAGE_SHIFT; + loff_t size = i_size_read(inode); + pgoff_t start, end; + + if (offset >= size) + return 0; + + len = min(len, size - offset); + start = offset >> PAGE_SHIFT; + end = (offset + len) >> PAGE_SHIFT; /* * Bindings must be stable across invalidation to ensure the start+end -- 2.56.0.257.gf7497c7d27-goog