]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: guest_memfd: Pass index, not gfn, to __kvm_gmem_get_pfn()
authorSean Christopherson <seanjc@google.com>
Thu, 20 Nov 2025 17:36:29 +0000 (12:36 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Nov 2025 09:36:05 +0000 (10:36 +0100)
[ Upstream commit 4af18dc6a9204464db76d9771d1f40e2b46bf6ae ]

Refactor guest_memfd usage of __kvm_gmem_get_pfn() to pass the index into
the guest_memfd file instead of the gfn, i.e. resolve the index based on
the slot+gfn in the caller instead of in __kvm_gmem_get_pfn().  This will
allow kvm_gmem_get_pfn() to retrieve and return the specific "struct page",
which requires the index into the folio, without a redoing the index
calculation multiple times (which isn't costly, just hard to follow).

Opportunistically add a kvm_gmem_get_index() helper to make the copy+pasted
code easier to understand.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-ID: <20241010182427.1434605-46-seanjc@google.com>
Stable-dep-of: ae431059e75d ("KVM: guest_memfd: Remove bindings on memslot deletion when gmem is dying")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
virt/kvm/guest_memfd.c

index bb062d3d2457238068f31f4006cc4bc5bc9360f1..73e5db8ef1611714bf12594703454124f494cbc8 100644 (file)
@@ -304,6 +304,11 @@ static inline struct file *kvm_gmem_get_file(struct kvm_memory_slot *slot)
        return get_file_active(&slot->gmem.file);
 }
 
+static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+       return gfn - slot->base_gfn + slot->gmem.pgoff;
+}
+
 static struct file_operations kvm_gmem_fops = {
        .open           = generic_file_open,
        .release        = kvm_gmem_release,
@@ -553,12 +558,11 @@ void kvm_gmem_unbind(struct kvm_memory_slot *slot)
 }
 
 /* Returns a locked folio on success.  */
-static struct folio *
-__kvm_gmem_get_pfn(struct file *file, struct kvm_memory_slot *slot,
-                  gfn_t gfn, kvm_pfn_t *pfn, bool *is_prepared,
-                  int *max_order)
+static struct folio *__kvm_gmem_get_pfn(struct file *file,
+                                       struct kvm_memory_slot *slot,
+                                       pgoff_t index, kvm_pfn_t *pfn,
+                                       bool *is_prepared, int *max_order)
 {
-       pgoff_t index = gfn - slot->base_gfn + slot->gmem.pgoff;
        struct kvm_gmem *gmem = file->private_data;
        struct folio *folio;
 
@@ -594,6 +598,7 @@ __kvm_gmem_get_pfn(struct file *file, struct kvm_memory_slot *slot,
 int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
                     gfn_t gfn, kvm_pfn_t *pfn, int *max_order)
 {
+       pgoff_t index = kvm_gmem_get_index(slot, gfn);
        struct file *file = kvm_gmem_get_file(slot);
        struct folio *folio;
        bool is_prepared = false;
@@ -602,7 +607,7 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
        if (!file)
                return -EFAULT;
 
-       folio = __kvm_gmem_get_pfn(file, slot, gfn, pfn, &is_prepared, max_order);
+       folio = __kvm_gmem_get_pfn(file, slot, index, pfn, &is_prepared, max_order);
        if (IS_ERR(folio)) {
                r = PTR_ERR(folio);
                goto out;
@@ -650,6 +655,7 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
        for (i = 0; i < npages; i += (1 << max_order)) {
                struct folio *folio;
                gfn_t gfn = start_gfn + i;
+               pgoff_t index = kvm_gmem_get_index(slot, gfn);
                bool is_prepared = false;
                kvm_pfn_t pfn;
 
@@ -658,7 +664,7 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
                        break;
                }
 
-               folio = __kvm_gmem_get_pfn(file, slot, gfn, &pfn, &is_prepared, &max_order);
+               folio = __kvm_gmem_get_pfn(file, slot, index, &pfn, &is_prepared, &max_order);
                if (IS_ERR(folio)) {
                        ret = PTR_ERR(folio);
                        break;