]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: PPC: Use kvm_faultin_pfn() to handle page faults on Book3s PR
authorSean Christopherson <seanjc@google.com>
Thu, 10 Oct 2024 18:24:06 +0000 (11:24 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 25 Oct 2024 17:00:49 +0000 (13:00 -0400)
Convert Book3S PR to __kvm_faultin_pfn()+kvm_release_faultin_page(), which
are new APIs to consolidate arch code and provide consistent behavior
across all KVM architectures.

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

arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_32_mmu_host.c
arch/powerpc/kvm/book3s_64_mmu_host.c

index 3d289dbe3982684cc0963c804a139834f9ec87b7..e1ff291ba89106af068ec81e51d3e6ff101f0da2 100644 (file)
@@ -235,7 +235,7 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
 extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
 extern int kvmppc_emulate_paired_single(struct kvm_vcpu *vcpu);
 extern kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa,
-                       bool writing, bool *writable);
+                       bool writing, bool *writable, struct page **page);
 extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,
                        unsigned long *rmap, long pte_index, int realmode);
 extern void kvmppc_update_dirty_map(const struct kvm_memory_slot *memslot,
index ff6c3837395752925cac49490a49effb6e882206..d79c5d1098c05c81d2c189f570a3ac4866c3811b 100644 (file)
@@ -422,7 +422,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
 EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter);
 
 kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
-                       bool *writable)
+                           bool *writable, struct page **page)
 {
        ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM;
        gfn_t gfn = gpa >> PAGE_SHIFT;
@@ -437,13 +437,14 @@ kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
                kvm_pfn_t pfn;
 
                pfn = (kvm_pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
-               get_page(pfn_to_page(pfn));
+               *page = pfn_to_page(pfn);
+               get_page(*page);
                if (writable)
                        *writable = true;
                return pfn;
        }
 
-       return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable);
+       return kvm_faultin_pfn(vcpu, gfn, writing, writable, page);
 }
 EXPORT_SYMBOL_GPL(kvmppc_gpa_to_pfn);
 
index 4b3a8d80cfa354c0720bbd8b2ef760b8e33e6ea1..5b7212edbb13130101892089fadc02aa2f1ac685 100644 (file)
@@ -130,6 +130,7 @@ extern char etext[];
 int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
                        bool iswrite)
 {
+       struct page *page;
        kvm_pfn_t hpaddr;
        u64 vpn;
        u64 vsid;
@@ -145,7 +146,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
        bool writable;
 
        /* Get host physical address for gpa */
-       hpaddr = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable);
+       hpaddr = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable, &page);
        if (is_error_noslot_pfn(hpaddr)) {
                printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n",
                                 orig_pte->raddr);
@@ -232,7 +233,7 @@ next_pteg:
 
        pte = kvmppc_mmu_hpte_cache_next(vcpu);
        if (!pte) {
-               kvm_release_pfn_clean(hpaddr >> PAGE_SHIFT);
+               kvm_release_page_unused(page);
                r = -EAGAIN;
                goto out;
        }
@@ -250,7 +251,7 @@ next_pteg:
 
        kvmppc_mmu_hpte_cache_map(vcpu, pte);
 
-       kvm_release_pfn_clean(hpaddr >> PAGE_SHIFT);
+       kvm_release_page_clean(page);
 out:
        return r;
 }
index d0e4f7bbdc3d833a4bd19833406d9e20c4d18761..be20aee6fd7d0988d37bb0c87ef6f9f93f6be9dc 100644 (file)
@@ -88,13 +88,14 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
        struct hpte_cache *cpte;
        unsigned long gfn = orig_pte->raddr >> PAGE_SHIFT;
        unsigned long pfn;
+       struct page *page;
 
        /* used to check for invalidations in progress */
        mmu_seq = kvm->mmu_invalidate_seq;
        smp_rmb();
 
        /* Get host physical address for gpa */
-       pfn = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable);
+       pfn = kvmppc_gpa_to_pfn(vcpu, orig_pte->raddr, iswrite, &writable, &page);
        if (is_error_noslot_pfn(pfn)) {
                printk(KERN_INFO "Couldn't get guest page for gpa %lx!\n",
                       orig_pte->raddr);
@@ -199,10 +200,9 @@ map_again:
        }
 
 out_unlock:
-       if (!orig_pte->may_write || !writable)
-               kvm_release_pfn_clean(pfn);
-       else
-               kvm_release_pfn_dirty(pfn);
+       /* FIXME: Don't unconditionally pass unused=false. */
+       kvm_release_faultin_page(kvm, page, false,
+                                orig_pte->may_write && writable);
        spin_unlock(&kvm->mmu_lock);
        if (cpte)
                kvmppc_mmu_hpte_cache_free(cpte);