[Xen-devel,09/15] xen/x86: p2m: Use typesafe GFN in p2m_set_entry

Message ID 20170913175953.16942-10-julien.grall@arm.com
State New
Headers show
Series
  • xen/x86: Clean-up the PoD code
Related show

Commit Message

Julien Grall Sept. 13, 2017, 5:59 p.m.
Signed-off-by: Julien Grall <julien.grall@arm.com>

---

Cc: George Dunlap <george.dunlap@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Tamas K Lengyel <tamas@tklengyel.com>
---
 xen/arch/x86/mm/hap/nested_hap.c |   2 +-
 xen/arch/x86/mm/mem_sharing.c    |   3 +-
 xen/arch/x86/mm/p2m-pod.c        |  36 +++++++------
 xen/arch/x86/mm/p2m.c            | 112 ++++++++++++++++++++++-----------------
 xen/include/asm-x86/p2m.h        |   2 +-
 5 files changed, 85 insertions(+), 70 deletions(-)

Comments

Tamas K Lengyel Sept. 13, 2017, 8:16 p.m. | #1
On Wed, Sep 13, 2017 at 11:59 AM, Julien Grall <julien.grall@arm.com> wrote:
> Signed-off-by: Julien Grall <julien.grall@arm.com>
>

I guess the rest of the mem_sharing codebase would benefit from moving
to the use gfn_t as well, clearing up some of the gfn conversion stuff
that's needed right now..

Acked-by: Tamas K Lengyel <tamas@tklengyel.com>

Patch

diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_hap.c
index 162afed46b..346fcb53e5 100644
--- a/xen/arch/x86/mm/hap/nested_hap.c
+++ b/xen/arch/x86/mm/hap/nested_hap.c
@@ -121,7 +121,7 @@  nestedhap_fix_p2m(struct vcpu *v, struct p2m_domain *p2m,
         gfn = (L2_gpa >> PAGE_SHIFT) & mask;
         mfn = _mfn((L0_gpa >> PAGE_SHIFT) & mask);
 
-        rc = p2m_set_entry(p2m, gfn, mfn, page_order, p2mt, p2ma);
+        rc = p2m_set_entry(p2m, _gfn(gfn), mfn, page_order, p2mt, p2ma);
     }
 
     p2m_unlock(p2m);
diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index 4c1ace9b21..2f8c6fa746 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -1052,7 +1052,8 @@  int mem_sharing_add_to_physmap(struct domain *sd, unsigned long sgfn, shr_handle
         goto err_unlock;
     }
 
-    ret = p2m_set_entry(p2m, cgfn, smfn, PAGE_ORDER_4K, p2m_ram_shared, a);
+    ret = p2m_set_entry(p2m, _gfn(cgfn), smfn, PAGE_ORDER_4K,
+                        p2m_ram_shared, a);
 
     /* Tempted to turn this into an assert */
     if ( ret )
diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c
index c8c8cff014..b8a51cf12a 100644
--- a/xen/arch/x86/mm/p2m-pod.c
+++ b/xen/arch/x86/mm/p2m-pod.c
@@ -565,7 +565,7 @@  p2m_pod_decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
          * All PoD: Mark the whole region invalid and tell caller
          * we're done.
          */
-        p2m_set_entry(p2m, gfn_x(gfn), INVALID_MFN, order, p2m_invalid,
+        p2m_set_entry(p2m, gfn, INVALID_MFN, order, p2m_invalid,
                       p2m->default_access);
         p2m->pod.entry_count -= 1UL << order;
         BUG_ON(p2m->pod.entry_count < 0);
@@ -609,7 +609,7 @@  p2m_pod_decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
         n = 1UL << cur_order;
         if ( t == p2m_populate_on_demand )
         {
-            p2m_set_entry(p2m, gfn_x(gfn) + i, INVALID_MFN, cur_order,
+            p2m_set_entry(p2m, gfn_add(gfn, i), INVALID_MFN, cur_order,
                           p2m_invalid, p2m->default_access);
             p2m->pod.entry_count -= n;
             BUG_ON(p2m->pod.entry_count < 0);
@@ -631,7 +631,7 @@  p2m_pod_decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
 
             page = mfn_to_page(mfn);
 
-            p2m_set_entry(p2m, gfn_x(gfn) + i, INVALID_MFN, cur_order,
+            p2m_set_entry(p2m, gfn_add(gfn, i), INVALID_MFN, cur_order,
                           p2m_invalid, p2m->default_access);
             p2m_tlb_flush_sync(p2m);
             for ( j = 0; j < n; ++j )
@@ -680,9 +680,10 @@  void p2m_pod_dump_data(struct domain *d)
  * in the p2m.
  */
 static int
-p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
+p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn_l)
 {
     mfn_t mfn, mfn0 = INVALID_MFN;
+    gfn_t gfn = _gfn(gfn_l);
     p2m_type_t type, type0 = 0;
     unsigned long * map = NULL;
     int ret=0, reset = 0;
@@ -693,7 +694,7 @@  p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
 
     ASSERT(pod_locked_by_me(p2m));
 
-    if ( !superpage_aligned(gfn) )
+    if ( !superpage_aligned(gfn_l) )
         goto out;
 
     /* Allow an extra refcount for one shadow pt mapping in shadowed domains */
@@ -717,7 +718,7 @@  p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
         unsigned long k;
         const struct page_info *page;
 
-        mfn = p2m->get_entry(p2m, _gfn(gfn +  i), &type, &a, 0,
+        mfn = p2m->get_entry(p2m, gfn_add(gfn, i), &type, &a, 0,
                              &cur_order, NULL);
 
         /*
@@ -815,7 +816,7 @@  p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
             int d:16,order:16;
         } t;
 
-        t.gfn = gfn;
+        t.gfn = gfn_l;
         t.mfn = mfn_x(mfn);
         t.d = d->domain_id;
         t.order = 9;
@@ -898,7 +899,7 @@  p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count)
         }
 
         /* Try to remove the page, restoring old mapping if it fails. */
-        p2m_set_entry(p2m, gfns[i], INVALID_MFN, PAGE_ORDER_4K,
+        p2m_set_entry(p2m, _gfn(gfns[i]), INVALID_MFN, PAGE_ORDER_4K,
                       p2m_populate_on_demand, p2m->default_access);
 
         /*
@@ -910,7 +911,7 @@  p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count)
             unmap_domain_page(map[i]);
             map[i] = NULL;
 
-            p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K,
+            p2m_set_entry(p2m, _gfn(gfns[i]), mfns[i], PAGE_ORDER_4K,
                 types[i], p2m->default_access);
 
             continue;
@@ -937,7 +938,7 @@  p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count)
          */
         if ( j < (PAGE_SIZE / sizeof(*map[i])) )
         {
-            p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K,
+            p2m_set_entry(p2m, _gfn(gfns[i]), mfns[i], PAGE_ORDER_4K,
                           types[i], p2m->default_access);
         }
         else
@@ -1080,7 +1081,7 @@  p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn,
 {
     struct domain *d = p2m->domain;
     struct page_info *p = NULL; /* Compiler warnings */
-    unsigned long gfn_aligned = (gfn >> order) << order;
+    gfn_t gfn_aligned = _gfn((gfn >> order) << order);
     mfn_t mfn;
     unsigned long i;
 
@@ -1152,14 +1153,14 @@  p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn,
 
     for( i = 0; i < (1UL << order); i++ )
     {
-        set_gpfn_from_mfn(mfn_x(mfn) + i, gfn_aligned + i);
+        set_gpfn_from_mfn(mfn_x(mfn) + i, gfn_x(gfn_aligned) + i);
         paging_mark_dirty(d, mfn_add(mfn, i));
     }
 
     p2m->pod.entry_count -= (1UL << order);
     BUG_ON(p2m->pod.entry_count < 0);
 
-    pod_eager_record(p2m, gfn_aligned, order);
+    pod_eager_record(p2m, gfn_x(gfn_aligned), order);
 
     if ( tb_init_done )
     {
@@ -1199,7 +1200,7 @@  remap_and_retry:
      * need promoting the gfn lock from gfn->2M superpage.
      */
     for ( i = 0; i < (1UL << order); i++ )
-        p2m_set_entry(p2m, gfn_aligned + i, INVALID_MFN, PAGE_ORDER_4K,
+        p2m_set_entry(p2m, gfn_add(gfn_aligned, i), INVALID_MFN, PAGE_ORDER_4K,
                       p2m_populate_on_demand, p2m->default_access);
     if ( tb_init_done )
     {
@@ -1219,10 +1220,11 @@  remap_and_retry:
 
 
 int
-guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
+guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn_l,
                                       unsigned int order)
 {
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
+    gfn_t gfn = _gfn(gfn_l);
     unsigned long i, n, pod_count = 0;
     int rc = 0;
 
@@ -1231,7 +1233,7 @@  guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
 
     gfn_lock(p2m, gfn, order);
 
-    P2M_DEBUG("mark pod gfn=%#lx\n", gfn);
+    P2M_DEBUG("mark pod gfn=%#lx\n", gfn_l);
 
     /* Make sure all gpfns are unused */
     for ( i = 0; i < (1UL << order); i += n )
@@ -1240,7 +1242,7 @@  guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
         p2m_access_t a;
         unsigned int cur_order;
 
-        p2m->get_entry(p2m, _gfn(gfn + i), &ot, &a, 0, &cur_order, NULL);
+        p2m->get_entry(p2m, gfn_add(gfn, i), &ot, &a, 0, &cur_order, NULL);
         n = 1UL << min(order, cur_order);
         if ( p2m_is_ram(ot) )
         {
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 35d4a15391..3fbc537da6 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -532,7 +532,7 @@  struct page_info *p2m_get_page_from_gfn(
 }
 
 /* Returns: 0 for success, -errno for failure */
-int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
+int p2m_set_entry(struct p2m_domain *p2m, gfn_t gfn, mfn_t mfn,
                   unsigned int page_order, p2m_type_t p2mt, p2m_access_t p2ma)
 {
     struct domain *d = p2m->domain;
@@ -546,8 +546,9 @@  int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
     {
         if ( hap_enabled(d) )
         {
-            unsigned long fn_mask = !mfn_eq(mfn, INVALID_MFN) ?
-                                     (gfn | mfn_x(mfn) | todo) : (gfn | todo);
+            unsigned long fn_mask = !mfn_eq(mfn, INVALID_MFN) ? mfn_x(mfn) : 0;
+
+            fn_mask |= gfn_x(gfn) | todo;
 
             order = (!(fn_mask & ((1ul << PAGE_ORDER_1G) - 1)) &&
                      hap_has_1gb) ? PAGE_ORDER_1G :
@@ -557,11 +558,11 @@  int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
         else
             order = 0;
 
-        set_rc = p2m->set_entry(p2m, _gfn(gfn), mfn, order, p2mt, p2ma, -1);
+        set_rc = p2m->set_entry(p2m, gfn, mfn, order, p2mt, p2ma, -1);
         if ( set_rc )
             rc = set_rc;
 
-        gfn += 1ul << order;
+        gfn = gfn_add(gfn, 1ul << order);
         if ( !mfn_eq(mfn, INVALID_MFN) )
             mfn = mfn_add(mfn, 1ul << order);
         todo -= 1ul << order;
@@ -652,7 +653,7 @@  int p2m_alloc_table(struct p2m_domain *p2m)
 
     /* Initialise physmap tables for slot zero. Other code assumes this. */
     p2m->defer_nested_flush = 1;
-    rc = p2m_set_entry(p2m, 0, INVALID_MFN, PAGE_ORDER_4K,
+    rc = p2m_set_entry(p2m, _gfn(0), INVALID_MFN, PAGE_ORDER_4K,
                        p2m_invalid, p2m->default_access);
     p2m->defer_nested_flush = 0;
     p2m_unlock(p2m);
@@ -703,10 +704,11 @@  void p2m_final_teardown(struct domain *d)
 
 
 static int
-p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn, unsigned long mfn,
+p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn_l, unsigned long mfn,
                 unsigned int page_order)
 {
     unsigned long i;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn_return;
     p2m_type_t t;
     p2m_access_t a;
@@ -730,13 +732,13 @@  p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn, unsigned long mfn,
     }
 
     ASSERT(gfn_locked_by_me(p2m, gfn));
-    P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
+    P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn_l, mfn);
 
     if ( mfn_valid(_mfn(mfn)) )
     {
         for ( i = 0; i < (1UL << page_order); i++ )
         {
-            mfn_return = p2m->get_entry(p2m, _gfn(gfn + i), &t, &a, 0,
+            mfn_return = p2m->get_entry(p2m, gfn_add(gfn, i), &t, &a, 0,
                                         NULL, NULL);
             if ( !p2m_is_grant(t) && !p2m_is_shared(t) && !p2m_is_foreign(t) )
                 set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
@@ -901,7 +903,7 @@  guest_physmap_add_entry(struct domain *d, gfn_t gfn, mfn_t mfn,
     /* Now, actually do the two-way mapping */
     if ( mfn_valid(mfn) )
     {
-        rc = p2m_set_entry(p2m, gfn_x(gfn), mfn, page_order, t,
+        rc = p2m_set_entry(p2m, gfn, mfn, page_order, t,
                            p2m->default_access);
         if ( rc )
             goto out; /* Failed to update p2m, bail without updating m2p. */
@@ -917,7 +919,7 @@  guest_physmap_add_entry(struct domain *d, gfn_t gfn, mfn_t mfn,
     {
         gdprintk(XENLOG_WARNING, "Adding bad mfn to p2m map (%#lx -> %#lx)\n",
                  gfn_x(gfn), mfn_x(mfn));
-        rc = p2m_set_entry(p2m, gfn_x(gfn), INVALID_MFN, page_order,
+        rc = p2m_set_entry(p2m, gfn, INVALID_MFN, page_order,
                            p2m_invalid, p2m->default_access);
         if ( rc == 0 )
         {
@@ -940,11 +942,12 @@  out:
  * Returns: 0 for success, -errno for failure.
  * Resets the access permissions.
  */
-int p2m_change_type_one(struct domain *d, unsigned long gfn,
+int p2m_change_type_one(struct domain *d, unsigned long gfn_l,
                        p2m_type_t ot, p2m_type_t nt)
 {
     p2m_access_t a;
     p2m_type_t pt;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int rc;
@@ -954,7 +957,7 @@  int p2m_change_type_one(struct domain *d, unsigned long gfn,
 
     gfn_lock(p2m, gfn, 0);
 
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &pt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &pt, &a, 0, NULL, NULL);
     rc = likely(pt == ot)
          ? p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, nt,
                          p2m->default_access)
@@ -1111,7 +1114,7 @@  static int set_typed_p2m_entry(struct domain *d, unsigned long gfn_l,
     }
 
     P2M_DEBUG("set %d %lx %lx\n", gfn_p2mt, gfn_l, mfn_x(mfn));
-    rc = p2m_set_entry(p2m, gfn_l, mfn, order, gfn_p2mt, access);
+    rc = p2m_set_entry(p2m, gfn, mfn, order, gfn_p2mt, access);
     if ( rc )
         gdprintk(XENLOG_ERR, "p2m_set_entry: %#lx:%u -> %d (0x%"PRI_mfn")\n",
                  gfn_l, order, rc, mfn_x(mfn));
@@ -1146,11 +1149,12 @@  int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     return set_typed_p2m_entry(d, gfn, mfn, order, p2m_mmio_direct, access);
 }
 
-int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
+int set_identity_p2m_entry(struct domain *d, unsigned long gfn_l,
                            p2m_access_t p2ma, unsigned int flag)
 {
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int ret;
@@ -1159,17 +1163,17 @@  int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
     {
         if ( !need_iommu(d) )
             return 0;
-        return iommu_map_page(d, gfn, gfn, IOMMUF_readable|IOMMUF_writable);
+        return iommu_map_page(d, gfn_l, gfn_l, IOMMUF_readable|IOMMUF_writable);
     }
 
     gfn_lock(p2m, gfn, 0);
 
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
 
     if ( p2mt == p2m_invalid || p2mt == p2m_mmio_dm )
-        ret = p2m_set_entry(p2m, gfn, _mfn(gfn), PAGE_ORDER_4K,
+        ret = p2m_set_entry(p2m, gfn, _mfn(gfn_l), PAGE_ORDER_4K,
                             p2m_mmio_direct, p2ma);
-    else if ( mfn_x(mfn) == gfn && p2mt == p2m_mmio_direct && a == p2ma )
+    else if ( mfn_x(mfn) == gfn_l && p2mt == p2m_mmio_direct && a == p2ma )
         ret = 0;
     else
     {
@@ -1180,7 +1184,7 @@  int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
         printk(XENLOG_G_WARNING
                "Cannot setup identity map d%d:%lx,"
                " gfn already mapped to %lx.\n",
-               d->domain_id, gfn, mfn_x(mfn));
+               d->domain_id, gfn_l, mfn_x(mfn));
     }
 
     gfn_unlock(p2m, gfn, 0);
@@ -1194,10 +1198,11 @@  int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
  *    order+1  for caller to retry with order (guaranteed smaller than
  *             the order value passed in)
  */
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
+int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn,
                          unsigned int order)
 {
     int rc = -EINVAL;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t actual_mfn;
     p2m_access_t a;
     p2m_type_t t;
@@ -1208,7 +1213,7 @@  int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
         return -EIO;
 
     gfn_lock(p2m, gfn, order);
-    actual_mfn = p2m->get_entry(p2m, _gfn(gfn), &t, &a, 0, &cur_order, NULL);
+    actual_mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, &cur_order, NULL);
     if ( cur_order < order )
     {
         rc = cur_order + 1;
@@ -1219,13 +1224,13 @@  int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     if ( mfn_eq(actual_mfn, INVALID_MFN) || (t != p2m_mmio_direct) )
     {
         gdprintk(XENLOG_ERR,
-                 "gfn_to_mfn failed! gfn=%08lx type:%d\n", gfn, t);
+                 "gfn_to_mfn failed! gfn=%08lx type:%d\n", gfn_l, t);
         goto out;
     }
     if ( mfn_x(mfn) != mfn_x(actual_mfn) )
         gdprintk(XENLOG_WARNING,
                  "no mapping between mfn %08lx and gfn %08lx\n",
-                 mfn_x(mfn), gfn);
+                 mfn_x(mfn), gfn_l);
     rc = p2m_set_entry(p2m, gfn, INVALID_MFN, order, p2m_invalid,
                        p2m->default_access);
 
@@ -1235,10 +1240,11 @@  int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     return rc;
 }
 
-int clear_identity_p2m_entry(struct domain *d, unsigned long gfn)
+int clear_identity_p2m_entry(struct domain *d, unsigned long gfn_l)
 {
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int ret;
@@ -1247,13 +1253,13 @@  int clear_identity_p2m_entry(struct domain *d, unsigned long gfn)
     {
         if ( !need_iommu(d) )
             return 0;
-        return iommu_unmap_page(d, gfn);
+        return iommu_unmap_page(d, gfn_l);
     }
 
     gfn_lock(p2m, gfn, 0);
 
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
-    if ( p2mt == p2m_mmio_direct && mfn_x(mfn) == gfn )
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
+    if ( p2mt == p2m_mmio_direct && mfn_x(mfn) == gfn_l )
     {
         ret = p2m_set_entry(p2m, gfn, INVALID_MFN, PAGE_ORDER_4K,
                             p2m_invalid, p2m->default_access);
@@ -1264,7 +1270,7 @@  int clear_identity_p2m_entry(struct domain *d, unsigned long gfn)
         gfn_unlock(p2m, gfn, 0);
         printk(XENLOG_G_WARNING
                "non-identity map d%d:%lx not cleared (mapped to %lx)\n",
-               d->domain_id, gfn, mfn_x(mfn));
+               d->domain_id, gfn_l, mfn_x(mfn));
         ret = 0;
     }
 
@@ -1272,10 +1278,11 @@  int clear_identity_p2m_entry(struct domain *d, unsigned long gfn)
 }
 
 /* Returns: 0 for success, -errno for failure */
-int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+int set_shared_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn)
 {
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int rc = 0;
+    gfn_t gfn = _gfn(gfn_l);
     p2m_access_t a;
     p2m_type_t ot;
     mfn_t omfn;
@@ -1285,7 +1292,7 @@  int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
         return -EIO;
 
     gfn_lock(p2m, gfn, 0);
-    omfn = p2m->get_entry(p2m, _gfn(gfn), &ot, &a, 0, NULL, NULL);
+    omfn = p2m->get_entry(p2m, gfn, &ot, &a, 0, NULL, NULL);
     /* At the moment we only allow p2m change if gfn has already been made
      * sharable first */
     ASSERT(p2m_is_shared(ot));
@@ -1297,14 +1304,14 @@  int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
          || (pg_type & PGT_type_mask) != PGT_shared_page )
         set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
 
-    P2M_DEBUG("set shared %lx %lx\n", gfn, mfn_x(mfn));
+    P2M_DEBUG("set shared %lx %lx\n", gfn_l, mfn_x(mfn));
     rc = p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, p2m_ram_shared,
                        p2m->default_access);
     gfn_unlock(p2m, gfn, 0);
     if ( rc )
         gdprintk(XENLOG_ERR,
                  "p2m_set_entry failed! mfn=%08lx rc:%d\n",
-                 mfn_x(get_gfn_query_unlocked(p2m->domain, gfn, &ot)), rc);
+                 mfn_x(get_gfn_query_unlocked(p2m->domain, gfn_l, &ot)), rc);
     return rc;
 }
 
@@ -1326,18 +1333,19 @@  int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
  * Once the p2mt is changed the page is readonly for the guest.  On success the
  * pager can write the page contents to disk and later evict the page.
  */
-int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn)
+int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn_l)
 {
     struct page_info *page;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     int ret = -EBUSY;
 
     gfn_lock(p2m, gfn, 0);
 
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
 
     /* Check if mfn is valid */
     if ( !mfn_valid(mfn) )
@@ -1387,11 +1395,12 @@  int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn)
  * could evict it, eviction can not be done either. In this case the gfn is
  * still backed by a mfn.
  */
-int p2m_mem_paging_evict(struct domain *d, unsigned long gfn)
+int p2m_mem_paging_evict(struct domain *d, unsigned long gfn_l)
 {
     struct page_info *page;
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int ret = -EBUSY;
@@ -1399,7 +1408,7 @@  int p2m_mem_paging_evict(struct domain *d, unsigned long gfn)
     gfn_lock(p2m, gfn, 0);
 
     /* Get mfn */
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
     if ( unlikely(!mfn_valid(mfn)) )
         goto out;
 
@@ -1502,15 +1511,16 @@  void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn,
  * already sent to the pager. In this case the caller has to try again until the
  * gfn is fully paged in again.
  */
-void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
+void p2m_mem_paging_populate(struct domain *d, unsigned long gfn_l)
 {
     struct vcpu *v = current;
     vm_event_request_t req = {
         .reason = VM_EVENT_REASON_MEM_PAGING,
-        .u.mem_paging.gfn = gfn
+        .u.mem_paging.gfn = gfn_l
     };
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
@@ -1519,7 +1529,7 @@  void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
     if ( rc == -ENOSYS )
     {
         gdprintk(XENLOG_ERR, "Domain %hu paging gfn %lx yet no ring "
-                             "in place\n", d->domain_id, gfn);
+                             "in place\n", d->domain_id, gfn_l);
         /* Prevent the vcpu from faulting repeatedly on the same gfn */
         if ( v->domain == d )
             vcpu_pause_nosync(v);
@@ -1531,7 +1541,7 @@  void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
 
     /* Fix p2m mapping */
     gfn_lock(p2m, gfn, 0);
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
     /* Allow only nominated or evicted pages to enter page-in path */
     if ( p2mt == p2m_ram_paging_out || p2mt == p2m_ram_paged )
     {
@@ -1575,11 +1585,12 @@  void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
  * mfn if populate was called for  gfn which was nominated but not evicted. In
  * this case only the p2mt needs to be forwarded.
  */
-int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, uint64_t buffer)
+int p2m_mem_paging_prep(struct domain *d, unsigned long gfn_l, uint64_t buffer)
 {
     struct page_info *page;
     p2m_type_t p2mt;
     p2m_access_t a;
+    gfn_t gfn = _gfn(gfn_l);
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int ret, page_extant = 1;
@@ -1593,7 +1604,7 @@  int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, uint64_t buffer)
 
     gfn_lock(p2m, gfn, 0);
 
-    mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
 
     ret = -ENOENT;
     /* Allow missing pages */
@@ -1629,7 +1640,7 @@  int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, uint64_t buffer)
         if ( rc )
         {
             gdprintk(XENLOG_ERR, "Failed to load paging-in gfn %lx domain %u "
-                                 "bytes left %d\n", gfn, d->domain_id, rc);
+                                 "bytes left %d\n", gfn_l, d->domain_id, rc);
             ret = -EFAULT;
             put_page(page); /* Don't leak pages */
             goto out;            
@@ -1642,7 +1653,7 @@  int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, uint64_t buffer)
     ret = p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K,
                         paging_mode_log_dirty(d) ? p2m_ram_logdirty
                                                  : p2m_ram_rw, a);
-    set_gpfn_from_mfn(mfn_x(mfn), gfn);
+    set_gpfn_from_mfn(mfn_x(mfn), gfn_l);
 
     if ( !page_extant )
         atomic_dec(&d->paged_pages);
@@ -1678,10 +1689,10 @@  void p2m_mem_paging_resume(struct domain *d, vm_event_response_t *rsp)
     /* Fix p2m entry if the page was not dropped */
     if ( !(rsp->u.mem_paging.flags & MEM_PAGING_DROP_PAGE) )
     {
-        unsigned long gfn = rsp->u.mem_access.gfn;
+        gfn_t gfn = _gfn(rsp->u.mem_access.gfn);
 
         gfn_lock(p2m, gfn, 0);
-        mfn = p2m->get_entry(p2m, _gfn(gfn), &p2mt, &a, 0, NULL, NULL);
+        mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
         /*
          * Allow only pages which were prepared properly, or pages which
          * were nominated but not evicted.
@@ -1691,7 +1702,7 @@  void p2m_mem_paging_resume(struct domain *d, vm_event_response_t *rsp)
             p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K,
                           paging_mode_log_dirty(d) ? p2m_ram_logdirty :
                           p2m_ram_rw, a);
-            set_gpfn_from_mfn(mfn_x(mfn), gfn);
+            set_gpfn_from_mfn(mfn_x(mfn), gfn_x(gfn));
         }
         gfn_unlock(p2m, gfn, 0);
     }
@@ -2109,8 +2120,9 @@  bool_t p2m_altp2m_lazy_copy(struct vcpu *v, paddr_t gpa,
      */
     mask = ~((1UL << page_order) - 1);
     mfn = _mfn(mfn_x(mfn) & mask);
+    gfn = _gfn(gfn_x(gfn) & mask);
 
-    rv = p2m_set_entry(*ap2m, gfn_x(gfn) & mask, mfn, page_order, p2mt, p2ma);
+    rv = p2m_set_entry(*ap2m, gfn, mfn, page_order, p2mt, p2ma);
     p2m_unlock(*ap2m);
 
     if ( rv )
@@ -2396,7 +2408,7 @@  void p2m_altp2m_propagate_change(struct domain *d, gfn_t gfn,
             }
         }
         else if ( !mfn_eq(m, INVALID_MFN) )
-            p2m_set_entry(p2m, gfn_x(gfn), mfn, page_order, p2mt, p2ma);
+            p2m_set_entry(p2m, gfn, mfn, page_order, p2mt, p2ma);
 
         __put_gfn(p2m, gfn_x(gfn));
     }
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 1c9a51e9ad..07ca02a173 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -682,7 +682,7 @@  void p2m_free_ptp(struct p2m_domain *p2m, struct page_info *pg);
 
 /* Directly set a p2m entry: only for use by p2m code. Does not need
  * a call to put_gfn afterwards/ */
-int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
+int p2m_set_entry(struct p2m_domain *p2m, gfn_t gfn, mfn_t mfn,
                   unsigned int page_order, p2m_type_t p2mt, p2m_access_t p2ma);
 
 /* Set up function pointers for PT implementation: only for use by p2m code */