diff --git a/stubdom/grub/kexec.c b/stubdom/grub/kexec.c
index 61ca082d42..10891eabcc 100644
--- a/stubdom/grub/kexec.c
+++ b/stubdom/grub/kexec.c
@@ -320,14 +320,6 @@ void kexec(void *kernel, long kernel_size, void *module, long module_size, char
     do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base),
             virt_to_mfn(&_boot_page));
 
-    /* Make sure the bootstrap page table does not RW-map any of our current
-     * page table frames */
-    if ( (rc = xc_dom_update_guest_p2m(dom))) {
-        printk("xc_dom_update_guest_p2m returned %d\n", rc);
-        errnum = ERR_BOOT_FAILURE;
-        goto out;
-    }
-
     if ( dom->arch_hooks->setup_pgtables )
         if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
             printk("setup_pgtables returned %d\n", rc);
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 9ff1cb8b07..b7d0faf7e1 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -133,7 +133,6 @@ struct xc_dom_image {
      * Note that the input is offset by rambase.
      */
     xen_pfn_t *p2m_host;
-    void *p2m_guest;
 
     /* physical memory
      *
@@ -331,7 +330,6 @@ int xc_dom_devicetree_mem(struct xc_dom_image *dom, const void *mem,
 int xc_dom_parse_image(struct xc_dom_image *dom);
 int xc_dom_set_arch_hooks(struct xc_dom_image *dom);
 int xc_dom_build_image(struct xc_dom_image *dom);
-int xc_dom_update_guest_p2m(struct xc_dom_image *dom);
 
 int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch,
                          uint32_t domid);
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 79dbbf6571..bb599b33ba 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -197,8 +197,6 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
         return -1;
 
     /* initial mm setup */
-    if ( (rc = xc_dom_update_guest_p2m(dom)) != 0 )
-        return rc;
     if ( dom->arch_hooks->setup_pgtables &&
          (rc = dom->arch_hooks->setup_pgtables(dom)) != 0 )
         return rc;
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index fc77804a7e..f30c73b5e8 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -969,46 +969,6 @@ int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb)
     return 0;
 }
 
-int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
-{
-    uint32_t *p2m_32;
-    uint64_t *p2m_64;
-    xen_pfn_t i;
-
-    if ( !dom->p2m_guest )
-        return 0;
-
-    switch ( dom->arch_hooks->sizeof_pfn )
-    {
-    case 4:
-        DOMPRINTF("%s: dst 32bit, pages 0x%" PRIpfn "",
-                  __FUNCTION__, dom->p2m_size);
-        p2m_32 = dom->p2m_guest;
-        for ( i = 0; i < dom->p2m_size; i++ )
-            if ( dom->p2m_host[i] != INVALID_PFN )
-                p2m_32[i] = dom->p2m_host[i];
-            else
-                p2m_32[i] = (uint32_t) - 1;
-        break;
-    case 8:
-        DOMPRINTF("%s: dst 64bit, pages 0x%" PRIpfn "",
-                  __FUNCTION__, dom->p2m_size);
-        p2m_64 = dom->p2m_guest;
-        for ( i = 0; i < dom->p2m_size; i++ )
-            if ( dom->p2m_host[i] != INVALID_PFN )
-                p2m_64[i] = dom->p2m_host[i];
-            else
-                p2m_64[i] = (uint64_t) - 1;
-        break;
-    default:
-        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
-                     "sizeof_pfn is invalid (is %d, can be 4 or 8)",
-                     dom->arch_hooks->sizeof_pfn);
-        return -1;
-    }
-    return 0;
-}
-
 static int xc_dom_build_module(struct xc_dom_image *dom, unsigned int mod)
 {
     size_t unziplen, modulelen;
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index d2acff1061..f21662c8b9 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -104,6 +104,9 @@ struct xc_dom_image_x86 {
 #define MAPPING_MAX 2
     struct xc_dom_x86_mapping maps[MAPPING_MAX];
     const struct xc_dom_params *params;
+
+    /* PV: Pointer to the in-guest P2M. */
+    void *p2m_guest;
 };
 
 /* get guest IO ABI protocol */
@@ -296,6 +299,8 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
                                   xen_pfn_t l3pfn,
                                   xen_pfn_t l3mfn)
 {
+    struct xc_dom_image_x86 *domx86 = dom->arch_private;
+    uint32_t *p2m_guest = domx86->p2m_guest;
     xen_pfn_t new_l3mfn;
     struct xc_mmu *mmu;
     void *l3tab;
@@ -313,9 +318,7 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
     if ( !new_l3mfn )
         goto out;
 
-    dom->p2m_host[l3pfn] = new_l3mfn;
-    if ( xc_dom_update_guest_p2m(dom) != 0 )
-        goto out;
+    p2m_guest[l3pfn] = dom->p2m_host[l3pfn] = new_l3mfn;
 
     if ( xc_add_mmu_update(dom->xch, mmu,
                            (((unsigned long long)new_l3mfn)
@@ -444,7 +447,17 @@ static int setup_pgtables_pv(struct xc_dom_image *dom)
 static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
 {
     struct xc_dom_image_x86 *domx86 = dom->arch_private;
-    xen_pfn_t l3mfn, l3pfn;
+    uint32_t *p2m_guest = domx86->p2m_guest;
+    xen_pfn_t l3mfn, l3pfn, i;
+
+    /* Copy dom->p2m_host[] into the guest. */
+    for ( i = 0; i < dom->p2m_size; ++i )
+    {
+        if ( dom->p2m_host[i] != INVALID_PFN )
+            p2m_guest[i] = dom->p2m_host[i];
+        else
+            p2m_guest[i] = -1;
+    }
 
     l3pfn = domx86->maps[0].lvls[2].pfn;
     l3mfn = xc_dom_p2m(dom, l3pfn);
@@ -488,6 +501,19 @@ static int alloc_pgtables_x86_64(struct xc_dom_image *dom)
 
 static int setup_pgtables_x86_64(struct xc_dom_image *dom)
 {
+    struct xc_dom_image_x86 *domx86 = dom->arch_private;
+    uint64_t *p2m_guest = domx86->p2m_guest;
+    xen_pfn_t i;
+
+    /* Copy dom->p2m_host[] into the guest. */
+    for ( i = 0; i < dom->p2m_size; ++i )
+    {
+        if ( dom->p2m_host[i] != INVALID_PFN )
+            p2m_guest[i] = dom->p2m_host[i];
+        else
+            p2m_guest[i] = -1;
+    }
+
     return setup_pgtables_pv(dom);
 }
 
@@ -495,11 +521,14 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
 
 static int alloc_p2m_list(struct xc_dom_image *dom, size_t p2m_alloc_size)
 {
+    struct xc_dom_image_x86 *domx86 = dom->arch_private;
+
     if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach",
                               0, p2m_alloc_size) )
         return -1;
-    dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
-    if ( dom->p2m_guest == NULL )
+
+    domx86->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
+    if ( domx86->p2m_guest == NULL )
         return -1;
 
     return 0;
