KVM: MMU: pass struct kvm_page_fault to mmu_set_spte
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 17 Aug 2021 11:49:47 +0000 (07:49 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 1 Oct 2021 07:44:56 +0000 (03:44 -0400)
mmu_set_spte is called for either PTE prefetching or page faults.  The
three boolean arguments write_fault, speculative and host_writable are
always respectively false/true/true for prefetching and coming from
a struct kvm_page_fault for page faults.

Let mmu_set_spte distinguish these two situation by accepting a
possibly NULL struct kvm_page_fault argument.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/paging_tmpl.h

index c208f001c302fca1dd7585c073a1e567a8316792..4b304f60cf4417db9f07bf2e2dbd6a21d5d3bb5f 100644 (file)
@@ -2675,9 +2675,8 @@ int mmu_try_to_unsync_pages(struct kvm_vcpu *vcpu, gfn_t gfn, bool can_unsync,
 }
 
 static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
-                       unsigned int pte_access, bool write_fault,
-                       gfn_t gfn, kvm_pfn_t pfn, bool speculative,
-                       bool host_writable)
+                       unsigned int pte_access, gfn_t gfn,
+                       kvm_pfn_t pfn, struct kvm_page_fault *fault)
 {
        struct kvm_mmu_page *sp = sptep_to_sp(sptep);
        int level = sp->role.level;
@@ -2687,6 +2686,11 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
        bool wrprot;
        u64 spte;
 
+       /* Prefetching always gets a writable pfn.  */
+       bool host_writable = !fault || fault->map_writable;
+       bool speculative = !fault || fault->prefault;
+       bool write_fault = fault && fault->write;
+
        pgprintk("%s: spte %llx write_fault %d gfn %llx\n", __func__,
                 *sptep, write_fault, gfn);
 
@@ -2778,8 +2782,8 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
                return -1;
 
        for (i = 0; i < ret; i++, gfn++, start++) {
-               mmu_set_spte(vcpu, start, access, false, gfn,
-                            page_to_pfn(pages[i]), true, true);
+               mmu_set_spte(vcpu, start, access, gfn,
+                            page_to_pfn(pages[i]), NULL);
                put_page(pages[i]);
        }
 
@@ -2981,8 +2985,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
                return -EFAULT;
 
        ret = mmu_set_spte(vcpu, it.sptep, ACC_ALL,
-                          fault->write, base_gfn, fault->pfn,
-                          fault->prefault, fault->map_writable);
+                          base_gfn, fault->pfn, fault);
        if (ret == RET_PF_SPURIOUS)
                return ret;
 
index fbbaa3f5fb4e8e010d8f8c3dbc75b0e0bd57e69d..8c07c42a4d73d5264917b52f06f841d126fab6e0 100644 (file)
@@ -578,13 +578,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
        if (is_error_pfn(pfn))
                return false;
 
-       /*
-        * we call mmu_set_spte() with host_writable = true because
-        * pte_prefetch_gfn_to_pfn always gets a writable pfn.
-        */
-       mmu_set_spte(vcpu, spte, pte_access, false, gfn, pfn,
-                    true, true);
-
+       mmu_set_spte(vcpu, spte, pte_access, gfn, pfn, NULL);
        kvm_release_pfn_clean(pfn);
        return true;
 }
@@ -763,9 +757,8 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
        if (WARN_ON_ONCE(it.level != fault->goal_level))
                return -EFAULT;
 
-       ret = mmu_set_spte(vcpu, it.sptep, gw->pte_access, fault->write,
-                          base_gfn, fault->pfn, fault->prefault,
-                          fault->map_writable);
+       ret = mmu_set_spte(vcpu, it.sptep, gw->pte_access,
+                          base_gfn, fault->pfn, fault);
        if (ret == RET_PF_SPURIOUS)
                return ret;