]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: PPC: Use __kvm_faultin_pfn() to handle page faults on Book3s Radix
authorSean Christopherson <seanjc@google.com>
Thu, 10 Oct 2024 18:24:03 +0000 (11:24 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 25 Oct 2024 17:00:48 +0000 (13:00 -0400)
Replace Book3s Radix's homebrewed (read: copy+pasted) fault-in logic with
__kvm_faultin_pfn(), which functionally does pretty much the exact same
thing.

Note, when the code was written, KVM indeed didn't do fast GUP without
"!atomic && !async", but that has long since changed (KVM tries fast GUP
for all writable mappings).

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-62-seanjc@google.com>

arch/powerpc/kvm/book3s_64_mmu_radix.c

index 8304b6f8fe45e3d45ef1636f2524edb6e2f740a9..14891d0a3b73a446ee3409d631f07cd6b5ec71e1 100644 (file)
@@ -829,40 +829,21 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu,
        unsigned long mmu_seq;
        unsigned long hva, gfn = gpa >> PAGE_SHIFT;
        bool upgrade_write = false;
-       bool *upgrade_p = &upgrade_write;
        pte_t pte, *ptep;
        unsigned int shift, level;
        int ret;
        bool large_enable;
+       kvm_pfn_t pfn;
 
        /* used to check for invalidations in progress */
        mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
-       /*
-        * Do a fast check first, since __gfn_to_pfn_memslot doesn't
-        * do it with !atomic && !async, which is how we call it.
-        * We always ask for write permission since the common case
-        * is that the page is writable.
-        */
        hva = gfn_to_hva_memslot(memslot, gfn);
-       if (!kvm_ro && get_user_page_fast_only(hva, FOLL_WRITE, &page)) {
-               upgrade_write = true;
-       } else {
-               unsigned long pfn;
-
-               /* Call KVM generic code to do the slow-path check */
-               pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL,
-                                          writing, upgrade_p);
-               if (is_error_noslot_pfn(pfn))
-                       return -EFAULT;
-               page = NULL;
-               if (pfn_valid(pfn)) {
-                       page = pfn_to_page(pfn);
-                       if (PageReserved(page))
-                               page = NULL;
-               }
-       }
+       pfn = __kvm_faultin_pfn(memslot, gfn, writing ? FOLL_WRITE : 0,
+                               &upgrade_write, &page);
+       if (is_error_noslot_pfn(pfn))
+               return -EFAULT;
 
        /*
         * Read the PTE from the process' radix tree and use that