[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 06 of 11] x86: Use get_page_from_gfn() instead of get_gfn()/put_gfn



# HG changeset patch
# User Tim Deegan <tim@xxxxxxx>
# Date 1336661656 -3600
# Node ID d19b3ba026fd844d21a250f768f70a1543d6bbd7
# Parent  c68f83ff7bf403637ade5a6002a7749226602c05
x86: Use get_page_from_gfn() instead of get_gfn()/put_gfn.

Signed-off-by: Tim Deegan <tim@xxxxxxx>

diff -r c68f83ff7bf4 -r d19b3ba026fd xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu May 10 15:54:16 2012 +0100
+++ b/xen/arch/x86/domain.c     Thu May 10 15:54:16 2012 +0100
@@ -716,7 +716,7 @@ int arch_set_info_guest(
 {
     struct domain *d = v->domain;
     unsigned long cr3_gfn;
-    unsigned long cr3_pfn = INVALID_MFN;
+    struct page_info *cr3_page;
     unsigned long flags, cr4;
     unsigned int i;
     int rc = 0, compat;
@@ -925,46 +925,45 @@ int arch_set_info_guest(
     if ( !compat )
     {
         cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]);
-        cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+        cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
 
-        if ( !mfn_valid(cr3_pfn) ||
-             (paging_mode_refcounts(d)
-              ? !get_page(mfn_to_page(cr3_pfn), d)
-              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                   PGT_base_page_table)) )
+        if ( !cr3_page )
         {
-            put_gfn(d, cr3_gfn);
+            destroy_gdt(v);
+            return -EINVAL;
+        }
+        if ( !paging_mode_refcounts(d)
+             && !get_page_type(cr3_page, PGT_base_page_table) )
+        {
+            put_page(cr3_page);
             destroy_gdt(v);
             return -EINVAL;
         }
 
-        v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
-        put_gfn(d, cr3_gfn);
+        v->arch.guest_table = pagetable_from_page(cr3_page);
 #ifdef __x86_64__
         if ( c.nat->ctrlreg[1] )
         {
             cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[1]);
-            cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+            cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
 
-            if ( !mfn_valid(cr3_pfn) ||
-                 (paging_mode_refcounts(d)
-                  ? !get_page(mfn_to_page(cr3_pfn), d)
-                  : !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                       PGT_base_page_table)) )
+            if ( !cr3_page ||
+                 (!paging_mode_refcounts(d)
+                  && !get_page_type(cr3_page, PGT_base_page_table)) )
             {
-                cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
+                if (cr3_page)
+                    put_page(cr3_page);
+                cr3_page = pagetable_get_page(v->arch.guest_table);
                 v->arch.guest_table = pagetable_null();
                 if ( paging_mode_refcounts(d) )
-                    put_page(mfn_to_page(cr3_pfn));
+                    put_page(cr3_page);
                 else
-                    put_page_and_type(mfn_to_page(cr3_pfn));
-                put_gfn(d, cr3_gfn); 
+                    put_page_and_type(cr3_page);
                 destroy_gdt(v);
                 return -EINVAL;
             }
 
-            v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
-            put_gfn(d, cr3_gfn); 
+            v->arch.guest_table_user = pagetable_from_page(cr3_page);
         }
         else if ( !(flags & VGCF_in_kernel) )
         {
@@ -977,23 +976,25 @@ int arch_set_info_guest(
         l4_pgentry_t *l4tab;
 
         cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
-        cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+        cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
 
-        if ( !mfn_valid(cr3_pfn) ||
-             (paging_mode_refcounts(d)
-              ? !get_page(mfn_to_page(cr3_pfn), d)
-              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                   PGT_l3_page_table)) )
+        if ( !cr3_page)
         {
-            put_gfn(d, cr3_gfn); 
+            destroy_gdt(v);
+            return -EINVAL;
+        }
+
+        if (!paging_mode_refcounts(d)
+            && !get_page_type(cr3_page, PGT_l3_page_table) )
+        {
+            put_page(cr3_page);
             destroy_gdt(v);
             return -EINVAL;
         }
 
         l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
-        *l4tab = l4e_from_pfn(
-            cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
-        put_gfn(d, cr3_gfn); 
+        *l4tab = l4e_from_pfn(page_to_mfn(cr3_page),
+            _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
 #endif
     }
 
@@ -1064,7 +1065,7 @@ map_vcpu_info(struct vcpu *v, unsigned l
     struct domain *d = v->domain;
     void *mapping;
     vcpu_info_t *new_info;
-    unsigned long mfn;
+    struct page_info *page;
     int i;
 
     if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) )
@@ -1077,19 +1078,20 @@ map_vcpu_info(struct vcpu *v, unsigned l
     if ( (v != current) && !test_bit(_VPF_down, &v->pause_flags) )
         return -EINVAL;
 
-    mfn = get_gfn_untyped(d, gfn);
-    if ( !mfn_valid(mfn) ||
-         !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+    page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
+    if ( !page )
+        return -EINVAL;
+
+    if ( !get_page_type(page, PGT_writable_page) )
     {
-        put_gfn(d, gfn); 
+        put_page(page);
         return -EINVAL;
     }
 
-    mapping = map_domain_page_global(mfn);
+    mapping = __map_domain_page_global(page);
     if ( mapping == NULL )
     {
-        put_page_and_type(mfn_to_page(mfn));
-        put_gfn(d, gfn); 
+        put_page_and_type(page);
         return -ENOMEM;
     }
 
@@ -1106,7 +1108,7 @@ map_vcpu_info(struct vcpu *v, unsigned l
     }
 
     v->vcpu_info = new_info;
-    v->arch.pv_vcpu.vcpu_info_mfn = mfn;
+    v->arch.pv_vcpu.vcpu_info_mfn = page_to_mfn(page);
 
     /* Set new vcpu_info pointer /before/ setting pending flags. */
     wmb();
@@ -1119,7 +1121,6 @@ map_vcpu_info(struct vcpu *v, unsigned l
     for ( i = 0; i < BITS_PER_EVTCHN_WORD(d); i++ )
         set_bit(i, &vcpu_info(v, evtchn_pending_sel));
 
-    put_gfn(d, gfn); 
     return 0;
 }
 
diff -r c68f83ff7bf4 -r d19b3ba026fd xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Thu May 10 15:54:16 2012 +0100
+++ b/xen/arch/x86/domctl.c     Thu May 10 15:54:16 2012 +0100
@@ -202,16 +202,16 @@ long arch_do_domctl(
 
                 for ( j = 0; j < k; j++ )
                 {
-                    unsigned long type = 0, mfn = get_gfn_untyped(d, arr[j]);
+                    unsigned long type = 0;
 
-                    page = mfn_to_page(mfn);
+                    page = get_page_from_gfn(d, arr[j], NULL, P2M_ALLOC);
 
-                    if ( unlikely(!mfn_valid(mfn)) ||
-                         unlikely(is_xen_heap_mfn(mfn)) )
+                    if ( unlikely(!page) ||
+                         unlikely(is_xen_heap_page(page)) )
                         type = XEN_DOMCTL_PFINFO_XTAB;
                     else if ( xsm_getpageframeinfo(page) != 0 )
                         ;
-                    else if ( likely(get_page(page, d)) )
+                    else
                     {
                         switch( page->u.inuse.type_info & PGT_type_mask )
                         {
@@ -231,13 +231,10 @@ long arch_do_domctl(
 
                         if ( page->u.inuse.type_info & PGT_pinned )
                             type |= XEN_DOMCTL_PFINFO_LPINTAB;
+                    }
 
+                    if ( page )
                         put_page(page);
-                    }
-                    else
-                        type = XEN_DOMCTL_PFINFO_XTAB;
-
-                    put_gfn(d, arr[j]);
                     arr[j] = type;
                 }
 
@@ -304,21 +301,21 @@ long arch_do_domctl(
             {      
                 struct page_info *page;
                 unsigned long gfn = arr32[j];
-                unsigned long mfn = get_gfn_untyped(d, gfn);
 
-                page = mfn_to_page(mfn);
+                page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
 
                 if ( domctl->cmd == XEN_DOMCTL_getpageframeinfo3)
                     arr32[j] = 0;
 
-                if ( unlikely(!mfn_valid(mfn)) ||
-                     unlikely(is_xen_heap_mfn(mfn)) )
+                if ( unlikely(!page) ||
+                     unlikely(is_xen_heap_page(page)) )
                     arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
                 else if ( xsm_getpageframeinfo(page) != 0 )
                 {
-                    put_gfn(d, gfn); 
+                    put_page(page);
                     continue;
-                } else if ( likely(get_page(page, d)) )
+                }
+                else
                 {
                     unsigned long type = 0;
 
@@ -341,12 +338,10 @@ long arch_do_domctl(
                     if ( page->u.inuse.type_info & PGT_pinned )
                         type |= XEN_DOMCTL_PFINFO_LPINTAB;
                     arr32[j] |= type;
+                }
+
+                if ( page )
                     put_page(page);
-                }
-                else
-                    arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
-
-                put_gfn(d, gfn); 
             }
 
             if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array,
@@ -419,7 +414,7 @@ long arch_do_domctl(
     {
         struct domain *d = rcu_lock_domain_by_id(domctl->domain);
         unsigned long gmfn = domctl->u.hypercall_init.gmfn;
-        unsigned long mfn;
+        struct page_info *page;
         void *hypercall_page;
 
         ret = -ESRCH;
@@ -433,26 +428,25 @@ long arch_do_domctl(
             break;
         }
 
-        mfn = get_gfn_untyped(d, gmfn);
+        page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
 
         ret = -EACCES;
-        if ( !mfn_valid(mfn) ||
-             !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+        if ( !page || !get_page_type(page, PGT_writable_page) )
         {
-            put_gfn(d, gmfn); 
+            if ( page )
+                put_page(page);
             rcu_unlock_domain(d);
             break;
         }
 
         ret = 0;
 
-        hypercall_page = map_domain_page(mfn);
+        hypercall_page = __map_domain_page(page);
         hypercall_page_initialise(d, hypercall_page);
         unmap_domain_page(hypercall_page);
 
-        put_page_and_type(mfn_to_page(mfn));
+        put_page_and_type(page);
 
-        put_gfn(d, gmfn); 
         rcu_unlock_domain(d);
     }
     break;
diff -r c68f83ff7bf4 -r d19b3ba026fd xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Thu May 10 15:54:16 2012 +0100
+++ b/xen/arch/x86/physdev.c    Thu May 10 15:54:16 2012 +0100
@@ -306,26 +306,27 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
     case PHYSDEVOP_pirq_eoi_gmfn_v1: {
         struct physdev_pirq_eoi_gmfn info;
         unsigned long mfn;
+        struct page_info *page;
 
         ret = -EFAULT;
         if ( copy_from_guest(&info, arg, 1) != 0 )
             break;
 
         ret = -EINVAL;
-        mfn = get_gfn_untyped(current->domain, info.gmfn);
-        if ( !mfn_valid(mfn) ||
-             !get_page_and_type(mfn_to_page(mfn), v->domain,
-                                PGT_writable_page) )
+        page = get_page_from_gfn(current->domain, info.gmfn, NULL, P2M_ALLOC);
+        if ( !page )
+            break;
+        if ( !get_page_type(page, PGT_writable_page) )
         {
-            put_gfn(current->domain, info.gmfn);
+            put_page(page);
             break;
         }
+        mfn = page_to_mfn(page);
 
         if ( cmpxchg(&v->domain->arch.pv_domain.pirq_eoi_map_mfn,
                      0, mfn) != 0 )
         {
             put_page_and_type(mfn_to_page(mfn));
-            put_gfn(current->domain, info.gmfn);
             ret = -EBUSY;
             break;
         }
@@ -335,14 +336,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         {
             v->domain->arch.pv_domain.pirq_eoi_map_mfn = 0;
             put_page_and_type(mfn_to_page(mfn));
-            put_gfn(current->domain, info.gmfn);
             ret = -ENOSPC;
             break;
         }
         if ( cmd == PHYSDEVOP_pirq_eoi_gmfn_v1 )
             v->domain->arch.pv_domain.auto_unmask = 1;
 
-        put_gfn(current->domain, info.gmfn);
         ret = 0;
         break;
     }
diff -r c68f83ff7bf4 -r d19b3ba026fd xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu May 10 15:54:16 2012 +0100
+++ b/xen/arch/x86/traps.c      Thu May 10 15:54:16 2012 +0100
@@ -662,9 +662,9 @@ int wrmsr_hypervisor_regs(uint32_t idx, 
     case 0:
     {
         void *hypercall_page;
-        unsigned long mfn;
         unsigned long gmfn = val >> 12;
         unsigned int idx  = val & 0xfff;
+        struct page_info *page;
 
         if ( idx > 0 )
         {
@@ -674,24 +674,23 @@ int wrmsr_hypervisor_regs(uint32_t idx, 
             return 0;
         }
 
-        mfn = get_gfn_untyped(d, gmfn);
-
-        if ( !mfn_valid(mfn) ||
-             !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+        page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
+
+        if ( !page || !get_page_type(page, PGT_writable_page) )
         {
-            put_gfn(d, gmfn);
+            if ( page )
+                put_page(page);
             gdprintk(XENLOG_WARNING,
                      "Bad GMFN %lx (MFN %lx) to MSR %08x\n",
-                     gmfn, mfn, base + idx);
+                     gmfn, page_to_mfn(page), base + idx);
             return 0;
         }
 
-        hypercall_page = map_domain_page(mfn);
+        hypercall_page = __map_domain_page(page);
         hypercall_page_initialise(d, hypercall_page);
         unmap_domain_page(hypercall_page);
 
-        put_page_and_type(mfn_to_page(mfn));
-        put_gfn(d, gmfn);
+        put_page_and_type(page);
         break;
     }
 
@@ -2374,7 +2373,8 @@ static int emulate_privileged_op(struct 
             break;
 
         case 3: {/* Write CR3 */
-            unsigned long mfn, gfn;
+            unsigned long gfn;
+            struct page_info *page;
             domain_lock(v->domain);
             if ( !is_pv_32on64_vcpu(v) )
             {
@@ -2384,9 +2384,10 @@ static int emulate_privileged_op(struct 
                 gfn = compat_cr3_to_pfn(*reg);
 #endif
             }
-            mfn = get_gfn_untyped(v->domain, gfn);
-            rc = new_guest_cr3(mfn);
-            put_gfn(v->domain, gfn);
+            page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
+            rc = page ? new_guest_cr3(page_to_mfn(page)) : 0;
+            if ( page )
+                put_page(page);
             domain_unlock(v->domain);
             if ( rc == 0 ) /* not okay */
                 goto fail;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.