kvmppc_svm_page_out() will need to be called by kvmppc_uvmem_drop_pages()
so move it upper in this file.

Furthermore it will be interesting to call this function when already
holding the kvm->arch.uvmem_lock, so prefix the original function with __
and remove the locking in it, and introduce a wrapper which call that
function with the lock held.

There is no functional change.

Cc: Ram Pai <linux...@us.ibm.com>
Cc: Bharata B Rao <bhar...@linux.ibm.com>
Cc: Paul Mackerras <pau...@ozlabs.org>
Signed-off-by: Laurent Dufour <lduf...@linux.ibm.com>
---
 arch/powerpc/kvm/book3s_hv_uvmem.c | 166 ++++++++++++++++-------------
 1 file changed, 90 insertions(+), 76 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 778a6ea86991..852cc9ae6a0b 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -435,6 +435,96 @@ unsigned long kvmppc_h_svm_init_done(struct kvm *kvm)
        return ret;
 }
 
+/*
+ * Provision a new page on HV side and copy over the contents
+ * from secure memory using UV_PAGE_OUT uvcall.
+ * Caller must held kvm->arch.uvmem_lock.
+ */
+static int __kvmppc_svm_page_out(struct vm_area_struct *vma,
+               unsigned long start,
+               unsigned long end, unsigned long page_shift,
+               struct kvm *kvm, unsigned long gpa)
+{
+       unsigned long src_pfn, dst_pfn = 0;
+       struct migrate_vma mig;
+       struct page *dpage, *spage;
+       struct kvmppc_uvmem_page_pvt *pvt;
+       unsigned long pfn;
+       int ret = U_SUCCESS;
+
+       memset(&mig, 0, sizeof(mig));
+       mig.vma = vma;
+       mig.start = start;
+       mig.end = end;
+       mig.src = &src_pfn;
+       mig.dst = &dst_pfn;
+       mig.src_owner = &kvmppc_uvmem_pgmap;
+
+       /* The requested page is already paged-out, nothing to do */
+       if (!kvmppc_gfn_is_uvmem_pfn(gpa >> page_shift, kvm, NULL))
+               return ret;
+
+       ret = migrate_vma_setup(&mig);
+       if (ret)
+               return -1;
+
+       spage = migrate_pfn_to_page(*mig.src);
+       if (!spage || !(*mig.src & MIGRATE_PFN_MIGRATE))
+               goto out_finalize;
+
+       if (!is_zone_device_page(spage))
+               goto out_finalize;
+
+       dpage = alloc_page_vma(GFP_HIGHUSER, vma, start);
+       if (!dpage) {
+               ret = -1;
+               goto out_finalize;
+       }
+
+       lock_page(dpage);
+       pvt = spage->zone_device_data;
+       pfn = page_to_pfn(dpage);
+
+       /*
+        * This function is used in two cases:
+        * - When HV touches a secure page, for which we do UV_PAGE_OUT
+        * - When a secure page is converted to shared page, we *get*
+        *   the page to essentially unmap the device page. In this
+        *   case we skip page-out.
+        */
+       if (!pvt->skip_page_out)
+               ret = uv_page_out(kvm->arch.lpid, pfn << page_shift,
+                                 gpa, 0, page_shift);
+
+       if (ret == U_SUCCESS)
+               *mig.dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
+       else {
+               unlock_page(dpage);
+               __free_page(dpage);
+               goto out_finalize;
+       }
+
+       migrate_vma_pages(&mig);
+
+out_finalize:
+       migrate_vma_finalize(&mig);
+       return ret;
+}
+
+static inline int kvmppc_svm_page_out(struct vm_area_struct *vma,
+                                     unsigned long start, unsigned long end,
+                                     unsigned long page_shift,
+                                     struct kvm *kvm, unsigned long gpa)
+{
+       int ret;
+
+       mutex_lock(&kvm->arch.uvmem_lock);
+       ret = __kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa);
+       mutex_unlock(&kvm->arch.uvmem_lock);
+
+       return ret;
+}
+
 /*
  * Drop device pages that we maintain for the secure guest
  *
@@ -801,82 +891,6 @@ unsigned long kvmppc_h_svm_page_in(struct kvm *kvm, 
unsigned long gpa,
        return ret;
 }
 
-/*
- * Provision a new page on HV side and copy over the contents
- * from secure memory using UV_PAGE_OUT uvcall.
- */
-static int kvmppc_svm_page_out(struct vm_area_struct *vma,
-               unsigned long start,
-               unsigned long end, unsigned long page_shift,
-               struct kvm *kvm, unsigned long gpa)
-{
-       unsigned long src_pfn, dst_pfn = 0;
-       struct migrate_vma mig;
-       struct page *dpage, *spage;
-       struct kvmppc_uvmem_page_pvt *pvt;
-       unsigned long pfn;
-       int ret = U_SUCCESS;
-
-       memset(&mig, 0, sizeof(mig));
-       mig.vma = vma;
-       mig.start = start;
-       mig.end = end;
-       mig.src = &src_pfn;
-       mig.dst = &dst_pfn;
-       mig.src_owner = &kvmppc_uvmem_pgmap;
-
-       mutex_lock(&kvm->arch.uvmem_lock);
-       /* The requested page is already paged-out, nothing to do */
-       if (!kvmppc_gfn_is_uvmem_pfn(gpa >> page_shift, kvm, NULL))
-               goto out;
-
-       ret = migrate_vma_setup(&mig);
-       if (ret)
-               goto out;
-
-       spage = migrate_pfn_to_page(*mig.src);
-       if (!spage || !(*mig.src & MIGRATE_PFN_MIGRATE))
-               goto out_finalize;
-
-       if (!is_zone_device_page(spage))
-               goto out_finalize;
-
-       dpage = alloc_page_vma(GFP_HIGHUSER, vma, start);
-       if (!dpage) {
-               ret = -1;
-               goto out_finalize;
-       }
-
-       lock_page(dpage);
-       pvt = spage->zone_device_data;
-       pfn = page_to_pfn(dpage);
-
-       /*
-        * This function is used in two cases:
-        * - When HV touches a secure page, for which we do UV_PAGE_OUT
-        * - When a secure page is converted to shared page, we *get*
-        *   the page to essentially unmap the device page. In this
-        *   case we skip page-out.
-        */
-       if (!pvt->skip_page_out)
-               ret = uv_page_out(kvm->arch.lpid, pfn << page_shift,
-                                 gpa, 0, page_shift);
-
-       if (ret == U_SUCCESS)
-               *mig.dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
-       else {
-               unlock_page(dpage);
-               __free_page(dpage);
-               goto out_finalize;
-       }
-
-       migrate_vma_pages(&mig);
-out_finalize:
-       migrate_vma_finalize(&mig);
-out:
-       mutex_unlock(&kvm->arch.uvmem_lock);
-       return ret;
-}
 
 /*
  * Fault handler callback that gets called when HV touches any page that
-- 
2.27.0

Reply via email to