WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Nested Virtualization: p2m infrastructure

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Nested Virtualization: p2m infrastructure
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 11 Aug 2010 13:55:49 -0700
Delivery-date: Wed, 11 Aug 2010 13:58:35 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1281368802 -3600
# Node ID e7afe98afd4372010ac4fdb7d0d7c948f821feee
# Parent  9e58c46ee63b3201a0a08b631ed4b79c72cf91a3
Nested Virtualization: p2m infrastructure

Change p2m infrastructure to operate on per-p2m instead of per-domain.
This allows us to use multiple p2m tables per-domain.

Signed-off-by: Christoph Egger <Christoph.Egger@xxxxxxx>
Acked-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 xen/arch/x86/debug.c              |    2 
 xen/arch/x86/domain.c             |    2 
 xen/arch/x86/domctl.c             |    4 
 xen/arch/x86/hvm/emulate.c        |   10 
 xen/arch/x86/hvm/hvm.c            |   50 +-
 xen/arch/x86/hvm/mtrr.c           |    2 
 xen/arch/x86/hvm/stdvga.c         |    5 
 xen/arch/x86/hvm/svm/svm.c        |    9 
 xen/arch/x86/hvm/vmx/vmx.c        |   18 
 xen/arch/x86/mm.c                 |   57 +-
 xen/arch/x86/mm/guest_walk.c      |   15 
 xen/arch/x86/mm/hap/guest_walk.c  |   12 
 xen/arch/x86/mm/hap/hap.c         |   38 +
 xen/arch/x86/mm/hap/p2m-ept.c     |  148 ++++---
 xen/arch/x86/mm/mem_event.c       |    4 
 xen/arch/x86/mm/mem_paging.c      |    9 
 xen/arch/x86/mm/mem_sharing.c     |   31 -
 xen/arch/x86/mm/p2m.c             |  736 +++++++++++++++++++-------------------
 xen/arch/x86/mm/shadow/common.c   |   38 +
 xen/arch/x86/mm/shadow/multi.c    |   49 +-
 xen/common/grant_table.c          |   12 
 xen/common/memory.c               |    4 
 xen/common/tmem_xen.c             |    2 
 xen/include/asm-x86/guest_pt.h    |    4 
 xen/include/asm-x86/mem_sharing.h |    6 
 xen/include/asm-x86/p2m.h         |  134 +++---
 26 files changed, 746 insertions(+), 655 deletions(-)

diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/debug.c
--- a/xen/arch/x86/debug.c      Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/debug.c      Mon Aug 09 16:46:42 2010 +0100
@@ -61,7 +61,7 @@ dbg_hvm_va2mfn(dbgva_t vaddr, struct dom
         return INVALID_MFN;
     }
 
-    mfn = mfn_x(gfn_to_mfn(dp, gfn, &gfntype)); 
+    mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(dp), gfn, &gfntype)); 
     if ( p2m_is_readonly(gfntype) && toaddr )
     {
         DBGP2("kdb:p2m_is_readonly: gfntype:%x\n", gfntype);
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/domain.c     Mon Aug 09 16:46:42 2010 +0100
@@ -151,7 +151,7 @@ void dump_pageframe_info(struct domain *
 
     if ( is_hvm_domain(d) )
     {
-        p2m_pod_dump_data(d);
+        p2m_pod_dump_data(p2m_get_hostp2m(d));
     }
 
     spin_lock(&d->page_alloc_lock);
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/domctl.c     Mon Aug 09 16:46:42 2010 +0100
@@ -982,7 +982,7 @@ long arch_do_domctl(
 
             ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
             for ( i = 0; i < nr_mfns; i++ )
-                set_mmio_p2m_entry(d, gfn+i, _mfn(mfn+i));
+                set_mmio_p2m_entry(p2m_get_hostp2m(d), gfn+i, _mfn(mfn+i));
         }
         else
         {
@@ -991,7 +991,7 @@ long arch_do_domctl(
                  gfn, mfn, nr_mfns);
 
             for ( i = 0; i < nr_mfns; i++ )
-                clear_mmio_p2m_entry(d, gfn+i);
+                clear_mmio_p2m_entry(p2m_get_hostp2m(d), gfn+i);
             ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
         }
 
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/emulate.c
--- a/xen/arch/x86/hvm/emulate.c        Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/emulate.c        Mon Aug 09 16:46:42 2010 +0100
@@ -55,6 +55,7 @@ int hvmemul_do_io(
     paddr_t value = ram_gpa;
     int value_is_ptr = (p_data == NULL);
     struct vcpu *curr = current;
+    struct p2m_domain *p2m = p2m_get_hostp2m(curr->domain);
     ioreq_t *p = get_ioreq(curr);
     unsigned long ram_gfn = paddr_to_pfn(ram_gpa);
     p2m_type_t p2mt;
@@ -62,10 +63,10 @@ int hvmemul_do_io(
     int rc;
 
     /* Check for paged out page */
-    ram_mfn = gfn_to_mfn_unshare(current->domain, ram_gfn, &p2mt, 0);
+    ram_mfn = gfn_to_mfn_unshare(p2m, ram_gfn, &p2mt, 0);
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(curr->domain, ram_gfn);
+        p2m_mem_paging_populate(p2m, ram_gfn);
         return X86EMUL_RETRY;
     }
     if ( p2m_is_shared(p2mt) )
@@ -638,6 +639,7 @@ static int hvmemul_rep_movs(
     unsigned long saddr, daddr, bytes;
     paddr_t sgpa, dgpa;
     uint32_t pfec = PFEC_page_present;
+    struct p2m_domain *p2m = p2m_get_hostp2m(current->domain);
     p2m_type_t p2mt;
     int rc, df = !!(ctxt->regs->eflags & X86_EFLAGS_DF);
     char *buf;
@@ -668,12 +670,12 @@ static int hvmemul_rep_movs(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    (void)gfn_to_mfn_current(sgpa >> PAGE_SHIFT, &p2mt);
+    (void)gfn_to_mfn(p2m, sgpa >> PAGE_SHIFT, &p2mt);
     if ( !p2m_is_ram(p2mt) && !p2m_is_grant(p2mt) )
         return hvmemul_do_mmio(
             sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ, df, NULL);
 
-    (void)gfn_to_mfn_current(dgpa >> PAGE_SHIFT, &p2mt);
+    (void)gfn_to_mfn(p2m, dgpa >> PAGE_SHIFT, &p2mt);
     if ( !p2m_is_ram(p2mt) && !p2m_is_grant(p2mt) )
         return hvmemul_do_mmio(
             dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE, df, NULL);
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Mon Aug 09 16:46:42 2010 +0100
@@ -335,16 +335,17 @@ static int hvm_set_ioreq_page(
     struct domain *d, struct hvm_ioreq_page *iorp, unsigned long gmfn)
 {
     struct page_info *page;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     p2m_type_t p2mt;
     unsigned long mfn;
     void *va;
 
-    mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn, &p2mt, 0));
+    mfn = mfn_x(gfn_to_mfn_unshare(p2m, gmfn, &p2mt, 0));
     if ( !p2m_is_ram(p2mt) )
         return -EINVAL;
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(d, gmfn);
+        p2m_mem_paging_populate(p2m, gmfn);
         return -ENOENT;
     }
     if ( p2m_is_shared(p2mt) )
@@ -968,8 +969,10 @@ bool_t hvm_hap_nested_page_fault(unsigne
 {
     p2m_type_t p2mt;
     mfn_t mfn;
-
-    mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
+    struct vcpu *v = current;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
+
+    mfn = gfn_to_mfn_guest(p2m, gfn, &p2mt);
 
     /*
      * If this GFN is emulated MMIO or marked as read-only, pass the fault
@@ -985,12 +988,12 @@ bool_t hvm_hap_nested_page_fault(unsigne
 #ifdef __x86_64__
     /* Check if the page has been paged out */
     if ( p2m_is_paged(p2mt) || (p2mt == p2m_ram_paging_out) )
-        p2m_mem_paging_populate(current->domain, gfn);
+        p2m_mem_paging_populate(p2m, gfn);
 
     /* Mem sharing: unshare the page and try again */
     if ( p2mt == p2m_ram_shared )
     {
-        mem_sharing_unshare_page(current->domain, gfn, 0);
+        mem_sharing_unshare_page(p2m, gfn, 0);
         return 1;
     }
 #endif
@@ -1003,8 +1006,8 @@ bool_t hvm_hap_nested_page_fault(unsigne
          * a large page, we do not change other pages type within that large
          * page.
          */
-        paging_mark_dirty(current->domain, mfn_x(mfn));
-        p2m_change_type(current->domain, gfn, p2m_ram_logdirty, p2m_ram_rw);
+        paging_mark_dirty(v->domain, mfn_x(mfn));
+        p2m_change_type(p2m, gfn, p2m_ram_logdirty, p2m_ram_rw);
         return 1;
     }
 
@@ -1088,6 +1091,7 @@ int hvm_set_cr0(unsigned long value)
 {
     struct vcpu *v = current;
     p2m_type_t p2mt;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
     unsigned long gfn, mfn, old_value = v->arch.hvm_vcpu.guest_cr[0];
 
     HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value);
@@ -1126,7 +1130,7 @@ int hvm_set_cr0(unsigned long value)
         {
             /* The guest CR3 must be pointing to the guest physical. */
             gfn = v->arch.hvm_vcpu.guest_cr[3]>>PAGE_SHIFT;
-            mfn = mfn_x(gfn_to_mfn_current(gfn, &p2mt));
+            mfn = mfn_x(gfn_to_mfn(p2m, gfn, &p2mt));
             if ( !p2m_is_ram(p2mt) || !mfn_valid(mfn) ||
                  !get_page(mfn_to_page(mfn), v->domain))
             {
@@ -1213,7 +1217,8 @@ int hvm_set_cr3(unsigned long value)
     {
         /* Shadow-mode CR3 change. Check PDBR and update refcounts. */
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
-        mfn = mfn_x(gfn_to_mfn_current(value >> PAGE_SHIFT, &p2mt));
+        mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(v->domain),
+            value >> PAGE_SHIFT, &p2mt));
         if ( !p2m_is_ram(p2mt) || !mfn_valid(mfn) ||
              !get_page(mfn_to_page(mfn), v->domain) )
               goto bad_cr3;
@@ -1356,6 +1361,8 @@ static void *hvm_map_entry(unsigned long
     unsigned long gfn, mfn;
     p2m_type_t p2mt;
     uint32_t pfec;
+    struct vcpu *v = current;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
 
     if ( ((va & ~PAGE_MASK) + 8) > PAGE_SIZE )
     {
@@ -1372,10 +1379,10 @@ static void *hvm_map_entry(unsigned long
     gfn = paging_gva_to_gfn(current, va, &pfec);
     if ( pfec == PFEC_page_paged || pfec == PFEC_page_shared )
         return NULL;
-    mfn = mfn_x(gfn_to_mfn_unshare(current->domain, gfn, &p2mt, 0));
+    mfn = mfn_x(gfn_to_mfn_unshare(p2m, gfn, &p2mt, 0));
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(current->domain, gfn);
+        p2m_mem_paging_populate(p2m, gfn);
         return NULL;
     }
     if ( p2m_is_shared(p2mt) )
@@ -1742,6 +1749,7 @@ static enum hvm_copy_result __hvm_copy(
     void *buf, paddr_t addr, int size, unsigned int flags, uint32_t pfec)
 {
     struct vcpu *curr = current;
+    struct p2m_domain *p2m = p2m_get_hostp2m(curr->domain);
     unsigned long gfn, mfn;
     p2m_type_t p2mt;
     char *p;
@@ -1770,11 +1778,11 @@ static enum hvm_copy_result __hvm_copy(
             gfn = addr >> PAGE_SHIFT;
         }
 
-        mfn = mfn_x(gfn_to_mfn_unshare(current->domain, gfn, &p2mt, 0));
+        mfn = mfn_x(gfn_to_mfn_unshare(p2m, gfn, &p2mt, 0));
 
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(curr->domain, gfn);
+            p2m_mem_paging_populate(p2m, gfn);
             return HVMCOPY_gfn_paged_out;
         }
         if ( p2m_is_shared(p2mt) )
@@ -3031,6 +3039,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
     {
         struct xen_hvm_modified_memory a;
         struct domain *d;
+        struct p2m_domain *p2m;
         unsigned long pfn;
 
         if ( copy_from_guest(&a, arg, 1) )
@@ -3058,13 +3067,14 @@ long do_hvm_op(unsigned long op, XEN_GUE
         if ( !paging_mode_log_dirty(d) )
             goto param_fail3;
 
+        p2m = p2m_get_hostp2m(d);
         for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
         {
             p2m_type_t t;
-            mfn_t mfn = gfn_to_mfn(d, pfn, &t);
+            mfn_t mfn = gfn_to_mfn(p2m, pfn, &t);
             if ( p2m_is_paging(t) )
             {
-                p2m_mem_paging_populate(d, pfn);
+                p2m_mem_paging_populate(p2m, pfn);
 
                 rc = -EINVAL;
                 goto param_fail3;
@@ -3091,6 +3101,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
     {
         struct xen_hvm_set_mem_type a;
         struct domain *d;
+        struct p2m_domain *p2m;
         unsigned long pfn;
         
         /* Interface types to internal p2m types */
@@ -3120,15 +3131,16 @@ long do_hvm_op(unsigned long op, XEN_GUE
         if ( a.hvmmem_type >= ARRAY_SIZE(memtype) )
             goto param_fail4;
 
+        p2m = p2m_get_hostp2m(d);
         for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
         {
             p2m_type_t t;
             p2m_type_t nt;
             mfn_t mfn;
-            mfn = gfn_to_mfn_unshare(d, pfn, &t, 0);
+            mfn = gfn_to_mfn_unshare(p2m, pfn, &t, 0);
             if ( p2m_is_paging(t) )
             {
-                p2m_mem_paging_populate(d, pfn);
+                p2m_mem_paging_populate(p2m, pfn);
 
                 rc = -EINVAL;
                 goto param_fail4;
@@ -3147,7 +3159,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
             }
             else
             {
-                nt = p2m_change_type(d, pfn, t, memtype[a.hvmmem_type]);
+                nt = p2m_change_type(p2m, pfn, t, memtype[a.hvmmem_type]);
                 if ( nt != t )
                 {
                     gdprintk(XENLOG_WARNING,
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/mtrr.c
--- a/xen/arch/x86/hvm/mtrr.c   Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/mtrr.c   Mon Aug 09 16:46:42 2010 +0100
@@ -399,7 +399,7 @@ uint32_t get_pat_flags(struct vcpu *v,
     {
         struct domain *d = v->domain;
         p2m_type_t p2mt;
-        gfn_to_mfn(d, paddr_to_pfn(gpaddr), &p2mt);
+        gfn_to_mfn(p2m_get_hostp2m(d), paddr_to_pfn(gpaddr), &p2mt);
         if (p2m_is_ram(p2mt))
             gdprintk(XENLOG_WARNING,
                     "Conflict occurs for a given guest l1e flags:%x "
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/stdvga.c
--- a/xen/arch/x86/hvm/stdvga.c Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/stdvga.c Mon Aug 09 16:46:42 2010 +0100
@@ -469,6 +469,7 @@ static int mmio_move(struct hvm_hw_stdvg
     int i;
     int sign = p->df ? -1 : 1;
     p2m_type_t p2mt;
+    struct p2m_domain *p2m = p2m_get_hostp2m(current->domain);
 
     if ( p->data_is_ptr )
     {
@@ -481,7 +482,7 @@ static int mmio_move(struct hvm_hw_stdvg
                 if ( hvm_copy_to_guest_phys(data, &tmp, p->size) !=
                      HVMCOPY_okay )
                 {
-                    (void)gfn_to_mfn_current(data >> PAGE_SHIFT, &p2mt);
+                    (void)gfn_to_mfn(p2m, data >> PAGE_SHIFT, &p2mt);
                     /*
                      * The only case we handle is vga_mem <-> vga_mem.
                      * Anything else disables caching and leaves it to qemu-dm.
@@ -503,7 +504,7 @@ static int mmio_move(struct hvm_hw_stdvg
                 if ( hvm_copy_from_guest_phys(&tmp, data, p->size) !=
                      HVMCOPY_okay )
                 {
-                    (void)gfn_to_mfn_current(data >> PAGE_SHIFT, &p2mt);
+                    (void)gfn_to_mfn(p2m, data >> PAGE_SHIFT, &p2mt);
                     if ( (p2mt != p2m_mmio_dm) || (data < VGA_MEM_BASE) ||
                          ((data + p->size) > (VGA_MEM_BASE + VGA_MEM_SIZE)) )
                         return 0;
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Aug 09 16:46:42 2010 +0100
@@ -232,7 +232,7 @@ static int svm_vmcb_restore(struct vcpu 
     {
         if ( c->cr0 & X86_CR0_PG )
         {
-            mfn = mfn_x(gfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT, &p2mt));
+            mfn = mfn_x(gfn_to_mfn(p2m, c->cr3 >> PAGE_SHIFT, &p2mt));
             if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
             {
                 gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n",
@@ -946,6 +946,9 @@ static void svm_do_nested_pgfault(paddr_
     unsigned long gfn = gpa >> PAGE_SHIFT;
     mfn_t mfn;
     p2m_type_t p2mt;
+    struct p2m_domain *p2m;
+
+    p2m = p2m_get_hostp2m(current->domain);
 
     if ( tb_init_done )
     {
@@ -958,7 +961,7 @@ static void svm_do_nested_pgfault(paddr_
 
         _d.gpa = gpa;
         _d.qualification = 0;
-        _d.mfn = mfn_x(gfn_to_mfn_query(current->domain, gfn, &_d.p2mt));
+        _d.mfn = mfn_x(gfn_to_mfn_query(p2m, gfn, &_d.p2mt));
         
         __trace_var(TRC_HVM_NPF, 0, sizeof(_d), (unsigned char *)&_d);
     }
@@ -967,7 +970,7 @@ static void svm_do_nested_pgfault(paddr_
         return;
 
     /* Everything else is an error. */
-    mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
+    mfn = gfn_to_mfn_guest(p2m, gfn, &p2mt);
     gdprintk(XENLOG_ERR, "SVM violation gpa %#"PRIpaddr", mfn %#lx, type %i\n",
              gpa, mfn_x(mfn), p2mt);
     domain_crash(current->domain);
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Aug 09 16:46:42 2010 +0100
@@ -486,7 +486,8 @@ static int vmx_restore_cr0_cr3(
     {
         if ( cr0 & X86_CR0_PG )
         {
-            mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+            mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(v->domain),
+                cr3 >> PAGE_SHIFT, &p2mt));
             if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
             {
                 gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3);
@@ -1002,7 +1003,8 @@ static void vmx_load_pdptrs(struct vcpu 
     if ( cr3 & 0x1fUL )
         goto crash;
 
-    mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+    mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(v->domain),
+        cr3 >> PAGE_SHIFT, &p2mt));
     if ( !p2m_is_ram(p2mt) )
         goto crash;
 
@@ -1221,7 +1223,7 @@ void ept_sync_domain(struct domain *d)
         return;
 
     ASSERT(local_irq_is_enabled());
-    ASSERT(p2m_locked_by_me(d->arch.p2m));
+    ASSERT(p2m_locked_by_me(p2m_get_hostp2m(d)));
 
     /*
      * Flush active cpus synchronously. Flush others the next time this domain
@@ -1340,7 +1342,7 @@ static void vmx_set_uc_mode(struct vcpu 
 {
     if ( paging_mode_hap(v->domain) )
         ept_change_entry_emt_with_range(
-            v->domain, 0, v->domain->arch.p2m->max_mapped_pfn);
+            v->domain, 0, p2m_get_hostp2m(v->domain)->max_mapped_pfn);
     hvm_asid_flush_vcpu(v);
 }
 
@@ -1893,7 +1895,8 @@ static int vmx_alloc_vlapic_mapping(stru
         return -ENOMEM;
     share_xen_page_with_guest(virt_to_page(apic_va), d, XENSHARE_writable);
     set_mmio_p2m_entry(
-        d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), _mfn(virt_to_mfn(apic_va)));
+        p2m_get_hostp2m(d), paddr_to_pfn(APIC_DEFAULT_PHYS_BASE),
+        _mfn(virt_to_mfn(apic_va)));
     d->arch.hvm_domain.vmx.apic_access_mfn = virt_to_mfn(apic_va);
 
     return 0;
@@ -2098,6 +2101,7 @@ static void ept_handle_violation(unsigne
     unsigned long gla, gfn = gpa >> PAGE_SHIFT;
     mfn_t mfn;
     p2m_type_t p2mt;
+    struct p2m_domain *p2m = p2m_get_hostp2m(current->domain);
 
     if ( tb_init_done )
     {
@@ -2110,7 +2114,7 @@ static void ept_handle_violation(unsigne
 
         _d.gpa = gpa;
         _d.qualification = qualification;
-        _d.mfn = mfn_x(gfn_to_mfn_query(current->domain, gfn, &_d.p2mt));
+        _d.mfn = mfn_x(gfn_to_mfn_query(p2m, gfn, &_d.p2mt));
         
         __trace_var(TRC_HVM_NPF, 0, sizeof(_d), (unsigned char *)&_d);
     }
@@ -2120,7 +2124,7 @@ static void ept_handle_violation(unsigne
         return;
 
     /* Everything else is an error. */
-    mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest);
+    mfn = gfn_to_mfn_guest(p2m, gfn, &p2mt);
     gdprintk(XENLOG_ERR, "EPT violation %#lx (%c%c%c/%c%c%c), "
              "gpa %#"PRIpaddr", mfn %#lx, type %i.\n", 
              qualification, 
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm.c Mon Aug 09 16:46:42 2010 +0100
@@ -398,7 +398,7 @@ unsigned long domain_get_maximum_gpfn(st
 unsigned long domain_get_maximum_gpfn(struct domain *d)
 {
     if ( is_hvm_domain(d) )
-        return d->arch.p2m->max_mapped_pfn;
+        return p2m_get_hostp2m(d)->max_mapped_pfn;
     /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */
     return arch_get_max_pfn(d) - 1;
 }
@@ -1741,7 +1741,8 @@ static int mod_l1_entry(l1_pgentry_t *pl
     if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
     {
         /* Translate foreign guest addresses. */
-        mfn = mfn_x(gfn_to_mfn(pg_dom, l1e_get_pfn(nl1e), &p2mt));
+        mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(pg_dom),
+            l1e_get_pfn(nl1e), &p2mt));
         if ( !p2m_is_ram(p2mt) || unlikely(mfn == INVALID_MFN) )
             return 0;
         ASSERT((mfn & ~(PADDR_MASK >> PAGE_SHIFT)) == 0);
@@ -3318,8 +3319,8 @@ int do_mmu_update(
     struct page_info *page;
     int rc = 0, okay = 1, i = 0;
     unsigned int cmd, done = 0, pt_dom;
-    struct domain *d = current->domain, *pt_owner = d, *pg_owner;
     struct vcpu *v = current;
+    struct domain *d = v->domain, *pt_owner = d, *pg_owner;
     struct domain_mmap_cache mapcache;
 
     if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
@@ -3403,13 +3404,13 @@ int do_mmu_update(
 
             req.ptr -= cmd;
             gmfn = req.ptr >> PAGE_SHIFT;
-            mfn = mfn_x(gfn_to_mfn(pt_owner, gmfn, &p2mt));
+            mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(pt_owner), gmfn, &p2mt));
             if ( !p2m_is_valid(p2mt) )
               mfn = INVALID_MFN;
 
             if ( p2m_is_paged(p2mt) )
             {
-                p2m_mem_paging_populate(pg_owner, gmfn);
+                p2m_mem_paging_populate(p2m_get_hostp2m(pg_owner), gmfn);
 
                 rc = -ENOENT;
                 break;
@@ -3434,12 +3435,13 @@ int do_mmu_update(
                 {
                     l1_pgentry_t l1e = l1e_from_intpte(req.val);
                     p2m_type_t l1e_p2mt;
-                    gfn_to_mfn(pg_owner, l1e_get_pfn(l1e), &l1e_p2mt);
+                    gfn_to_mfn(p2m_get_hostp2m(pg_owner),
+                        l1e_get_pfn(l1e), &l1e_p2mt);
 
                     if ( p2m_is_paged(l1e_p2mt) )
                     {
-                        p2m_mem_paging_populate(pg_owner, l1e_get_pfn(l1e));
-
+                        p2m_mem_paging_populate(p2m_get_hostp2m(pg_owner),
+                            l1e_get_pfn(l1e));
                         rc = -ENOENT;
                         break;
                     }
@@ -3457,7 +3459,7 @@ int do_mmu_update(
                         /* Unshare the page for RW foreign mappings */
                         if ( l1e_get_flags(l1e) & _PAGE_RW )
                         {
-                            rc = mem_sharing_unshare_page(pg_owner, 
+                            rc = 
mem_sharing_unshare_page(p2m_get_hostp2m(pg_owner), 
                                                           l1e_get_pfn(l1e), 
                                                           0);
                             if ( rc )
@@ -3475,12 +3477,12 @@ int do_mmu_update(
                 {
                     l2_pgentry_t l2e = l2e_from_intpte(req.val);
                     p2m_type_t l2e_p2mt;
-                    gfn_to_mfn(pg_owner, l2e_get_pfn(l2e), &l2e_p2mt);
+                    gfn_to_mfn(p2m_get_hostp2m(pg_owner), l2e_get_pfn(l2e), 
&l2e_p2mt);
 
                     if ( p2m_is_paged(l2e_p2mt) )
                     {
-                        p2m_mem_paging_populate(pg_owner, l2e_get_pfn(l2e));
-
+                        p2m_mem_paging_populate(p2m_get_hostp2m(pg_owner),
+                            l2e_get_pfn(l2e));
                         rc = -ENOENT;
                         break;
                     }
@@ -3505,12 +3507,12 @@ int do_mmu_update(
                 {
                     l3_pgentry_t l3e = l3e_from_intpte(req.val);
                     p2m_type_t l3e_p2mt;
-                    gfn_to_mfn(pg_owner, l3e_get_pfn(l3e), &l3e_p2mt);
+                    gfn_to_mfn(p2m_get_hostp2m(pg_owner), l3e_get_pfn(l3e), 
&l3e_p2mt);
 
                     if ( p2m_is_paged(l3e_p2mt) )
                     {
-                        p2m_mem_paging_populate(pg_owner, l3e_get_pfn(l3e));
-
+                        p2m_mem_paging_populate(p2m_get_hostp2m(pg_owner),
+                            l3e_get_pfn(l3e));
                         rc = -ENOENT;
                         break;
                     }
@@ -3536,12 +3538,13 @@ int do_mmu_update(
                 {
                     l4_pgentry_t l4e = l4e_from_intpte(req.val);
                     p2m_type_t l4e_p2mt;
-                    gfn_to_mfn(pg_owner, l4e_get_pfn(l4e), &l4e_p2mt);
+                    gfn_to_mfn(p2m_get_hostp2m(pg_owner),
+                        l4e_get_pfn(l4e), &l4e_p2mt);
 
                     if ( p2m_is_paged(l4e_p2mt) )
                     {
-                        p2m_mem_paging_populate(pg_owner, l4e_get_pfn(l4e));
-
+                        p2m_mem_paging_populate(p2m_get_hostp2m(pg_owner),
+                            l4e_get_pfn(l4e));
                         rc = -ENOENT;
                         break;
                     }
@@ -3923,8 +3926,8 @@ static int create_grant_p2m_mapping(uint
         p2mt = p2m_grant_map_ro;
     else
         p2mt = p2m_grant_map_rw;
-    rc = guest_physmap_add_entry(current->domain, addr >> PAGE_SHIFT,
-                                 frame, 0, p2mt);
+    rc = guest_physmap_add_entry(p2m_get_hostp2m(current->domain),
+                                 addr >> PAGE_SHIFT, frame, 0, p2mt);
     if ( rc )
         return GNTST_general_error;
     else
@@ -3962,11 +3965,12 @@ static int replace_grant_p2m_mapping(
     unsigned long gfn = (unsigned long)(addr >> PAGE_SHIFT);
     p2m_type_t type;
     mfn_t old_mfn;
+    struct domain *d = current->domain;
 
     if ( new_addr != 0 || (flags & GNTMAP_contains_pte) )
         return GNTST_general_error;
 
-    old_mfn = gfn_to_mfn_current(gfn, &type);
+    old_mfn = gfn_to_mfn(p2m_get_hostp2m(d), gfn, &type);
     if ( !p2m_is_grant(type) || mfn_x(old_mfn) != frame )
     {
         gdprintk(XENLOG_WARNING,
@@ -3974,7 +3978,7 @@ static int replace_grant_p2m_mapping(
                  type, mfn_x(old_mfn), frame);
         return GNTST_general_error;
     }
-    guest_physmap_remove_page(current->domain, gfn, frame, 0);
+    guest_physmap_remove_page(d, gfn, frame, 0);
 
     return GNTST_okay;
 }
@@ -4581,7 +4585,8 @@ long arch_memory_op(int op, XEN_GUEST_HA
         {
             p2m_type_t p2mt;
 
-            xatp.idx = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
+            xatp.idx = mfn_x(gfn_to_mfn_unshare(p2m_get_hostp2m(d),
+                                                xatp.idx, &p2mt, 0));
             /* If the page is still shared, exit early */
             if ( p2m_is_shared(p2mt) )
             {
@@ -4771,6 +4776,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
     {
         xen_pod_target_t target;
         struct domain *d;
+        struct p2m_domain *p2m;
 
         /* Support DOMID_SELF? */
         if ( !IS_PRIV(current->domain) )
@@ -4794,9 +4800,10 @@ long arch_memory_op(int op, XEN_GUEST_HA
             rc = p2m_pod_set_mem_target(d, target.target_pages);
         }
 
+        p2m = p2m_get_hostp2m(d);
         target.tot_pages       = d->tot_pages;
-        target.pod_cache_pages = d->arch.p2m->pod.count;
-        target.pod_entries     = d->arch.p2m->pod.entry_count;
+        target.pod_cache_pages = p2m->pod.count;
+        target.pod_entries     = p2m->pod.entry_count;
 
         if ( copy_to_guest(arg, &target, 1) )
         {
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/guest_walk.c
--- a/xen/arch/x86/mm/guest_walk.c      Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/guest_walk.c      Mon Aug 09 16:46:42 2010 +0100
@@ -86,17 +86,17 @@ static uint32_t set_ad_bits(void *guest_
     return 0;
 }
 
-static inline void *map_domain_gfn(struct domain *d,
+static inline void *map_domain_gfn(struct p2m_domain *p2m,
                                    gfn_t gfn, 
                                    mfn_t *mfn,
                                    p2m_type_t *p2mt,
                                    uint32_t *rc) 
 {
     /* Translate the gfn, unsharing if shared */
-    *mfn = gfn_to_mfn_unshare(d, gfn_x(gfn), p2mt, 0);
+    *mfn = gfn_to_mfn_unshare(p2m, gfn_x(gfn), p2mt, 0);
     if ( p2m_is_paging(*p2mt) )
     {
-        p2m_mem_paging_populate(d, gfn_x(gfn));
+        p2m_mem_paging_populate(p2m, gfn_x(gfn));
 
         *rc = _PAGE_PAGED;
         return NULL;
@@ -119,7 +119,8 @@ static inline void *map_domain_gfn(struc
 
 /* Walk the guest pagetables, after the manner of a hardware walker. */
 uint32_t
-guest_walk_tables(struct vcpu *v, unsigned long va, walk_t *gw, 
+guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
+                  unsigned long va, walk_t *gw, 
                   uint32_t pfec, mfn_t top_mfn, void *top_map)
 {
     struct domain *d = v->domain;
@@ -154,7 +155,7 @@ guest_walk_tables(struct vcpu *v, unsign
     if ( rc & _PAGE_PRESENT ) goto out;
 
     /* Map the l3 table */
-    l3p = map_domain_gfn(d, 
+    l3p = map_domain_gfn(p2m, 
                          guest_l4e_get_gfn(gw->l4e), 
                          &gw->l3mfn,
                          &p2mt, 
@@ -181,7 +182,7 @@ guest_walk_tables(struct vcpu *v, unsign
 #endif /* PAE or 64... */
 
     /* Map the l2 table */
-    l2p = map_domain_gfn(d, 
+    l2p = map_domain_gfn(p2m, 
                          guest_l3e_get_gfn(gw->l3e), 
                          &gw->l2mfn,
                          &p2mt, 
@@ -237,7 +238,7 @@ guest_walk_tables(struct vcpu *v, unsign
     else 
     {
         /* Not a superpage: carry on and find the l1e. */
-        l1p = map_domain_gfn(d, 
+        l1p = map_domain_gfn(p2m, 
                              guest_l2e_get_gfn(gw->l2e), 
                              &gw->l1mfn,
                              &p2mt,
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/hap/guest_walk.c
--- a/xen/arch/x86/mm/hap/guest_walk.c  Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/hap/guest_walk.c  Mon Aug 09 16:46:42 2010 +0100
@@ -43,13 +43,14 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
     void *top_map;
     p2m_type_t p2mt;
     walk_t gw;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
 
     /* Get the top-level table's MFN */
     cr3 = v->arch.hvm_vcpu.guest_cr[3];
-    top_mfn = gfn_to_mfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt, 0);
+    top_mfn = gfn_to_mfn_unshare(p2m, cr3 >> PAGE_SHIFT, &p2mt, 0);
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
+        p2m_mem_paging_populate(p2m, cr3 >> PAGE_SHIFT);
 
         pfec[0] = PFEC_page_paged;
         return INVALID_GFN;
@@ -71,17 +72,17 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
 #if GUEST_PAGING_LEVELS == 3
     top_map += (cr3 & ~(PAGE_MASK | 31));
 #endif
-    missing = guest_walk_tables(v, gva, &gw, pfec[0], top_mfn, top_map);
+    missing = guest_walk_tables(v, p2m, gva, &gw, pfec[0], top_mfn, top_map);
     unmap_domain_page(top_map);
 
     /* Interpret the answer */
     if ( missing == 0 )
     {
         gfn_t gfn = guest_l1e_get_gfn(gw.l1e);
-        gfn_to_mfn_unshare(v->domain, gfn_x(gfn), &p2mt, 0);
+        gfn_to_mfn_unshare(p2m, gfn_x(gfn), &p2mt, 0);
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(v->domain, gfn_x(gfn));
+            p2m_mem_paging_populate(p2m, gfn_x(gfn));
 
             pfec[0] = PFEC_page_paged;
             return INVALID_GFN;
@@ -130,4 +131,3 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
  * indent-tabs-mode: nil
  * End:
  */
-
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/hap/hap.c Mon Aug 09 16:46:42 2010 +0100
@@ -70,7 +70,7 @@ static int hap_enable_vram_tracking(stru
 
     /* set l1e entries of P2M table to be read-only. */
     for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++)
-        p2m_change_type(d, i, p2m_ram_rw, p2m_ram_logdirty);
+        p2m_change_type(p2m_get_hostp2m(d), i, p2m_ram_rw, p2m_ram_logdirty);
 
     flush_tlb_mask(&d->domain_dirty_cpumask);
     return 0;
@@ -90,7 +90,7 @@ static int hap_disable_vram_tracking(str
 
     /* set l1e entries of P2M table with normal mode */
     for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++)
-        p2m_change_type(d, i, p2m_ram_logdirty, p2m_ram_rw);
+        p2m_change_type(p2m_get_hostp2m(d), i, p2m_ram_logdirty, p2m_ram_rw);
 
     flush_tlb_mask(&d->domain_dirty_cpumask);
     return 0;
@@ -106,7 +106,7 @@ static void hap_clean_vram_tracking(stru
 
     /* set l1e entries of P2M table to be read-only. */
     for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++)
-        p2m_change_type(d, i, p2m_ram_rw, p2m_ram_logdirty);
+        p2m_change_type(p2m_get_hostp2m(d), i, p2m_ram_rw, p2m_ram_logdirty);
 
     flush_tlb_mask(&d->domain_dirty_cpumask);
 }
@@ -200,7 +200,8 @@ static int hap_enable_log_dirty(struct d
     hap_unlock(d);
 
     /* set l1e entries of P2M table to be read-only. */
-    p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty);
+    p2m_change_entry_type_global(p2m_get_hostp2m(d),
+        p2m_ram_rw, p2m_ram_logdirty);
     flush_tlb_mask(&d->domain_dirty_cpumask);
     return 0;
 }
@@ -212,14 +213,16 @@ static int hap_disable_log_dirty(struct 
     hap_unlock(d);
 
     /* set l1e entries of P2M table with normal mode */
-    p2m_change_entry_type_global(d, p2m_ram_logdirty, p2m_ram_rw);
+    p2m_change_entry_type_global(p2m_get_hostp2m(d),
+        p2m_ram_logdirty, p2m_ram_rw);
     return 0;
 }
 
 static void hap_clean_dirty_bitmap(struct domain *d)
 {
     /* set l1e entries of P2M table to be read-only. */
-    p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty);
+    p2m_change_entry_type_global(p2m_get_hostp2m(d),
+        p2m_ram_rw, p2m_ram_logdirty);
     flush_tlb_mask(&d->domain_dirty_cpumask);
 }
 
@@ -273,8 +276,9 @@ static void hap_free(struct domain *d, m
     page_list_add_tail(pg, &d->arch.paging.hap.freelist);
 }
 
-static struct page_info *hap_alloc_p2m_page(struct domain *d)
-{
+static struct page_info *hap_alloc_p2m_page(struct p2m_domain *p2m)
+{
+    struct domain *d = p2m->domain;
     struct page_info *pg;
 
     hap_lock(d);
@@ -312,8 +316,9 @@ static struct page_info *hap_alloc_p2m_p
     return pg;
 }
 
-static void hap_free_p2m_page(struct domain *d, struct page_info *pg)
-{
+static void hap_free_p2m_page(struct p2m_domain *p2m, struct page_info *pg)
+{
+    struct domain *d = p2m->domain;
     hap_lock(d);
     ASSERT(page_get_owner(pg) == d);
     /* Should have just the one ref we gave it in alloc_p2m_page() */
@@ -594,7 +599,8 @@ int hap_enable(struct domain *d, u32 mod
     /* allocate P2m table */
     if ( mode & PG_translate )
     {
-        rv = p2m_alloc_table(d, hap_alloc_p2m_page, hap_free_p2m_page);
+        rv = p2m_alloc_table(p2m_get_hostp2m(d),
+            hap_alloc_p2m_page, hap_free_p2m_page);
         if ( rv != 0 )
             goto out;
     }
@@ -611,7 +617,7 @@ void hap_final_teardown(struct domain *d
     if ( d->arch.paging.hap.total_pages != 0 )
         hap_teardown(d);
 
-    p2m_teardown(d);
+    p2m_teardown(p2m_get_hostp2m(d));
     ASSERT(d->arch.paging.hap.p2m_pages == 0);
 }
 
@@ -711,9 +717,11 @@ static int hap_page_fault(struct vcpu *v
 static int hap_page_fault(struct vcpu *v, unsigned long va,
                           struct cpu_user_regs *regs)
 {
+    struct domain *d = v->domain;
+
     HAP_ERROR("Intercepted a guest #PF (%u:%u) with HAP enabled.\n",
-              v->domain->domain_id, v->vcpu_id);
-    domain_crash(v->domain);
+              d->domain_id, v->vcpu_id);
+    domain_crash(d);
     return 0;
 }
 
@@ -882,5 +890,3 @@ static const struct paging_mode hap_pagi
  * indent-tabs-mode: nil
  * End:
  */
-
-
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/hap/p2m-ept.c     Mon Aug 09 16:46:42 2010 +0100
@@ -36,23 +36,23 @@
 #define is_epte_superpage(ept_entry)    ((ept_entry)->sp)
 
 /* Non-ept "lock-and-check" wrapper */
-static int ept_pod_check_and_populate(struct domain *d, unsigned long gfn,
+static int ept_pod_check_and_populate(struct p2m_domain *p2m, unsigned long 
gfn,
                                       ept_entry_t *entry, int order,
                                       p2m_query_t q)
 {
     int r;
-    p2m_lock(d->arch.p2m);
+    p2m_lock(p2m);
 
     /* Check to make sure this is still PoD */
     if ( entry->avail1 != p2m_populate_on_demand )
     {
-        p2m_unlock(d->arch.p2m);
+        p2m_unlock(p2m);
         return 0;
     }
 
-    r = p2m_pod_demand_populate(d, gfn, order, q);
-
-    p2m_unlock(d->arch.p2m);
+    r = p2m_pod_demand_populate(p2m, gfn, order, q);
+
+    p2m_unlock(p2m);
 
     return r;
 }
@@ -98,11 +98,11 @@ static void ept_p2m_type_to_flags(ept_en
 #define GUEST_TABLE_POD_PAGE    3
 
 /* Fill in middle levels of ept table */
-static int ept_set_middle_entry(struct domain *d, ept_entry_t *ept_entry)
+static int ept_set_middle_entry(struct p2m_domain *p2m, ept_entry_t *ept_entry)
 {
     struct page_info *pg;
 
-    pg = p2m_alloc_ptp(d, 0);
+    pg = p2m_alloc_ptp(p2m, 0);
     if ( pg == NULL )
         return 0;
 
@@ -119,7 +119,7 @@ static int ept_set_middle_entry(struct d
 }
 
 /* free ept sub tree behind an entry */
-void ept_free_entry(struct domain *d, ept_entry_t *ept_entry, int level)
+void ept_free_entry(struct p2m_domain *p2m, ept_entry_t *ept_entry, int level)
 {
     /* End if the entry is a leaf entry. */
     if ( level == 0 || !is_epte_present(ept_entry) ||
@@ -130,14 +130,14 @@ void ept_free_entry(struct domain *d, ep
     {
         ept_entry_t *epte = map_domain_page(ept_entry->mfn);
         for ( int i = 0; i < EPT_PAGETABLE_ENTRIES; i++ )
-            ept_free_entry(d, epte + i, level - 1);
+            ept_free_entry(p2m, epte + i, level - 1);
         unmap_domain_page(epte);
     }
 
-    d->arch.p2m->free_page(d, mfn_to_page(ept_entry->mfn));
-}
-
-static int ept_split_super_page(struct domain *d, ept_entry_t *ept_entry,
+    p2m->free_page(p2m, mfn_to_page(ept_entry->mfn));
+}
+
+static int ept_split_super_page(struct p2m_domain *p2m, ept_entry_t *ept_entry,
                                 int level, int target)
 {
     ept_entry_t new_ept, *table;
@@ -150,7 +150,7 @@ static int ept_split_super_page(struct d
 
     ASSERT(is_epte_superpage(ept_entry));
 
-    if ( !ept_set_middle_entry(d, &new_ept) )
+    if ( !ept_set_middle_entry(p2m, &new_ept) )
         return 0;
 
     table = map_domain_page(new_ept.mfn);
@@ -174,7 +174,7 @@ static int ept_split_super_page(struct d
 
         ASSERT(is_epte_superpage(epte));
 
-        if ( !(rv = ept_split_super_page(d, epte, level - 1, target)) )
+        if ( !(rv = ept_split_super_page(p2m, epte, level - 1, target)) )
             break;
     }
 
@@ -200,7 +200,7 @@ static int ept_split_super_page(struct d
  *  GUEST_TABLE_POD:
  *   The next entry is marked populate-on-demand.
  */
-static int ept_next_level(struct domain *d, bool_t read_only,
+static int ept_next_level(struct p2m_domain *p2m, bool_t read_only,
                           ept_entry_t **table, unsigned long *gfn_remainder,
                           int next_level)
 {
@@ -225,7 +225,7 @@ static int ept_next_level(struct domain 
         if ( read_only )
             return GUEST_TABLE_MAP_FAILED;
 
-        if ( !ept_set_middle_entry(d, ept_entry) )
+        if ( !ept_set_middle_entry(p2m, ept_entry) )
             return GUEST_TABLE_MAP_FAILED;
     }
 
@@ -245,7 +245,7 @@ static int ept_next_level(struct domain 
  * by observing whether any gfn->mfn translations are modified.
  */
 static int
-ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
+ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
               unsigned int order, p2m_type_t p2mt)
 {
     ept_entry_t *table, *ept_entry;
@@ -259,6 +259,7 @@ ept_set_entry(struct domain *d, unsigned
     uint8_t ipat = 0;
     int need_modify_vtd_table = 1;
     int needs_sync = 1;
+    struct domain *d = p2m->domain;
 
     /*
      * the caller must make sure:
@@ -281,7 +282,7 @@ ept_set_entry(struct domain *d, unsigned
 
     for ( i = ept_get_wl(d); i > target; i-- )
     {
-        ret = ept_next_level(d, 0, &table, &gfn_remainder, i);
+        ret = ept_next_level(p2m, 0, &table, &gfn_remainder, i);
         if ( !ret )
             goto out;
         else if ( ret != GUEST_TABLE_NORMAL_PAGE )
@@ -311,7 +312,7 @@ ept_set_entry(struct domain *d, unsigned
         if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) ||
              (p2mt == p2m_ram_paging_in_start) )
         {
-            ept_entry->emt = epte_get_entry_emt(d, gfn, mfn, &ipat,
+            ept_entry->emt = epte_get_entry_emt(p2m->domain, gfn, mfn, &ipat,
                                                 direct_mmio);
             ept_entry->ipat = ipat;
             ept_entry->sp = order ? 1 : 0;
@@ -337,9 +338,9 @@ ept_set_entry(struct domain *d, unsigned
 
         split_ept_entry = *ept_entry;
 
-        if ( !ept_split_super_page(d, &split_ept_entry, i, target) )
-        {
-            ept_free_entry(d, &split_ept_entry, i);
+        if ( !ept_split_super_page(p2m, &split_ept_entry, i, target) )
+        {
+            ept_free_entry(p2m, &split_ept_entry, i);
             goto out;
         }
 
@@ -349,7 +350,7 @@ ept_set_entry(struct domain *d, unsigned
 
         /* then move to the level we want to make real changes */
         for ( ; i > target; i-- )
-            ept_next_level(d, 0, &table, &gfn_remainder, i);
+            ept_next_level(p2m, 0, &table, &gfn_remainder, i);
 
         ASSERT(i == target);
 
@@ -374,8 +375,8 @@ ept_set_entry(struct domain *d, unsigned
 
     /* Track the highest gfn for which we have ever had a valid mapping */
     if ( mfn_valid(mfn_x(mfn)) &&
-         (gfn + (1UL << order) - 1 > d->arch.p2m->max_mapped_pfn) )
-        d->arch.p2m->max_mapped_pfn = gfn + (1UL << order) - 1;
+         (gfn + (1UL << order) - 1 > p2m->max_mapped_pfn) )
+        p2m->max_mapped_pfn = gfn + (1UL << order) - 1;
 
     /* Success */
     rv = 1;
@@ -384,10 +385,10 @@ out:
     unmap_domain_page(table);
 
     if ( needs_sync )
-        ept_sync_domain(d);
+        ept_sync_domain(p2m->domain);
 
     /* Now the p2m table is not shared with vt-d page table */
-    if ( rv && iommu_enabled && need_iommu(d) && need_modify_vtd_table )
+    if ( rv && iommu_enabled && need_iommu(p2m->domain) && 
need_modify_vtd_table )
     {
         if ( p2mt == p2m_ram_rw )
         {
@@ -395,22 +396,22 @@ out:
             {
                 for ( i = 0; i < (1 << order); i++ )
                     iommu_map_page(
-                        d, gfn - offset + i, mfn_x(mfn) - offset + i,
+                        p2m->domain, gfn - offset + i, mfn_x(mfn) - offset + i,
                         IOMMUF_readable | IOMMUF_writable);
             }
             else if ( !order )
                 iommu_map_page(
-                    d, gfn, mfn_x(mfn), IOMMUF_readable | IOMMUF_writable);
+                    p2m->domain, gfn, mfn_x(mfn), IOMMUF_readable | 
IOMMUF_writable);
         }
         else
         {
             if ( order == EPT_TABLE_ORDER )
             {
                 for ( i = 0; i < (1 << order); i++ )
-                    iommu_unmap_page(d, gfn - offset + i);
+                    iommu_unmap_page(p2m->domain, gfn - offset + i);
             }
             else if ( !order )
-                iommu_unmap_page(d, gfn);
+                iommu_unmap_page(p2m->domain, gfn);
         }
     }
 
@@ -418,9 +419,11 @@ out:
 }
 
 /* Read ept p2m entries */
-static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t,
+static mfn_t ept_get_entry(struct p2m_domain *p2m,
+                           unsigned long gfn, p2m_type_t *t,
                            p2m_query_t q)
 {
+    struct domain *d = p2m->domain;
     ept_entry_t *table = map_domain_page(ept_get_asr(d));
     unsigned long gfn_remainder = gfn;
     ept_entry_t *ept_entry;
@@ -432,7 +435,7 @@ static mfn_t ept_get_entry(struct domain
     *t = p2m_mmio_dm;
 
     /* This pfn is higher than the highest the p2m map currently holds */
-    if ( gfn > d->arch.p2m->max_mapped_pfn )
+    if ( gfn > p2m->max_mapped_pfn )
         goto out;
 
     /* Should check if gfn obeys GAW here. */
@@ -440,7 +443,7 @@ static mfn_t ept_get_entry(struct domain
     for ( i = ept_get_wl(d); i > 0; i-- )
     {
     retry:
-        ret = ept_next_level(d, 1, &table, &gfn_remainder, i);
+        ret = ept_next_level(p2m, 1, &table, &gfn_remainder, i);
         if ( !ret )
             goto out;
         else if ( ret == GUEST_TABLE_POD_PAGE )
@@ -457,7 +460,7 @@ static mfn_t ept_get_entry(struct domain
             index = gfn_remainder >> ( i * EPT_TABLE_ORDER);
             ept_entry = table + index;
 
-            if ( !ept_pod_check_and_populate(d, gfn,
+            if ( !ept_pod_check_and_populate(p2m, gfn,
                                              ept_entry, 9, q) )
                 goto retry;
             else
@@ -480,7 +483,7 @@ static mfn_t ept_get_entry(struct domain
 
         ASSERT(i == 0);
         
-        if ( ept_pod_check_and_populate(d, gfn,
+        if ( ept_pod_check_and_populate(p2m, gfn,
                                         ept_entry, 0, q) )
             goto out;
     }
@@ -511,9 +514,10 @@ out:
 /* WARNING: Only caller doesn't care about PoD pages.  So this function will
  * always return 0 for PoD pages, not populate them.  If that becomes 
necessary,
  * pass a p2m_query_t type along to distinguish. */
-static ept_entry_t ept_get_entry_content(struct domain *d, unsigned long gfn, 
int *level)
-{
-    ept_entry_t *table = map_domain_page(ept_get_asr(d));
+static ept_entry_t ept_get_entry_content(struct p2m_domain *p2m,
+    unsigned long gfn, int *level)
+{
+    ept_entry_t *table = map_domain_page(ept_get_asr(p2m->domain));
     unsigned long gfn_remainder = gfn;
     ept_entry_t *ept_entry;
     ept_entry_t content = { .epte = 0 };
@@ -522,12 +526,12 @@ static ept_entry_t ept_get_entry_content
     int ret=0;
 
     /* This pfn is higher than the highest the p2m map currently holds */
-    if ( gfn > d->arch.p2m->max_mapped_pfn )
+    if ( gfn > p2m->max_mapped_pfn )
         goto out;
 
-    for ( i = ept_get_wl(d); i > 0; i-- )
-    {
-        ret = ept_next_level(d, 1, &table, &gfn_remainder, i);
+    for ( i = ept_get_wl(p2m->domain); i > 0; i-- )
+    {
+        ret = ept_next_level(p2m, 1, &table, &gfn_remainder, i);
         if ( !ret || ret == GUEST_TABLE_POD_PAGE )
             goto out;
         else if ( ret == GUEST_TABLE_SUPER_PAGE )
@@ -546,6 +550,7 @@ static ept_entry_t ept_get_entry_content
 
 void ept_walk_table(struct domain *d, unsigned long gfn)
 {
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     ept_entry_t *table = map_domain_page(ept_get_asr(d));
     unsigned long gfn_remainder = gfn;
 
@@ -555,10 +560,10 @@ void ept_walk_table(struct domain *d, un
            d->domain_id, gfn);
 
     /* This pfn is higher than the highest the p2m map currently holds */
-    if ( gfn > d->arch.p2m->max_mapped_pfn )
+    if ( gfn > p2m->max_mapped_pfn )
     {
         gdprintk(XENLOG_ERR, " gfn exceeds max_mapped_pfn %lx\n",
-               d->arch.p2m->max_mapped_pfn);
+               p2m->max_mapped_pfn);
         goto out;
     }
 
@@ -593,17 +598,18 @@ out:
     return;
 }
 
-static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t,
+static mfn_t ept_get_entry_current(struct p2m_domain *p2m,
+                                   unsigned long gfn, p2m_type_t *t,
                                    p2m_query_t q)
 {
-    return ept_get_entry(current->domain, gfn, t, q);
+    return ept_get_entry(p2m, gfn, t, q);
 }
 
 /*
  * To test if the new emt type is the same with old,
  * return 1 to not to reset ept entry.
  */
-static int need_modify_ept_entry(struct domain *d, unsigned long gfn,
+static int need_modify_ept_entry(struct p2m_domain *p2m, unsigned long gfn,
                                  mfn_t mfn, uint8_t o_ipat, uint8_t o_emt,
                                  p2m_type_t p2mt)
 {
@@ -611,7 +617,7 @@ static int need_modify_ept_entry(struct 
     uint8_t emt;
     bool_t direct_mmio = (p2mt == p2m_mmio_direct);
 
-    emt = epte_get_entry_emt(d, gfn, mfn, &ipat, direct_mmio);
+    emt = epte_get_entry_emt(p2m->domain, gfn, mfn, &ipat, direct_mmio);
 
     if ( (emt == o_emt) && (ipat == o_ipat) )
         return 0;
@@ -619,21 +625,23 @@ static int need_modify_ept_entry(struct 
     return 1;
 }
 
-void ept_change_entry_emt_with_range(struct domain *d, unsigned long start_gfn,
+void ept_change_entry_emt_with_range(struct domain *d,
+                                     unsigned long start_gfn,
                                      unsigned long end_gfn)
 {
     unsigned long gfn;
     ept_entry_t e;
     mfn_t mfn;
     int order = 0;
-
-    p2m_lock(d->arch.p2m);
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
+
+    p2m_lock(p2m);
     for ( gfn = start_gfn; gfn <= end_gfn; gfn++ )
     {
         int level = 0;
         uint64_t trunk = 0;
 
-        e = ept_get_entry_content(d, gfn, &level);
+        e = ept_get_entry_content(p2m, gfn, &level);
         if ( !p2m_has_emt(e.avail1) )
             continue;
 
@@ -652,9 +660,9 @@ void ept_change_entry_emt_with_range(str
                      * Set emt for super page.
                      */
                     order = level * EPT_TABLE_ORDER;
-                    if ( need_modify_ept_entry(d, gfn, mfn, 
+                    if ( need_modify_ept_entry(p2m, gfn, mfn, 
                           e.ipat, e.emt, e.avail1) )
-                        ept_set_entry(d, gfn, mfn, order, e.avail1);
+                        ept_set_entry(p2m, gfn, mfn, order, e.avail1);
                     gfn += trunk;
                     break;
                 }
@@ -663,11 +671,11 @@ void ept_change_entry_emt_with_range(str
         }
         else /* gfn assigned with 4k */
         {
-            if ( need_modify_ept_entry(d, gfn, mfn, e.ipat, e.emt, e.avail1) )
-                ept_set_entry(d, gfn, mfn, order, e.avail1);
-        }
-    }
-    p2m_unlock(d->arch.p2m);
+            if ( need_modify_ept_entry(p2m, gfn, mfn, e.ipat, e.emt, e.avail1) 
)
+                ept_set_entry(p2m, gfn, mfn, order, e.avail1);
+        }
+    }
+    p2m_unlock(p2m);
 }
 
 /*
@@ -701,9 +709,10 @@ static void ept_change_entry_type_page(m
     unmap_domain_page(epte);
 }
 
-static void ept_change_entry_type_global(struct domain *d,
+static void ept_change_entry_type_global(struct p2m_domain *p2m,
                                          p2m_type_t ot, p2m_type_t nt)
 {
+    struct domain *d = p2m->domain;
     if ( ept_get_asr(d) == 0 )
         return;
 
@@ -714,10 +723,11 @@ static void ept_change_entry_type_global
 
 void ept_p2m_init(struct domain *d)
 {
-    d->arch.p2m->set_entry = ept_set_entry;
-    d->arch.p2m->get_entry = ept_get_entry;
-    d->arch.p2m->get_entry_current = ept_get_entry_current;
-    d->arch.p2m->change_entry_type_global = ept_change_entry_type_global;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
+    p2m->set_entry = ept_set_entry;
+    p2m->get_entry = ept_get_entry;
+    p2m->get_entry_current = ept_get_entry_current;
+    p2m->change_entry_type_global = ept_change_entry_type_global;
 }
 
 static void ept_dump_p2m_table(unsigned char key)
@@ -742,7 +752,7 @@ static void ept_dump_p2m_table(unsigned 
         p2m = p2m_get_hostp2m(d);
         printk("\ndomain%d EPT p2m table: \n", d->domain_id);
 
-        for ( gfn = 0; gfn <= d->arch.p2m->max_mapped_pfn; gfn += (1 << order) 
)
+        for ( gfn = 0; gfn <= p2m->max_mapped_pfn; gfn += (1 << order) )
         {
             gfn_remainder = gfn;
             mfn = _mfn(INVALID_MFN);
@@ -750,7 +760,7 @@ static void ept_dump_p2m_table(unsigned 
 
             for ( i = ept_get_wl(d); i > 0; i-- )
             {
-                ret = ept_next_level(d, 1, &table, &gfn_remainder, i);
+                ret = ept_next_level(p2m, 1, &table, &gfn_remainder, i);
                 if ( ret != GUEST_TABLE_NORMAL_PAGE )
                     break;
             }
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/mem_event.c
--- a/xen/arch/x86/mm/mem_event.c       Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/mem_event.c       Mon Aug 09 16:46:42 2010 +0100
@@ -235,7 +235,7 @@ int mem_event_domctl(struct domain *d, x
             /* Get MFN of ring page */
             guest_get_eff_l1e(v, ring_addr, &l1e);
             gfn = l1e_get_pfn(l1e);
-            ring_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+            ring_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, &p2mt);
 
             rc = -EINVAL;
             if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
@@ -244,7 +244,7 @@ int mem_event_domctl(struct domain *d, x
             /* Get MFN of shared page */
             guest_get_eff_l1e(v, shared_addr, &l1e);
             gfn = l1e_get_pfn(l1e);
-            shared_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+            shared_mfn = gfn_to_mfn(p2m_get_hostp2m(dom_mem_event), gfn, 
&p2mt);
 
             rc = -EINVAL;
             if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/mem_paging.c
--- a/xen/arch/x86/mm/mem_paging.c      Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/mem_paging.c      Mon Aug 09 16:46:42 2010 +0100
@@ -29,33 +29,34 @@ int mem_paging_domctl(struct domain *d, 
                       XEN_GUEST_HANDLE(void) u_domctl)
 {
     int rc;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     switch( mec->op )
     {
     case XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE:
     {
         unsigned long gfn = mec->gfn;
-        rc = p2m_mem_paging_nominate(d, gfn);
+        rc = p2m_mem_paging_nominate(p2m, gfn);
     }
     break;
 
     case XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT:
     {
         unsigned long gfn = mec->gfn;
-        rc = p2m_mem_paging_evict(d, gfn);
+        rc = p2m_mem_paging_evict(p2m, gfn);
     }
     break;
 
     case XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP:
     {
         unsigned long gfn = mec->gfn;
-        rc = p2m_mem_paging_prep(d, gfn);
+        rc = p2m_mem_paging_prep(p2m, gfn);
     }
     break;
 
     case XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME:
     {
-        p2m_mem_paging_resume(d);
+        p2m_mem_paging_resume(p2m);
         rc = 0;
     }
     break;
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/mem_sharing.c
--- a/xen/arch/x86/mm/mem_sharing.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/mem_sharing.c     Mon Aug 09 16:46:42 2010 +0100
@@ -251,6 +251,7 @@ static void mem_sharing_audit(void)
             list_for_each(le, &e->gfns)
             {
                 struct domain *d;
+                struct p2m_domain *p2m;
                 p2m_type_t t;
                 mfn_t mfn;
 
@@ -262,7 +263,8 @@ static void mem_sharing_audit(void)
                             g->domain, g->gfn, mfn_x(e->mfn));
                     continue;
                 }
-                mfn = gfn_to_mfn(d, g->gfn, &t); 
+                p2m = p2m_get_hostp2m(d);
+                mfn = gfn_to_mfn(p2m, g->gfn, &t); 
                 if(mfn_x(mfn) != mfn_x(e->mfn))
                     MEM_SHARING_DEBUG("Incorrect P2M for d=%d, PFN=%lx."
                                       "Expecting MFN=%ld, got %ld\n",
@@ -377,7 +379,7 @@ int mem_sharing_debug_gfn(struct domain 
     mfn_t mfn;
     struct page_info *page;
 
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    mfn = gfn_to_mfn(p2m_get_hostp2m(d), gfn, &p2mt);
     page = mfn_to_page(mfn);
 
     printk("Debug for domain=%d, gfn=%lx, ", 
@@ -487,7 +489,7 @@ int mem_sharing_debug_gref(struct domain
     return mem_sharing_debug_gfn(d, gfn); 
 }
 
-int mem_sharing_nominate_page(struct domain *d, 
+int mem_sharing_nominate_page(struct p2m_domain *p2m, 
                               unsigned long gfn,
                               int expected_refcnt,
                               shr_handle_t *phandle)
@@ -499,10 +501,11 @@ int mem_sharing_nominate_page(struct dom
     shr_handle_t handle;
     shr_hash_entry_t *hash_entry;
     struct gfn_info *gfn_info;
+    struct domain *d = p2m->domain;
 
     *phandle = 0UL;
 
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    mfn = gfn_to_mfn(p2m, gfn, &p2mt);
 
     /* Check if mfn is valid */
     ret = -EINVAL;
@@ -536,7 +539,7 @@ int mem_sharing_nominate_page(struct dom
     }
 
     /* Change the p2m type */
-    if(p2m_change_type(d, gfn, p2mt, p2m_ram_shared) != p2mt) 
+    if(p2m_change_type(p2m, gfn, p2mt, p2m_ram_shared) != p2mt) 
     {
         /* This is unlikely, as the type must have changed since we've checked
          * it a few lines above.
@@ -599,7 +602,7 @@ int mem_sharing_share_pages(shr_handle_t
         list_del(&gfn->list);
         d = get_domain_by_id(gfn->domain);
         BUG_ON(!d);
-        BUG_ON(set_shared_p2m_entry(d, gfn->gfn, se->mfn) == 0);
+        BUG_ON(set_shared_p2m_entry(p2m_get_hostp2m(d), gfn->gfn, se->mfn) == 
0);
         put_domain(d);
         list_add(&gfn->list, &se->gfns);
         put_page_and_type(cpage);
@@ -618,7 +621,7 @@ err_out:
     return ret;
 }
 
-int mem_sharing_unshare_page(struct domain *d, 
+int mem_sharing_unshare_page(struct p2m_domain *p2m,
                              unsigned long gfn, 
                              uint16_t flags)
 {
@@ -631,8 +634,9 @@ int mem_sharing_unshare_page(struct doma
     struct gfn_info *gfn_info = NULL;
     shr_handle_t handle;
     struct list_head *le;
-
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    struct domain *d = p2m->domain;
+
+    mfn = gfn_to_mfn(p2m, gfn, &p2mt);
 
     page = mfn_to_page(mfn);
     handle = page->shr_handle;
@@ -696,7 +700,7 @@ gfn_found:
     unmap_domain_page(s);
     unmap_domain_page(t);
 
-    ASSERT(set_shared_p2m_entry(d, gfn, page_to_mfn(page)) != 0);
+    ASSERT(set_shared_p2m_entry(p2m, gfn, page_to_mfn(page)) != 0);
     put_page_and_type(old_page);
 
 private_page_found:    
@@ -708,7 +712,7 @@ private_page_found:
         atomic_dec(&nr_saved_mfns);
     shr_unlock();
 
-    if(p2m_change_type(d, gfn, p2m_ram_shared, p2m_ram_rw) != 
+    if(p2m_change_type(p2m, gfn, p2m_ram_shared, p2m_ram_rw) != 
                                                 p2m_ram_shared) 
     {
         printk("Could not change p2m type.\n");
@@ -740,7 +744,7 @@ int mem_sharing_domctl(struct domain *d,
             shr_handle_t handle;
             if(!mem_sharing_enabled(d))
                 return -EINVAL;
-            rc = mem_sharing_nominate_page(d, gfn, 0, &handle);
+            rc = mem_sharing_nominate_page(p2m_get_hostp2m(d), gfn, 0, 
&handle);
             mec->u.nominate.handle = handle;
             mem_sharing_audit();
         }
@@ -756,7 +760,8 @@ int mem_sharing_domctl(struct domain *d,
                 return -EINVAL;
             if(mem_sharing_gref_to_gfn(d, gref, &gfn) < 0)
                 return -EINVAL;
-            rc = mem_sharing_nominate_page(d, gfn, 3, &handle);
+            rc = mem_sharing_nominate_page(p2m_get_hostp2m(d),
+                gfn, 3, &handle);
             mec->u.nominate.handle = handle;
             mem_sharing_audit();
         }
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/p2m.c     Mon Aug 09 16:46:42 2010 +0100
@@ -108,9 +108,9 @@ static unsigned long p2m_type_to_flags(p
 }
 
 #if P2M_AUDIT
-static void audit_p2m(struct domain *d);
+static void audit_p2m(struct p2m_domain *p2m);
 #else
-# define audit_p2m(_d) do { (void)(_d); } while(0)
+# define audit_p2m(_p2m) do { (void)(_p2m); } while(0)
 #endif /* P2M_AUDIT */
 
 // Find the next level's P2M entry, checking for out-of-range gfn's...
@@ -135,15 +135,17 @@ p2m_find_entry(void *table, unsigned lon
 }
 
 struct page_info *
-p2m_alloc_ptp(struct domain *d, unsigned long type)
+p2m_alloc_ptp(struct p2m_domain *p2m, unsigned long type)
 {
     struct page_info *pg;
 
-    pg = d->arch.p2m->alloc_page(d);
+    ASSERT(p2m);
+    ASSERT(p2m->alloc_page);
+    pg = p2m->alloc_page(p2m);
     if (pg == NULL)
         return NULL;
 
-    page_list_add_tail(pg, &d->arch.p2m->pages);
+    page_list_add_tail(pg, &p2m->pages);
     pg->u.inuse.type_info = type | 1 | PGT_validated;
     pg->count_info |= 1;
 
@@ -154,7 +156,7 @@ p2m_alloc_ptp(struct domain *d, unsigned
 // Returns 0 on error.
 //
 static int
-p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
+p2m_next_level(struct p2m_domain *p2m, mfn_t *table_mfn, void **table,
                unsigned long *gfn_remainder, unsigned long gfn, u32 shift,
                u32 max, unsigned long type)
 {
@@ -163,7 +165,7 @@ p2m_next_level(struct domain *d, mfn_t *
     l1_pgentry_t new_entry;
     void *next;
     int i;
-    ASSERT(d->arch.p2m->alloc_page);
+    ASSERT(p2m->alloc_page);
 
     if ( !(p2m_entry = p2m_find_entry(*table, gfn_remainder, gfn,
                                       shift, max)) )
@@ -174,7 +176,7 @@ p2m_next_level(struct domain *d, mfn_t *
     {
         struct page_info *pg;
 
-        pg = p2m_alloc_ptp(d, type);
+        pg = p2m_alloc_ptp(p2m, type);
         if ( pg == NULL )
             return 0;
 
@@ -183,7 +185,7 @@ p2m_next_level(struct domain *d, mfn_t *
 
         switch ( type ) {
         case PGT_l3_page_table:
-            paging_write_p2m_entry(d, gfn,
+            paging_write_p2m_entry(p2m->domain, gfn,
                                    p2m_entry, *table_mfn, new_entry, 4);
             break;
         case PGT_l2_page_table:
@@ -191,11 +193,11 @@ p2m_next_level(struct domain *d, mfn_t *
             /* for PAE mode, PDPE only has PCD/PWT/P bits available */
             new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)), _PAGE_PRESENT);
 #endif
-            paging_write_p2m_entry(d, gfn,
+            paging_write_p2m_entry(p2m->domain, gfn,
                                    p2m_entry, *table_mfn, new_entry, 3);
             break;
         case PGT_l1_page_table:
-            paging_write_p2m_entry(d, gfn,
+            paging_write_p2m_entry(p2m->domain, gfn,
                                    p2m_entry, *table_mfn, new_entry, 2);
             break;
         default:
@@ -212,7 +214,7 @@ p2m_next_level(struct domain *d, mfn_t *
         unsigned long flags, pfn;
         struct page_info *pg;
 
-        pg = p2m_alloc_ptp(d, PGT_l2_page_table);
+        pg = p2m_alloc_ptp(p2m, PGT_l2_page_table);
         if ( pg == NULL )
             return 0;
 
@@ -223,13 +225,13 @@ p2m_next_level(struct domain *d, mfn_t *
         for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
         {
             new_entry = l1e_from_pfn(pfn + (i * L1_PAGETABLE_ENTRIES), flags);
-            paging_write_p2m_entry(d, gfn, l1_entry+i, *table_mfn, new_entry,
-                                   2);
+            paging_write_p2m_entry(p2m->domain, gfn,
+                                   l1_entry+i, *table_mfn, new_entry, 2);
         }
         unmap_domain_page(l1_entry);
         new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)),
                                  __PAGE_HYPERVISOR|_PAGE_USER); //disable PSE
-        paging_write_p2m_entry(d, gfn,
+        paging_write_p2m_entry(p2m->domain, gfn,
                                p2m_entry, *table_mfn, new_entry, 3);
     }
 
@@ -240,7 +242,7 @@ p2m_next_level(struct domain *d, mfn_t *
         unsigned long flags, pfn;
         struct page_info *pg;
 
-        pg = p2m_alloc_ptp(d, PGT_l1_page_table);
+        pg = p2m_alloc_ptp(p2m, PGT_l1_page_table);
         if ( pg == NULL )
             return 0;
 
@@ -257,14 +259,14 @@ p2m_next_level(struct domain *d, mfn_t *
         for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
         {
             new_entry = l1e_from_pfn(pfn + i, flags);
-            paging_write_p2m_entry(d, gfn,
+            paging_write_p2m_entry(p2m->domain, gfn,
                                    l1_entry+i, *table_mfn, new_entry, 1);
         }
         unmap_domain_page(l1_entry);
         
         new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)),
                                  __PAGE_HYPERVISOR|_PAGE_USER);
-        paging_write_p2m_entry(d, gfn,
+        paging_write_p2m_entry(p2m->domain, gfn,
                                p2m_entry, *table_mfn, new_entry, 2);
     }
 
@@ -280,17 +282,17 @@ p2m_next_level(struct domain *d, mfn_t *
  * Populate-on-demand functionality
  */
 static
-int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, 
+int set_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
                   unsigned int page_order, p2m_type_t p2mt);
 
 static int
-p2m_pod_cache_add(struct domain *d,
+p2m_pod_cache_add(struct p2m_domain *p2m,
                   struct page_info *page,
                   unsigned long order)
 {
     int i;
     struct page_info *p;
-    struct p2m_domain *p2md = d->arch.p2m;
+    struct domain *d = p2m->domain;
 
 #ifndef NDEBUG
     mfn_t mfn;
@@ -320,7 +322,7 @@ p2m_pod_cache_add(struct domain *d,
     }
 #endif
 
-    ASSERT(p2m_locked_by_me(p2md));
+    ASSERT(p2m_locked_by_me(p2m));
 
     /*
      * Pages from domain_alloc and returned by the balloon driver aren't
@@ -347,12 +349,12 @@ p2m_pod_cache_add(struct domain *d,
     switch(order)
     {
     case 9:
-        page_list_add_tail(page, &p2md->pod.super); /* lock: page_alloc */
-        p2md->pod.count += 1 << order;
+        page_list_add_tail(page, &p2m->pod.super); /* lock: page_alloc */
+        p2m->pod.count += 1 << order;
         break;
     case 0:
-        page_list_add_tail(page, &p2md->pod.single); /* lock: page_alloc */
-        p2md->pod.count += 1 ;
+        page_list_add_tail(page, &p2m->pod.single); /* lock: page_alloc */
+        p2m->pod.count += 1;
         break;
     default:
         BUG();
@@ -371,57 +373,56 @@ p2m_pod_cache_add(struct domain *d,
  * down 2-meg pages into singleton pages automatically.  Returns null if
  * a superpage is requested and no superpages are available.  Must be called
  * with the d->page_lock held. */
-static struct page_info * p2m_pod_cache_get(struct domain *d,
+static struct page_info * p2m_pod_cache_get(struct p2m_domain *p2m,
                                             unsigned long order)
 {
-    struct p2m_domain *p2md = d->arch.p2m;
     struct page_info *p = NULL;
     int i;
 
-    if ( order == 9 && page_list_empty(&p2md->pod.super) )
+    if ( order == 9 && page_list_empty(&p2m->pod.super) )
     {
         return NULL;
     }
-    else if ( order == 0 && page_list_empty(&p2md->pod.single) )
+    else if ( order == 0 && page_list_empty(&p2m->pod.single) )
     {
         unsigned long mfn;
         struct page_info *q;
 
-        BUG_ON( page_list_empty(&p2md->pod.super) );
+        BUG_ON( page_list_empty(&p2m->pod.super) );
 
         /* Break up a superpage to make single pages. NB count doesn't
          * need to be adjusted. */
-        p = page_list_remove_head(&p2md->pod.super);
+        p = page_list_remove_head(&p2m->pod.super);
         mfn = mfn_x(page_to_mfn(p));
 
         for ( i=0; i<SUPERPAGE_PAGES; i++ )
         {
             q = mfn_to_page(_mfn(mfn+i));
-            page_list_add_tail(q, &p2md->pod.single);
+            page_list_add_tail(q, &p2m->pod.single);
         }
     }
 
     switch ( order )
     {
     case 9:
-        BUG_ON( page_list_empty(&p2md->pod.super) );
-        p = page_list_remove_head(&p2md->pod.super);
-        p2md->pod.count -= 1 << order; /* Lock: page_alloc */
+        BUG_ON( page_list_empty(&p2m->pod.super) );
+        p = page_list_remove_head(&p2m->pod.super);
+        p2m->pod.count -= 1 << order; /* Lock: page_alloc */
         break;
     case 0:
-        BUG_ON( page_list_empty(&p2md->pod.single) );
-        p = page_list_remove_head(&p2md->pod.single);
-        p2md->pod.count -= 1;
+        BUG_ON( page_list_empty(&p2m->pod.single) );
+        p = page_list_remove_head(&p2m->pod.single);
+        p2m->pod.count -= 1;
         break;
     default:
         BUG();
     }
 
     /* Put the pages back on the domain page_list */
-    for ( i = 0 ; i < (1 << order) ; i++ )
-    {
-        BUG_ON(page_get_owner(p + i) != d);
-        page_list_add_tail(p + i, &d->page_list);
+    for ( i = 0 ; i < (1 << order); i++ )
+    {
+        BUG_ON(page_get_owner(p + i) != p2m->domain);
+        page_list_add_tail(p + i, &p2m->domain->page_list);
     }
 
     return p;
@@ -429,18 +430,18 @@ static struct page_info * p2m_pod_cache_
 
 /* Set the size of the cache, allocating or freeing as necessary. */
 static int
-p2m_pod_set_cache_target(struct domain *d, unsigned long pod_target)
-{
-    struct p2m_domain *p2md = d->arch.p2m;
+p2m_pod_set_cache_target(struct p2m_domain *p2m, unsigned long pod_target)
+{
+    struct domain *d = p2m->domain;
     int ret = 0;
 
     /* Increasing the target */
-    while ( pod_target > p2md->pod.count )
+    while ( pod_target > p2m->pod.count )
     {
         struct page_info * page;
         int order;
 
-        if ( (pod_target - p2md->pod.count) >= SUPERPAGE_PAGES )
+        if ( (pod_target - p2m->pod.count) >= SUPERPAGE_PAGES )
             order = 9;
         else
             order = 0;
@@ -456,18 +457,18 @@ p2m_pod_set_cache_target(struct domain *
             }   
             
             printk("%s: Unable to allocate domheap page for pod cache.  target 
%lu cachesize %d\n",
-                   __func__, pod_target, p2md->pod.count);
+                   __func__, pod_target, p2m->pod.count);
             ret = -ENOMEM;
             goto out;
         }
 
-        p2m_pod_cache_add(d, page, order);
+        p2m_pod_cache_add(p2m, page, order);
     }
 
     /* Decreasing the target */
     /* We hold the p2m lock here, so we don't need to worry about
      * cache disappearing under our feet. */
-    while ( pod_target < p2md->pod.count )
+    while ( pod_target < p2m->pod.count )
     {
         struct page_info * page;
         int order, i;
@@ -476,13 +477,13 @@ p2m_pod_set_cache_target(struct domain *
          * entries may disappear before we grab the lock. */
         spin_lock(&d->page_alloc_lock);
 
-        if ( (p2md->pod.count - pod_target) > SUPERPAGE_PAGES
-             && !page_list_empty(&p2md->pod.super) )
+        if ( (p2m->pod.count - pod_target) > SUPERPAGE_PAGES
+             && !page_list_empty(&p2m->pod.super) )
             order = 9;
         else
             order = 0;
 
-        page = p2m_pod_cache_get(d, order);
+        page = p2m_pod_cache_get(p2m, order);
 
         ASSERT(page != NULL);
 
@@ -553,14 +554,14 @@ p2m_pod_set_mem_target(struct domain *d,
 p2m_pod_set_mem_target(struct domain *d, unsigned long target)
 {
     unsigned pod_target;
-    struct p2m_domain *p2md = d->arch.p2m;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     int ret = 0;
     unsigned long populated;
 
-    p2m_lock(p2md);
+    p2m_lock(p2m);
 
     /* P == B: Nothing to do. */
-    if ( p2md->pod.entry_count == 0 )
+    if ( p2m->pod.entry_count == 0 )
         goto out;
 
     /* Don't do anything if the domain is being torn down */
@@ -572,21 +573,21 @@ p2m_pod_set_mem_target(struct domain *d,
     if ( target < d->tot_pages )
         goto out;
 
-    populated  = d->tot_pages - p2md->pod.count;
+    populated  = d->tot_pages - p2m->pod.count;
 
     pod_target = target - populated;
 
     /* B < T': Set the cache size equal to # of outstanding entries,
      * let the balloon driver fill in the rest. */
-    if ( pod_target > p2md->pod.entry_count )
-        pod_target = p2md->pod.entry_count;
-
-    ASSERT( pod_target >= p2md->pod.count );
-
-    ret = p2m_pod_set_cache_target(d, pod_target);
+    if ( pod_target > p2m->pod.entry_count )
+        pod_target = p2m->pod.entry_count;
+
+    ASSERT( pod_target >= p2m->pod.count );
+
+    ret = p2m_pod_set_cache_target(p2m, pod_target);
 
 out:
-    p2m_unlock(p2md);
+    p2m_unlock(p2m);
 
     return ret;
 }
@@ -594,16 +595,16 @@ void
 void
 p2m_pod_empty_cache(struct domain *d)
 {
-    struct p2m_domain *p2md = d->arch.p2m;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     struct page_info *page;
 
     /* After this barrier no new PoD activities can happen. */
     BUG_ON(!d->is_dying);
-    spin_barrier(&p2md->lock);
+    spin_barrier(&p2m->lock);
 
     spin_lock(&d->page_alloc_lock);
 
-    while ( (page = page_list_remove_head(&p2md->pod.super)) )
+    while ( (page = page_list_remove_head(&p2m->pod.super)) )
     {
         int i;
             
@@ -613,18 +614,18 @@ p2m_pod_empty_cache(struct domain *d)
             page_list_add_tail(page + i, &d->page_list);
         }
 
-        p2md->pod.count -= SUPERPAGE_PAGES;
-    }
-
-    while ( (page = page_list_remove_head(&p2md->pod.single)) )
+        p2m->pod.count -= SUPERPAGE_PAGES;
+    }
+
+    while ( (page = page_list_remove_head(&p2m->pod.single)) )
     {
         BUG_ON(page_get_owner(page) != d);
         page_list_add_tail(page, &d->page_list);
 
-        p2md->pod.count -= 1;
-    }
-
-    BUG_ON(p2md->pod.count != 0);
+        p2m->pod.count -= 1;
+    }
+
+    BUG_ON(p2m->pod.count != 0);
 
     spin_unlock(&d->page_alloc_lock);
 }
@@ -642,9 +643,9 @@ p2m_pod_decrease_reservation(struct doma
                              xen_pfn_t gpfn,
                              unsigned int order)
 {
-    struct p2m_domain *p2md = d->arch.p2m;
     int ret=0;
     int i;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     int steal_for_cache = 0;
     int pod = 0, nonpod = 0, ram = 0;
@@ -652,14 +653,14 @@ p2m_pod_decrease_reservation(struct doma
 
     /* If we don't have any outstanding PoD entries, let things take their
      * course */
-    if ( p2md->pod.entry_count == 0 )
+    if ( p2m->pod.entry_count == 0 )
         goto out;
 
     /* Figure out if we need to steal some freed memory for our cache */
-    steal_for_cache =  ( p2md->pod.entry_count > p2md->pod.count );
-
-    p2m_lock(p2md);
-    audit_p2m(d);
+    steal_for_cache =  ( p2m->pod.entry_count > p2m->pod.count );
+
+    p2m_lock(p2m);
+    audit_p2m(p2m);
 
     if ( unlikely(d->is_dying) )
         goto out_unlock;
@@ -670,7 +671,7 @@ p2m_pod_decrease_reservation(struct doma
     {
         p2m_type_t t;
 
-        gfn_to_mfn_query(d, gpfn + i, &t);
+        gfn_to_mfn_query(p2m, gpfn + i, &t);
 
         if ( t == p2m_populate_on_demand )
             pod++;
@@ -690,9 +691,9 @@ p2m_pod_decrease_reservation(struct doma
     {
         /* All PoD: Mark the whole region invalid and tell caller
          * we're done. */
-        set_p2m_entry(d, gpfn, _mfn(INVALID_MFN), order, p2m_invalid);
-        p2md->pod.entry_count-=(1<<order); /* Lock: p2m */
-        BUG_ON(p2md->pod.entry_count < 0);
+        set_p2m_entry(p2m, gpfn, _mfn(INVALID_MFN), order, p2m_invalid);
+        p2m->pod.entry_count-=(1<<order); /* Lock: p2m */
+        BUG_ON(p2m->pod.entry_count < 0);
         ret = 1;
         goto out_entry_check;
     }
@@ -710,12 +711,12 @@ p2m_pod_decrease_reservation(struct doma
         mfn_t mfn;
         p2m_type_t t;
 
-        mfn = gfn_to_mfn_query(d, gpfn + i, &t);
+        mfn = gfn_to_mfn_query(p2m, gpfn + i, &t);
         if ( t == p2m_populate_on_demand )
         {
-            set_p2m_entry(d, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid);
-            p2md->pod.entry_count--; /* Lock: p2m */
-            BUG_ON(p2md->pod.entry_count < 0);
+            set_p2m_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid);
+            p2m->pod.entry_count--; /* Lock: p2m */
+            BUG_ON(p2m->pod.entry_count < 0);
             pod--;
         }
         else if ( steal_for_cache && p2m_is_ram(t) )
@@ -726,12 +727,12 @@ p2m_pod_decrease_reservation(struct doma
 
             page = mfn_to_page(mfn);
 
-            set_p2m_entry(d, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid);
+            set_p2m_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid);
             set_gpfn_from_mfn(mfn_x(mfn), INVALID_M2P_ENTRY);
 
-            p2m_pod_cache_add(d, page, 0);
-
-            steal_for_cache =  ( p2md->pod.entry_count > p2md->pod.count );
+            p2m_pod_cache_add(p2m, page, 0);
+
+            steal_for_cache =  ( p2m->pod.entry_count > p2m->pod.count );
 
             nonpod--;
             ram--;
@@ -745,33 +746,31 @@ p2m_pod_decrease_reservation(struct doma
 
 out_entry_check:
     /* If we've reduced our "liabilities" beyond our "assets", free some */
-    if ( p2md->pod.entry_count < p2md->pod.count )
-    {
-        p2m_pod_set_cache_target(d, p2md->pod.entry_count);
+    if ( p2m->pod.entry_count < p2m->pod.count )
+    {
+        p2m_pod_set_cache_target(p2m, p2m->pod.entry_count);
     }
 
 out_unlock:
-    audit_p2m(d);
-    p2m_unlock(p2md);
+    audit_p2m(p2m);
+    p2m_unlock(p2m);
 
 out:
     return ret;
 }
 
 void
-p2m_pod_dump_data(struct domain *d)
-{
-    struct p2m_domain *p2md = d->arch.p2m;
-    
+p2m_pod_dump_data(struct p2m_domain *p2m)
+{
     printk("    PoD entries=%d cachesize=%d\n",
-           p2md->pod.entry_count, p2md->pod.count);
+           p2m->pod.entry_count, p2m->pod.count);
 }
 
 
 /* Search for all-zero superpages to be reclaimed as superpages for the
  * PoD cache. Must be called w/ p2m lock held, page_alloc lock not held. */
 static int
-p2m_pod_zero_check_superpage(struct domain *d, unsigned long gfn)
+p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
 {
     mfn_t mfn, mfn0 = _mfn(INVALID_MFN);
     p2m_type_t type, type0 = 0;
@@ -779,6 +778,7 @@ p2m_pod_zero_check_superpage(struct doma
     int ret=0, reset = 0;
     int i, j;
     int max_ref = 1;
+    struct domain *d = p2m->domain;
 
     if ( !superpage_aligned(gfn) )
         goto out;
@@ -792,7 +792,7 @@ p2m_pod_zero_check_superpage(struct doma
     for ( i=0; i<SUPERPAGE_PAGES; i++ )
     {
         
-        mfn = gfn_to_mfn_query(d, gfn + i, &type);
+        mfn = gfn_to_mfn_query(p2m, gfn + i, &type);
 
         if ( i == 0 )
         {
@@ -840,7 +840,7 @@ p2m_pod_zero_check_superpage(struct doma
     }
 
     /* Try to remove the page, restoring old mapping if it fails. */
-    set_p2m_entry(d, gfn,
+    set_p2m_entry(p2m, gfn,
                   _mfn(POPULATE_ON_DEMAND_MFN), 9,
                   p2m_populate_on_demand);
 
@@ -892,23 +892,24 @@ p2m_pod_zero_check_superpage(struct doma
 
     /* Finally!  We've passed all the checks, and can add the mfn superpage
      * back on the PoD cache, and account for the new p2m PoD entries */
-    p2m_pod_cache_add(d, mfn_to_page(mfn0), 9);
-    d->arch.p2m->pod.entry_count += SUPERPAGE_PAGES;
+    p2m_pod_cache_add(p2m, mfn_to_page(mfn0), 9);
+    p2m->pod.entry_count += SUPERPAGE_PAGES;
 
 out_reset:
     if ( reset )
-        set_p2m_entry(d, gfn, mfn0, 9, type0);
+        set_p2m_entry(p2m, gfn, mfn0, 9, type0);
     
 out:
     return ret;
 }
 
 static void
-p2m_pod_zero_check(struct domain *d, unsigned long *gfns, int count)
+p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count)
 {
     mfn_t mfns[count];
     p2m_type_t types[count];
     unsigned long * map[count];
+    struct domain *d = p2m->domain;
 
     int i, j;
     int max_ref = 1;
@@ -920,7 +921,7 @@ p2m_pod_zero_check(struct domain *d, uns
     /* First, get the gfn list, translate to mfns, and map the pages. */
     for ( i=0; i<count; i++ )
     {
-        mfns[i] = gfn_to_mfn_query(d, gfns[i], types + i);
+        mfns[i] = gfn_to_mfn_query(p2m, gfns[i], types + i);
         /* If this is ram, and not a pagetable or from the xen heap, and 
probably not mapped
            elsewhere, map it; otherwise, skip. */
         if ( p2m_is_ram(types[i])
@@ -952,7 +953,7 @@ p2m_pod_zero_check(struct domain *d, uns
         }
 
         /* Try to remove the page, restoring old mapping if it fails. */
-        set_p2m_entry(d, gfns[i],
+        set_p2m_entry(p2m, gfns[i],
                       _mfn(POPULATE_ON_DEMAND_MFN), 0,
                       p2m_populate_on_demand);
 
@@ -963,7 +964,7 @@ p2m_pod_zero_check(struct domain *d, uns
             unmap_domain_page(map[i]);
             map[i] = NULL;
 
-            set_p2m_entry(d, gfns[i], mfns[i], 0, types[i]);
+            set_p2m_entry(p2m, gfns[i], mfns[i], 0, types[i]);
 
             continue;
         }
@@ -985,7 +986,7 @@ p2m_pod_zero_check(struct domain *d, uns
          * check timing.  */
         if ( j < PAGE_SIZE/sizeof(*map[i]) )
         {
-            set_p2m_entry(d, gfns[i], mfns[i], 0, types[i]);
+            set_p2m_entry(p2m, gfns[i], mfns[i], 0, types[i]);
         }
         else
         {
@@ -1005,8 +1006,8 @@ p2m_pod_zero_check(struct domain *d, uns
             }
 
             /* Add to cache, and account for the new p2m PoD entry */
-            p2m_pod_cache_add(d, mfn_to_page(mfns[i]), 0);
-            d->arch.p2m->pod.entry_count++;
+            p2m_pod_cache_add(p2m, mfn_to_page(mfns[i]), 0);
+            p2m->pod.entry_count++;
         }
     }
     
@@ -1014,56 +1015,53 @@ p2m_pod_zero_check(struct domain *d, uns
 
 #define POD_SWEEP_LIMIT 1024
 static void
-p2m_pod_emergency_sweep_super(struct domain *d)
-{
-    struct p2m_domain *p2md = d->arch.p2m;
+p2m_pod_emergency_sweep_super(struct p2m_domain *p2m)
+{
     unsigned long i, start, limit;
 
-    if ( p2md->pod.reclaim_super == 0 )
-    {
-        p2md->pod.reclaim_super = (p2md->pod.max_guest>>9)<<9;
-        p2md->pod.reclaim_super -= SUPERPAGE_PAGES;
+    if ( p2m->pod.reclaim_super == 0 )
+    {
+        p2m->pod.reclaim_super = (p2m->pod.max_guest>>9)<<9;
+        p2m->pod.reclaim_super -= SUPERPAGE_PAGES;
     }
     
-    start = p2md->pod.reclaim_super;
+    start = p2m->pod.reclaim_super;
     limit = (start > POD_SWEEP_LIMIT) ? (start - POD_SWEEP_LIMIT) : 0;
 
-    for ( i=p2md->pod.reclaim_super ; i > 0 ; i-=SUPERPAGE_PAGES )
-    {
-        p2m_pod_zero_check_superpage(d, i);
+    for ( i=p2m->pod.reclaim_super ; i > 0 ; i -= SUPERPAGE_PAGES )
+    {
+        p2m_pod_zero_check_superpage(p2m, i);
         /* Stop if we're past our limit and we have found *something*.
          *
          * NB that this is a zero-sum game; we're increasing our cache size
          * by increasing our 'debt'.  Since we hold the p2m lock,
          * (entry_count - count) must remain the same. */
-        if ( !page_list_empty(&p2md->pod.super) &&  i < limit )
+        if ( !page_list_empty(&p2m->pod.super) &&  i < limit )
             break;
     }
 
-    p2md->pod.reclaim_super = i ? i - SUPERPAGE_PAGES : 0;
-
+    p2m->pod.reclaim_super = i ? i - SUPERPAGE_PAGES : 0;
 }
 
 #define POD_SWEEP_STRIDE  16
 static void
-p2m_pod_emergency_sweep(struct domain *d)
-{
-    struct p2m_domain *p2md = d->arch.p2m;
+p2m_pod_emergency_sweep(struct p2m_domain *p2m)
+{
     unsigned long gfns[POD_SWEEP_STRIDE];
     unsigned long i, j=0, start, limit;
     p2m_type_t t;
 
 
-    if ( p2md->pod.reclaim_single == 0 )
-        p2md->pod.reclaim_single = p2md->pod.max_guest;
-
-    start = p2md->pod.reclaim_single;
+    if ( p2m->pod.reclaim_single == 0 )
+        p2m->pod.reclaim_single = p2m->pod.max_guest;
+
+    start = p2m->pod.reclaim_single;
     limit = (start > POD_SWEEP_LIMIT) ? (start - POD_SWEEP_LIMIT) : 0;
 
     /* FIXME: Figure out how to avoid superpages */
-    for ( i=p2md->pod.reclaim_single ; i > 0 ; i-- )
-    {
-        gfn_to_mfn_query(d, i, &t );
+    for ( i=p2m->pod.reclaim_single; i > 0 ; i-- )
+    {
+        gfn_to_mfn_query(p2m, i, &t );
         if ( p2m_is_ram(t) )
         {
             gfns[j] = i;
@@ -1071,7 +1069,7 @@ p2m_pod_emergency_sweep(struct domain *d
             BUG_ON(j > POD_SWEEP_STRIDE);
             if ( j == POD_SWEEP_STRIDE )
             {
-                p2m_pod_zero_check(d, gfns, j);
+                p2m_pod_zero_check(p2m, gfns, j);
                 j = 0;
             }
         }
@@ -1080,29 +1078,29 @@ p2m_pod_emergency_sweep(struct domain *d
          * NB that this is a zero-sum game; we're increasing our cache size
          * by re-increasing our 'debt'.  Since we hold the p2m lock,
          * (entry_count - count) must remain the same. */
-        if ( p2md->pod.count > 0 && i < limit )
+        if ( p2m->pod.count > 0 && i < limit )
             break;
     }
 
     if ( j )
-        p2m_pod_zero_check(d, gfns, j);
-
-    p2md->pod.reclaim_single = i ? i - 1 : i;
+        p2m_pod_zero_check(p2m, gfns, j);
+
+    p2m->pod.reclaim_single = i ? i - 1 : i;
 
 }
 
 int
-p2m_pod_demand_populate(struct domain *d, unsigned long gfn,
+p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn,
                         unsigned int order,
                         p2m_query_t q)
 {
+    struct domain *d = p2m->domain;
     struct page_info *p = NULL; /* Compiler warnings */
     unsigned long gfn_aligned;
     mfn_t mfn;
-    struct p2m_domain *p2md = d->arch.p2m;
     int i;
 
-    ASSERT(p2m_locked_by_me(d->arch.p2m));
+    ASSERT(p2m_locked_by_me(p2m));
 
     /* This check is done with the p2m lock held.  This will make sure that
      * even if d->is_dying changes under our feet, p2m_pod_empty_cache() 
@@ -1120,34 +1118,34 @@ p2m_pod_demand_populate(struct domain *d
          * set_p2m_entry() should automatically shatter the 1GB page into 
          * 512 2MB pages. The rest of 511 calls are unnecessary.
          */
-        set_p2m_entry(d, gfn_aligned, _mfn(POPULATE_ON_DEMAND_MFN), 9,
+        set_p2m_entry(p2m, gfn_aligned, _mfn(POPULATE_ON_DEMAND_MFN), 9,
                       p2m_populate_on_demand);
-        audit_p2m(d);
-        p2m_unlock(p2md);
+        audit_p2m(p2m);
+        p2m_unlock(p2m);
         return 0;
     }
 
     /* If we're low, start a sweep */
-    if ( order == 9 && page_list_empty(&p2md->pod.super) )
-        p2m_pod_emergency_sweep_super(d);
-
-    if ( page_list_empty(&p2md->pod.single) &&
+    if ( order == 9 && page_list_empty(&p2m->pod.super) )
+        p2m_pod_emergency_sweep_super(p2m);
+
+    if ( page_list_empty(&p2m->pod.single) &&
          ( ( order == 0 )
-           || (order == 9 && page_list_empty(&p2md->pod.super) ) ) )
-        p2m_pod_emergency_sweep(d);
+           || (order == 9 && page_list_empty(&p2m->pod.super) ) ) )
+        p2m_pod_emergency_sweep(p2m);
 
     /* Keep track of the highest gfn demand-populated by a guest fault */
-    if ( q == p2m_guest && gfn > p2md->pod.max_guest )
-        p2md->pod.max_guest = gfn;
+    if ( q == p2m_guest && gfn > p2m->pod.max_guest )
+        p2m->pod.max_guest = gfn;
 
     spin_lock(&d->page_alloc_lock);
 
-    if ( p2md->pod.count == 0 )
+    if ( p2m->pod.count == 0 )
         goto out_of_memory;
 
     /* Get a page f/ the cache.  A NULL return value indicates that the
      * 2-meg range should be marked singleton PoD, and retried */
-    if ( (p = p2m_pod_cache_get(d, order)) == NULL )
+    if ( (p = p2m_pod_cache_get(p2m, order)) == NULL )
         goto remap_and_retry;
 
     mfn = page_to_mfn(p);
@@ -1158,13 +1156,13 @@ p2m_pod_demand_populate(struct domain *d
 
     gfn_aligned = (gfn >> order) << order;
 
-    set_p2m_entry(d, gfn_aligned, mfn, order, p2m_ram_rw);
-
-    for( i = 0 ; i < (1UL << order) ; i++ )
+    set_p2m_entry(p2m, gfn_aligned, mfn, order, p2m_ram_rw);
+
+    for( i = 0; i < (1UL << order); i++ )
         set_gpfn_from_mfn(mfn_x(mfn) + i, gfn_aligned + i);
     
-    p2md->pod.entry_count -= (1 << order); /* Lock: p2m */
-    BUG_ON(p2md->pod.entry_count < 0);
+    p2m->pod.entry_count -= (1 << order); /* Lock: p2m */
+    BUG_ON(p2m->pod.entry_count < 0);
 
     if ( tb_init_done )
     {
@@ -1186,7 +1184,7 @@ out_of_memory:
     spin_unlock(&d->page_alloc_lock);
 
     printk("%s: Out of populate-on-demand memory! tot_pages %" PRIu32 " 
pod_entries %" PRIi32 "\n",
-           __func__, d->tot_pages, p2md->pod.entry_count);
+           __func__, d->tot_pages, p2m->pod.entry_count);
     domain_crash(d);
 out_fail:
     return -1;
@@ -1197,7 +1195,7 @@ remap_and_retry:
     /* Remap this 2-meg region in singleton chunks */
     gfn_aligned = (gfn>>order)<<order;
     for(i=0; i<(1<<order); i++)
-        set_p2m_entry(d, gfn_aligned+i, _mfn(POPULATE_ON_DEMAND_MFN), 0,
+        set_p2m_entry(p2m, gfn_aligned+i, _mfn(POPULATE_ON_DEMAND_MFN), 0,
                       p2m_populate_on_demand);
     if ( tb_init_done )
     {
@@ -1216,44 +1214,44 @@ remap_and_retry:
 }
 
 /* Non-ept "lock-and-check" wrapper */
-static int p2m_pod_check_and_populate(struct domain *d, unsigned long gfn,
+static int p2m_pod_check_and_populate(struct p2m_domain *p2m, unsigned long 
gfn,
                                       l1_pgentry_t *p2m_entry, int order,
                                       p2m_query_t q)
 {
     /* Only take the lock if we don't already have it.  Otherwise it
      * wouldn't be safe to do p2m lookups with the p2m lock held */
-    int do_locking = !p2m_locked_by_me(d->arch.p2m);
+    int do_locking = !p2m_locked_by_me(p2m);
     int r;
 
     if ( do_locking )
-        p2m_lock(d->arch.p2m);
-
-    audit_p2m(d);
+        p2m_lock(p2m);
+
+    audit_p2m(p2m);
 
     /* Check to make sure this is still PoD */
     if ( p2m_flags_to_type(l1e_get_flags(*p2m_entry)) != 
p2m_populate_on_demand )
     {
         if ( do_locking )
-            p2m_unlock(d->arch.p2m);
+            p2m_unlock(p2m);
         return 0;
     }
 
-    r = p2m_pod_demand_populate(d, gfn, order, q);
-
-    audit_p2m(d);
+    r = p2m_pod_demand_populate(p2m, gfn, order, q);
+
+    audit_p2m(p2m);
     if ( do_locking )
-        p2m_unlock(d->arch.p2m);
+        p2m_unlock(p2m);
 
     return r;
 }
 
 // Returns 0 on error (out of memory)
 static int
-p2m_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn, 
+p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
               unsigned int page_order, p2m_type_t p2mt)
 {
     // XXX -- this might be able to be faster iff current->domain == d
-    mfn_t table_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
+    mfn_t table_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m));
     void *table =map_domain_page(mfn_x(table_mfn));
     unsigned long i, gfn_remainder = gfn;
     l1_pgentry_t *p2m_entry;
@@ -1273,14 +1271,14 @@ p2m_set_entry(struct domain *d, unsigned
         t.gfn = gfn;
         t.mfn = mfn_x(mfn);
         t.p2mt = p2mt;
-        t.d = d->domain_id;
+        t.d = p2m->domain->domain_id;
         t.order = page_order;
 
         __trace_var(TRC_MEM_SET_P2M_ENTRY, 0, sizeof(t), (unsigned char *)&t);
     }
 
 #if CONFIG_PAGING_LEVELS >= 4
-    if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+    if ( !p2m_next_level(p2m, &table_mfn, &table, &gfn_remainder, gfn,
                          L4_PAGETABLE_SHIFT - PAGE_SHIFT,
                          L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
         goto out;
@@ -1298,14 +1296,15 @@ p2m_set_entry(struct domain *d, unsigned
              !(l1e_get_flags(*p2m_entry) & _PAGE_PSE) )
         {
             P2M_ERROR("configure P2M table L3 entry with large page\n");
-            domain_crash(d);
+            domain_crash(p2m->domain);
             goto out;
         }
         l3e_content = mfn_valid(mfn) 
             ? l3e_from_pfn(mfn_x(mfn), p2m_type_to_flags(p2mt) | _PAGE_PSE)
             : l3e_empty();
         entry_content.l1 = l3e_content.l3;
-        paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 3);
+        paging_write_p2m_entry(p2m->domain, gfn, p2m_entry,
+                               table_mfn, entry_content, 3);
 
     }
     /*
@@ -1315,17 +1314,17 @@ p2m_set_entry(struct domain *d, unsigned
      * in Xen's address space for translated PV guests.
      * When using AMD's NPT on PAE Xen, we are restricted to 4GB.
      */
-    else if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+    else if ( !p2m_next_level(p2m, &table_mfn, &table, &gfn_remainder, gfn,
                               L3_PAGETABLE_SHIFT - PAGE_SHIFT,
                               ((CONFIG_PAGING_LEVELS == 3)
-                               ? (paging_mode_hap(d) ? 4 : 8)
+                               ? (paging_mode_hap(p2m->domain) ? 4 : 8)
                                : L3_PAGETABLE_ENTRIES),
                               PGT_l2_page_table) )
         goto out;
 
     if ( page_order == 0 )
     {
-        if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+        if ( !p2m_next_level(p2m, &table_mfn, &table, &gfn_remainder, gfn,
                              L2_PAGETABLE_SHIFT - PAGE_SHIFT,
                              L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
             goto out;
@@ -1340,7 +1339,8 @@ p2m_set_entry(struct domain *d, unsigned
             entry_content = l1e_empty();
         
         /* level 1 entry */
-        paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 1);
+        paging_write_p2m_entry(p2m->domain, gfn, p2m_entry,
+                               table_mfn, entry_content, 1);
     }
     else if ( page_order == 9 )
     {
@@ -1354,7 +1354,7 @@ p2m_set_entry(struct domain *d, unsigned
              !(l1e_get_flags(*p2m_entry) & _PAGE_PSE) )
         {
             P2M_ERROR("configure P2M table 4KB L2 entry with large page\n");
-            domain_crash(d);
+            domain_crash(p2m->domain);
             goto out;
         }
         
@@ -1365,23 +1365,24 @@ p2m_set_entry(struct domain *d, unsigned
             l2e_content = l2e_empty();
         
         entry_content.l1 = l2e_content.l2;
-        paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 2);
+        paging_write_p2m_entry(p2m->domain, gfn, p2m_entry,
+                               table_mfn, entry_content, 2);
     }
 
     /* Track the highest gfn for which we have ever had a valid mapping */
     if ( mfn_valid(mfn) 
-         && (gfn + (1UL << page_order) - 1 > d->arch.p2m->max_mapped_pfn) )
-        d->arch.p2m->max_mapped_pfn = gfn + (1UL << page_order) - 1;
-
-    if ( iommu_enabled && need_iommu(d) )
+         && (gfn + (1UL << page_order) - 1 > p2m->max_mapped_pfn) )
+        p2m->max_mapped_pfn = gfn + (1UL << page_order) - 1;
+
+    if ( iommu_enabled && need_iommu(p2m->domain) )
     {
         if ( p2mt == p2m_ram_rw )
             for ( i = 0; i < (1UL << page_order); i++ )
-                iommu_map_page(d, gfn+i, mfn_x(mfn)+i,
+                iommu_map_page(p2m->domain, gfn+i, mfn_x(mfn)+i,
                                IOMMUF_readable|IOMMUF_writable);
         else
             for ( int i = 0; i < (1UL << page_order); i++ )
-                iommu_unmap_page(d, gfn+i);
+                iommu_unmap_page(p2m->domain, gfn+i);
     }
 
     /* Success */
@@ -1393,7 +1394,7 @@ out:
 }
 
 static mfn_t
-p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t,
+p2m_gfn_to_mfn(struct p2m_domain *p2m, unsigned long gfn, p2m_type_t *t,
                p2m_query_t q)
 {
     mfn_t mfn;
@@ -1401,7 +1402,7 @@ p2m_gfn_to_mfn(struct domain *d, unsigne
     l2_pgentry_t *l2e;
     l1_pgentry_t *l1e;
 
-    ASSERT(paging_mode_translate(d));
+    ASSERT(paging_mode_translate(p2m->domain));
 
     /* XXX This is for compatibility with the old model, where anything not 
      * XXX marked as RAM was considered to be emulated MMIO space.
@@ -1409,9 +1410,9 @@ p2m_gfn_to_mfn(struct domain *d, unsigne
      * XXX we will return p2m_invalid for unmapped gfns */
     *t = p2m_mmio_dm;
 
-    mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
-
-    if ( gfn > d->arch.p2m->max_mapped_pfn )
+    mfn = pagetable_get_mfn(p2m_get_pagetable(p2m));
+
+    if ( gfn > p2m->max_mapped_pfn )
         /* This pfn is higher than the highest the p2m map currently holds */
         return _mfn(INVALID_MFN);
 
@@ -1447,7 +1448,7 @@ pod_retry_l3:
             {
                 if ( q != p2m_query )
                 {
-                    if ( !p2m_pod_demand_populate(d, gfn, 18, q) )
+                    if ( !p2m_pod_demand_populate(p2m, gfn, 18, q) )
                         goto pod_retry_l3;
                 }
                 else
@@ -1482,8 +1483,8 @@ pod_retry_l2:
         if ( p2m_flags_to_type(l2e_get_flags(*l2e)) == p2m_populate_on_demand )
         {
             if ( q != p2m_query ) {
-                if ( !p2m_pod_check_and_populate(d, gfn,
-                                                       (l1_pgentry_t *)l2e, 9, 
q) )
+                if ( !p2m_pod_check_and_populate(p2m, gfn,
+                                                 (l1_pgentry_t *)l2e, 9, q) )
                     goto pod_retry_l2;
             } else
                 *t = p2m_populate_on_demand;
@@ -1514,8 +1515,8 @@ pod_retry_l1:
         if ( p2m_flags_to_type(l1e_get_flags(*l1e)) == p2m_populate_on_demand )
         {
             if ( q != p2m_query ) {
-                if ( !p2m_pod_check_and_populate(d, gfn,
-                                                       (l1_pgentry_t *)l1e, 0, 
q) )
+                if ( !p2m_pod_check_and_populate(p2m, gfn,
+                                                 (l1_pgentry_t *)l1e, 0, q) )
                     goto pod_retry_l1;
             } else
                 *t = p2m_populate_on_demand;
@@ -1533,7 +1534,8 @@ pod_retry_l1:
 }
 
 /* Read the current domain's p2m table (through the linear mapping). */
-static mfn_t p2m_gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t,
+static mfn_t p2m_gfn_to_mfn_current(struct p2m_domain *p2m,
+                                    unsigned long gfn, p2m_type_t *t,
                                     p2m_query_t q)
 {
     mfn_t mfn = _mfn(INVALID_MFN);
@@ -1544,7 +1546,7 @@ static mfn_t p2m_gfn_to_mfn_current(unsi
      * XXX Once we start explicitly registering MMIO regions in the p2m 
      * XXX we will return p2m_invalid for unmapped gfns */
 
-    if ( gfn <= current->domain->arch.p2m->max_mapped_pfn )
+    if ( gfn <= p2m->max_mapped_pfn )
     {
         l1_pgentry_t l1e = l1e_empty(), *p2m_entry;
         l2_pgentry_t l2e = l2e_empty();
@@ -1574,7 +1576,7 @@ static mfn_t p2m_gfn_to_mfn_current(unsi
                 /* The read has succeeded, so we know that mapping exists */
                 if ( q != p2m_query )
                 {
-                    if ( !p2m_pod_demand_populate(current->domain, gfn, 18, q) 
)
+                    if ( !p2m_pod_demand_populate(p2m, gfn, 18, q) )
                         goto pod_retry_l3;
                     p2mt = p2m_invalid;
                     printk("%s: Allocate 1GB failed!\n", __func__);
@@ -1624,8 +1626,8 @@ static mfn_t p2m_gfn_to_mfn_current(unsi
                  * exits at this point.  */
                 if ( q != p2m_query )
                 {
-                    if ( !p2m_pod_check_and_populate(current->domain, gfn,
-                                                            p2m_entry, 9, q) )
+                    if ( !p2m_pod_check_and_populate(p2m, gfn,
+                                                     p2m_entry, 9, q) )
                         goto pod_retry_l2;
 
                     /* Allocate failed. */
@@ -1680,8 +1682,8 @@ static mfn_t p2m_gfn_to_mfn_current(unsi
                  * exits at this point.  */
                 if ( q != p2m_query )
                 {
-                    if ( !p2m_pod_check_and_populate(current->domain, gfn,
-                                                            (l1_pgentry_t 
*)p2m_entry, 0, q) )
+                    if ( !p2m_pod_check_and_populate(p2m, gfn,
+                                                     (l1_pgentry_t 
*)p2m_entry, 0, q) )
                         goto pod_retry_l1;
 
                     /* Allocate failed. */
@@ -1708,22 +1710,15 @@ out:
 }
 
 /* Init the datastructures for later use by the p2m code */
-int p2m_init(struct domain *d)
-{
-    struct p2m_domain *p2m;
-
-    p2m = xmalloc(struct p2m_domain);
-    if ( p2m == NULL )
-        return -ENOMEM;
-
-    d->arch.p2m = p2m;
-
+static void p2m_initialise(struct domain *d, struct p2m_domain *p2m)
+{
     memset(p2m, 0, sizeof(*p2m));
     p2m_lock_init(p2m);
     INIT_PAGE_LIST_HEAD(&p2m->pages);
     INIT_PAGE_LIST_HEAD(&p2m->pod.super);
     INIT_PAGE_LIST_HEAD(&p2m->pod.single);
 
+    p2m->domain = d;
     p2m->set_entry = p2m_set_entry;
     p2m->get_entry = p2m_gfn_to_mfn;
     p2m->get_entry_current = p2m_gfn_to_mfn_current;
@@ -1732,23 +1727,34 @@ int p2m_init(struct domain *d)
     if ( hap_enabled(d) && (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) )
         ept_p2m_init(d);
 
+    return;
+}
+
+int p2m_init(struct domain *d)
+{
+    struct p2m_domain *p2m;
+
+    p2m_get_hostp2m(d) = p2m = xmalloc(struct p2m_domain);
+    if ( p2m == NULL )
+        return -ENOMEM;
+    p2m_initialise(d, p2m);
+
     return 0;
 }
 
-void p2m_change_entry_type_global(struct domain *d,
+void p2m_change_entry_type_global(struct p2m_domain *p2m,
                                   p2m_type_t ot, p2m_type_t nt)
 {
-    struct p2m_domain *p2m = d->arch.p2m;
-
     p2m_lock(p2m);
-    p2m->change_entry_type_global(d, ot, nt);
+    p2m->change_entry_type_global(p2m, ot, nt);
     p2m_unlock(p2m);
 }
 
 static
-int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, 
+int set_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
                     unsigned int page_order, p2m_type_t p2mt)
 {
+    struct domain *d = p2m->domain;
     unsigned long todo = 1ul << page_order;
     unsigned int order;
     int rc = 1;
@@ -1763,7 +1769,7 @@ int set_p2m_entry(struct domain *d, unsi
         else
             order = 0;
 
-        if ( !d->arch.p2m->set_entry(d, gfn, mfn, order, p2mt) )
+        if ( !p2m->set_entry(p2m, gfn, mfn, order, p2mt) )
             rc = 0;
         gfn += 1ul << order;
         if ( mfn_x(mfn) != INVALID_MFN )
@@ -1784,16 +1790,14 @@ int set_p2m_entry(struct domain *d, unsi
 //
 // Returns 0 for success or -errno.
 //
-int p2m_alloc_table(struct domain *d,
-                    struct page_info * (*alloc_page)(struct domain *d),
-                    void (*free_page)(struct domain *d, struct page_info *pg))
-
+int p2m_alloc_table(struct p2m_domain *p2m,
+               struct page_info * (*alloc_page)(struct p2m_domain *p2m),
+               void (*free_page)(struct p2m_domain *p2m, struct page_info *pg))
 {
     mfn_t mfn = _mfn(INVALID_MFN);
     struct page_info *page, *p2m_top;
     unsigned int page_count = 0;
     unsigned long gfn = -1UL;
-    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     p2m_lock(p2m);
 
@@ -1809,7 +1813,7 @@ int p2m_alloc_table(struct domain *d,
     p2m->alloc_page = alloc_page;
     p2m->free_page = free_page;
 
-    p2m_top = p2m_alloc_ptp(d,
+    p2m_top = p2m_alloc_ptp(p2m,
 #if CONFIG_PAGING_LEVELS == 4
         PGT_l4_page_table
 #else
@@ -1828,13 +1832,13 @@ int p2m_alloc_table(struct domain *d,
     P2M_PRINTK("populating p2m table\n");
 
     /* Initialise physmap tables for slot zero. Other code assumes this. */
-    if ( !set_p2m_entry(d, 0, _mfn(INVALID_MFN), 0,
+    if ( !set_p2m_entry(p2m, 0, _mfn(INVALID_MFN), 0,
                         p2m_invalid) )
         goto error;
 
     /* Copy all existing mappings from the page list and m2p */
-    spin_lock(&d->page_alloc_lock);
-    page_list_for_each(page, &d->page_list)
+    spin_lock(&p2m->domain->page_alloc_lock);
+    page_list_for_each(page, &p2m->domain->page_list)
     {
         mfn = page_to_mfn(page);
         gfn = get_gpfn_from_mfn(mfn_x(mfn));
@@ -1848,17 +1852,17 @@ int p2m_alloc_table(struct domain *d,
             (gfn != 0x55555555L)
 #endif
              && gfn != INVALID_M2P_ENTRY
-            && !set_p2m_entry(d, gfn, mfn, 0, p2m_ram_rw) )
+            && !set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_rw) )
             goto error_unlock;
     }
-    spin_unlock(&d->page_alloc_lock);
+    spin_unlock(&p2m->domain->page_alloc_lock);
 
     P2M_PRINTK("p2m table initialised (%u pages)\n", page_count);
     p2m_unlock(p2m);
     return 0;
 
 error_unlock:
-    spin_unlock(&d->page_alloc_lock);
+    spin_unlock(&p2m->domain->page_alloc_lock);
  error:
     P2M_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%"
                PRI_mfn "\n", gfn, mfn_x(mfn));
@@ -1866,12 +1870,11 @@ error_unlock:
     return -ENOMEM;
 }
 
-void p2m_teardown(struct domain *d)
+void p2m_teardown(struct p2m_domain *p2m)
 /* Return all the p2m pages to Xen.
  * We know we don't have any extra mappings to these pages */
 {
     struct page_info *pg;
-    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 #ifdef __x86_64__
     unsigned long gfn;
     p2m_type_t t;
@@ -1883,27 +1886,28 @@ void p2m_teardown(struct domain *d)
 #ifdef __x86_64__
     for ( gfn=0; gfn < p2m->max_mapped_pfn; gfn++ )
     {
-        mfn = p2m->get_entry(d, gfn, &t, p2m_query);
+        mfn = p2m->get_entry(p2m, gfn, &t, p2m_query);
         if ( mfn_valid(mfn) && (t == p2m_ram_shared) )
-            BUG_ON(mem_sharing_unshare_page(d, gfn, MEM_SHARING_DESTROY_GFN));
+            BUG_ON(mem_sharing_unshare_page(p2m, gfn, 
MEM_SHARING_DESTROY_GFN));
     }
 #endif
 
     p2m->phys_table = pagetable_null();
 
     while ( (pg = page_list_remove_head(&p2m->pages)) )
-        p2m->free_page(d, pg);
+        p2m->free_page(p2m, pg);
     p2m_unlock(p2m);
 }
 
 void p2m_final_teardown(struct domain *d)
 {
+    /* Iterate over all p2m tables per domain */
     xfree(d->arch.p2m);
     d->arch.p2m = NULL;
 }
 
 #if P2M_AUDIT
-static void audit_p2m(struct domain *d)
+static void audit_p2m(struct p2m_domain *p2m)
 {
     struct page_info *page;
     struct domain *od;
@@ -1913,6 +1917,7 @@ static void audit_p2m(struct domain *d)
     unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0;
     int test_linear;
     p2m_type_t type;
+    struct domain *d = p2m->domain;
 
     if ( !paging_mode_translate(d) )
         return;
@@ -1967,7 +1972,7 @@ static void audit_p2m(struct domain *d)
             continue;
         }
 
-        p2mfn = gfn_to_mfn_type_foreign(d, gfn, &type, p2m_query);
+        p2mfn = gfn_to_mfn_type_p2m(p2m, gfn, &type, p2m_query);
         if ( mfn_x(p2mfn) != mfn )
         {
             mpbad++;
@@ -1983,9 +1988,9 @@ static void audit_p2m(struct domain *d)
             set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
         }
 
-        if ( test_linear && (gfn <= d->arch.p2m->max_mapped_pfn) )
-        {
-            lp2mfn = mfn_x(gfn_to_mfn_query(d, gfn, &type));
+        if ( test_linear && (gfn <= p2m->max_mapped_pfn) )
+        {
+            lp2mfn = mfn_x(gfn_to_mfn_query(p2m, gfn, &type));
             if ( lp2mfn != mfn_x(p2mfn) )
             {
                 P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
@@ -2000,7 +2005,7 @@ static void audit_p2m(struct domain *d)
     spin_unlock(&d->page_alloc_lock);
 
     /* Audit part two: walk the domain's p2m table, checking the entries. */
-    if ( pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d)) != 0 )
+    if ( pagetable_get_pfn(p2m_get_pagetable(p2m)) != 0 )
     {
         l2_pgentry_t *l2e;
         l1_pgentry_t *l1e;
@@ -2009,12 +2014,12 @@ static void audit_p2m(struct domain *d)
 #if CONFIG_PAGING_LEVELS == 4
         l4_pgentry_t *l4e;
         l3_pgentry_t *l3e;
-        int i3, i4;
-        l4e = 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)))));
+        int i4, i3;
+        l4e = 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m))));
 #else /* CONFIG_PAGING_LEVELS == 3 */
         l3_pgentry_t *l3e;
         int i3;
-        l3e = 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)))));
+        l3e = 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m))));
 #endif
 
         gfn = 0;
@@ -2144,11 +2149,11 @@ static void audit_p2m(struct domain *d)
 
     }
 
-    if ( entry_count != d->arch.p2m->pod.entry_count )
+    if ( entry_count != p2m->pod.entry_count )
     {
         printk("%s: refcounted entry count %d, audit count %d!\n",
                __func__,
-               d->arch.p2m->pod.entry_count,
+               p2m->pod.entry_count,
                entry_count);
         BUG();
     }
@@ -2166,18 +2171,18 @@ static void audit_p2m(struct domain *d)
 
 
 static void
-p2m_remove_page(struct domain *d, unsigned long gfn, unsigned long mfn,
+p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn, unsigned long mfn,
                 unsigned int page_order)
 {
     unsigned long i;
     mfn_t mfn_return;
     p2m_type_t t;
 
-    if ( !paging_mode_translate(d) )
-    {
-        if ( need_iommu(d) )
+    if ( !paging_mode_translate(p2m->domain) )
+    {
+        if ( need_iommu(p2m->domain) )
             for ( i = 0; i < (1 << page_order); i++ )
-                iommu_unmap_page(d, mfn + i);
+                iommu_unmap_page(p2m->domain, mfn + i);
         return;
     }
 
@@ -2185,23 +2190,23 @@ p2m_remove_page(struct domain *d, unsign
 
     for ( i = 0; i < (1UL << page_order); i++ )
     {
-        mfn_return = d->arch.p2m->get_entry(d, gfn + i, &t, p2m_query);
+        mfn_return = p2m->get_entry(p2m, gfn + i, &t, p2m_query);
         if ( !p2m_is_grant(t) )
             set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
         ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) );
     }
-    set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid);
+    set_p2m_entry(p2m, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid);
 }
 
 void
-guest_physmap_remove_page(struct domain *d, unsigned long gfn,
+guest_physmap_remove_entry(struct p2m_domain *p2m, unsigned long gfn,
                           unsigned long mfn, unsigned int page_order)
 {
-    p2m_lock(d->arch.p2m);
-    audit_p2m(d);
-    p2m_remove_page(d, gfn, mfn, page_order);
-    audit_p2m(d);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    audit_p2m(p2m);
+    p2m_remove_page(p2m, gfn, mfn, page_order);
+    audit_p2m(p2m);
+    p2m_unlock(p2m);
 }
 
 #if CONFIG_PAGING_LEVELS == 3
@@ -2232,7 +2237,7 @@ guest_physmap_mark_populate_on_demand(st
 guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
                                       unsigned int order)
 {
-    struct p2m_domain *p2md = d->arch.p2m;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     unsigned long i;
     p2m_type_t ot;
     mfn_t omfn;
@@ -2245,15 +2250,15 @@ guest_physmap_mark_populate_on_demand(st
     if ( rc != 0 )
         return rc;
 
-    p2m_lock(p2md);
-    audit_p2m(d);
+    p2m_lock(p2m);
+    audit_p2m(p2m);
 
     P2M_DEBUG("mark pod gfn=%#lx\n", gfn);
 
     /* Make sure all gpfns are unused */
     for ( i = 0; i < (1UL << order); i++ )
     {
-        omfn = gfn_to_mfn_query(d, gfn + i, &ot);
+        omfn = gfn_to_mfn_query(p2m, gfn + i, &ot);
         if ( p2m_is_ram(ot) )
         {
             printk("%s: gfn_to_mfn returned type %d!\n",
@@ -2269,29 +2274,29 @@ guest_physmap_mark_populate_on_demand(st
     }
 
     /* Now, actually do the two-way mapping */
-    if ( !set_p2m_entry(d, gfn, _mfn(POPULATE_ON_DEMAND_MFN), order,
+    if ( !set_p2m_entry(p2m, gfn, _mfn(POPULATE_ON_DEMAND_MFN), order,
                         p2m_populate_on_demand) )
         rc = -EINVAL;
     else
     {
-        p2md->pod.entry_count += 1 << order; /* Lock: p2m */
-        p2md->pod.entry_count -= pod_count;
-        BUG_ON(p2md->pod.entry_count < 0);
-    }
-
-    audit_p2m(d);
-    p2m_unlock(p2md);
+        p2m->pod.entry_count += 1 << order; /* Lock: p2m */
+        p2m->pod.entry_count -= pod_count;
+        BUG_ON(p2m->pod.entry_count < 0);
+    }
+
+    audit_p2m(p2m);
+    p2m_unlock(p2m);
 
 out:
     return rc;
-
 }
 
 int
-guest_physmap_add_entry(struct domain *d, unsigned long gfn,
+guest_physmap_add_entry(struct p2m_domain *p2m, unsigned long gfn,
                         unsigned long mfn, unsigned int page_order, 
                         p2m_type_t t)
 {
+    struct domain *d = p2m->domain;
     unsigned long i, ogfn;
     p2m_type_t ot;
     mfn_t omfn;
@@ -2321,20 +2326,20 @@ guest_physmap_add_entry(struct domain *d
     if ( rc != 0 )
         return rc;
 
-    p2m_lock(d->arch.p2m);
-    audit_p2m(d);
+    p2m_lock(p2m);
+    audit_p2m(p2m);
 
     P2M_DEBUG("adding gfn=%#lx mfn=%#lx\n", gfn, mfn);
 
     /* First, remove m->p mappings for existing p->m mappings */
     for ( i = 0; i < (1UL << page_order); i++ )
     {
-        omfn = gfn_to_mfn_query(d, gfn + i, &ot);
+        omfn = gfn_to_mfn_query(p2m, gfn + i, &ot);
         if ( p2m_is_grant(ot) )
         {
             /* Really shouldn't be unmapping grant maps this way */
             domain_crash(d);
-            p2m_unlock(d->arch.p2m);
+            p2m_unlock(p2m);
             return -EINVAL;
         }
         else if ( p2m_is_ram(ot) )
@@ -2368,7 +2373,7 @@ guest_physmap_add_entry(struct domain *d
              * address */
             P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
                       mfn + i, ogfn, gfn + i);
-            omfn = gfn_to_mfn_query(d, ogfn, &ot);
+            omfn = gfn_to_mfn_query(p2m, ogfn, &ot);
             /* If we get here, we know the local domain owns the page,
                so it can't have been grant mapped in. */
             BUG_ON( p2m_is_grant(ot) );
@@ -2378,7 +2383,7 @@ guest_physmap_add_entry(struct domain *d
                 P2M_DEBUG("old gfn=%#lx -> mfn %#lx\n",
                           ogfn , mfn_x(omfn));
                 if ( mfn_x(omfn) == (mfn + i) )
-                    p2m_remove_page(d, ogfn, mfn + i, 0);
+                    p2m_remove_page(p2m, ogfn, mfn + i, 0);
             }
         }
     }
@@ -2386,7 +2391,7 @@ guest_physmap_add_entry(struct domain *d
     /* Now, actually do the two-way mapping */
     if ( mfn_valid(_mfn(mfn)) ) 
     {
-        if ( !set_p2m_entry(d, gfn, _mfn(mfn), page_order, t) )
+        if ( !set_p2m_entry(p2m, gfn, _mfn(mfn), page_order, t) )
             rc = -EINVAL;
         if ( !p2m_is_grant(t) )
         {
@@ -2398,18 +2403,18 @@ guest_physmap_add_entry(struct domain *d
     {
         gdprintk(XENLOG_WARNING, "Adding bad mfn to p2m map (%#lx -> %#lx)\n",
                  gfn, mfn);
-        if ( !set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, 
+        if ( !set_p2m_entry(p2m, gfn, _mfn(INVALID_MFN), page_order, 
                             p2m_invalid) )
             rc = -EINVAL;
         else
         {
-            d->arch.p2m->pod.entry_count -= pod_count; /* Lock: p2m */
-            BUG_ON(d->arch.p2m->pod.entry_count < 0);
-        }
-    }
-
-    audit_p2m(d);
-    p2m_unlock(d->arch.p2m);
+            p2m->pod.entry_count -= pod_count; /* Lock: p2m */
+            BUG_ON(p2m->pod.entry_count < 0);
+        }
+    }
+
+    audit_p2m(p2m);
+    p2m_unlock(p2m);
 
     return rc;
 }
@@ -2417,7 +2422,7 @@ guest_physmap_add_entry(struct domain *d
 /* Walk the whole p2m table, changing any entries of the old type
  * to the new type.  This is used in hardware-assisted paging to 
  * quickly enable or diable log-dirty tracking */
-void p2m_change_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt)
+void p2m_change_type_global(struct p2m_domain *p2m, p2m_type_t ot, p2m_type_t 
nt)
 {
     unsigned long mfn, gfn, flags;
     l1_pgentry_t l1e_content;
@@ -2430,17 +2435,16 @@ void p2m_change_type_global(struct domai
     l4_pgentry_t *l4e;
     unsigned long i4;
 #endif /* CONFIG_PAGING_LEVELS == 4 */
-    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     BUG_ON(p2m_is_grant(ot) || p2m_is_grant(nt));
 
-    if ( !paging_mode_translate(d) )
+    if ( !paging_mode_translate(p2m->domain) )
         return;
 
     if ( pagetable_get_pfn(p2m_get_pagetable(p2m)) == 0 )
         return;
 
-    ASSERT(p2m_locked_by_me(d->arch.p2m));
+    ASSERT(p2m_locked_by_me(p2m));
 
 #if CONFIG_PAGING_LEVELS == 4
     l4e = map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m))));
@@ -2476,7 +2480,8 @@ void p2m_change_type_global(struct domai
                 gfn = get_gpfn_from_mfn(mfn);
                 flags = p2m_type_to_flags(nt);
                 l1e_content = l1e_from_pfn(mfn, flags | _PAGE_PSE);
-                paging_write_p2m_entry(d, gfn, (l1_pgentry_t *)&l3e[i3],
+                paging_write_p2m_entry(p2m->domain, gfn,
+                                       (l1_pgentry_t *)&l3e[i3],
                                        l3mfn, l1e_content, 3);
                 continue;
             }
@@ -2506,7 +2511,8 @@ void p2m_change_type_global(struct domai
                            * L2_PAGETABLE_ENTRIES) * L1_PAGETABLE_ENTRIES; 
                     flags = p2m_type_to_flags(nt);
                     l1e_content = l1e_from_pfn(mfn, flags | _PAGE_PSE);
-                    paging_write_p2m_entry(d, gfn, (l1_pgentry_t *)&l2e[i2],
+                    paging_write_p2m_entry(p2m->domain, gfn,
+                                           (l1_pgentry_t *)&l2e[i2],
                                            l2mfn, l1e_content, 2);
                     continue;
                 }
@@ -2529,7 +2535,7 @@ void p2m_change_type_global(struct domai
                     /* create a new 1le entry with the new type */
                     flags = p2m_type_to_flags(nt);
                     l1e_content = l1e_from_pfn(mfn, flags);
-                    paging_write_p2m_entry(d, gfn, &l1e[i1],
+                    paging_write_p2m_entry(p2m->domain, gfn, &l1e[i1],
                                            l1mfn, l1e_content, 1);
                 }
                 unmap_domain_page(l1e);
@@ -2551,7 +2557,7 @@ void p2m_change_type_global(struct domai
 
 /* Modify the p2m type of a single gfn from ot to nt, returning the 
  * entry's previous type */
-p2m_type_t p2m_change_type(struct domain *d, unsigned long gfn, 
+p2m_type_t p2m_change_type(struct p2m_domain *p2m, unsigned long gfn, 
                            p2m_type_t ot, p2m_type_t nt)
 {
     p2m_type_t pt;
@@ -2559,31 +2565,31 @@ p2m_type_t p2m_change_type(struct domain
 
     BUG_ON(p2m_is_grant(ot) || p2m_is_grant(nt));
 
-    p2m_lock(d->arch.p2m);
-
-    mfn = gfn_to_mfn_query(d, gfn, &pt);
+    p2m_lock(p2m);
+
+    mfn = gfn_to_mfn_query(p2m, gfn, &pt);
     if ( pt == ot )
-        set_p2m_entry(d, gfn, mfn, 0, nt);
-
-    p2m_unlock(d->arch.p2m);
+        set_p2m_entry(p2m, gfn, mfn, 0, nt);
+
+    p2m_unlock(p2m);
 
     return pt;
 }
 
 int
-set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+set_mmio_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn)
 {
     int rc = 0;
     p2m_type_t ot;
     mfn_t omfn;
 
-    if ( !paging_mode_translate(d) )
+    if ( !paging_mode_translate(p2m->domain) )
         return 0;
 
-    omfn = gfn_to_mfn_query(d, gfn, &ot);
+    omfn = gfn_to_mfn_query(p2m, gfn, &ot);
     if ( p2m_is_grant(ot) )
     {
-        domain_crash(d);
+        domain_crash(p2m->domain);
         return 0;
     }
     else if ( p2m_is_ram(ot) )
@@ -2593,51 +2599,51 @@ set_mmio_p2m_entry(struct domain *d, uns
     }
 
     P2M_DEBUG("set mmio %lx %lx\n", gfn, mfn_x(mfn));
-    p2m_lock(d->arch.p2m);
-    rc = set_p2m_entry(d, gfn, mfn, 0, p2m_mmio_direct);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    rc = set_p2m_entry(p2m, gfn, mfn, 0, p2m_mmio_direct);
+    p2m_unlock(p2m);
     if ( 0 == rc )
         gdprintk(XENLOG_ERR,
             "set_mmio_p2m_entry: set_p2m_entry failed! mfn=%08lx\n",
-            gmfn_to_mfn(d, gfn));
+            mfn_x(gfn_to_mfn(p2m, gfn, &ot)));
     return rc;
 }
 
 int
-clear_mmio_p2m_entry(struct domain *d, unsigned long gfn)
+clear_mmio_p2m_entry(struct p2m_domain *p2m, unsigned long gfn)
 {
     int rc = 0;
-    unsigned long mfn;
-
-    if ( !paging_mode_translate(d) )
+    mfn_t mfn;
+    p2m_type_t t;
+
+    if ( !paging_mode_translate(p2m->domain) )
         return 0;
 
-    mfn = gmfn_to_mfn(d, gfn);
-    if ( INVALID_MFN == mfn )
+    mfn = gfn_to_mfn(p2m, gfn, &t);
+    if ( !mfn_valid(mfn) )
     {
         gdprintk(XENLOG_ERR,
             "clear_mmio_p2m_entry: gfn_to_mfn failed! gfn=%08lx\n", gfn);
         return 0;
     }
-    p2m_lock(d->arch.p2m);
-    rc = set_p2m_entry(d, gfn, _mfn(INVALID_MFN), 0, 0);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    rc = set_p2m_entry(p2m, gfn, _mfn(INVALID_MFN), 0, 0);
+    p2m_unlock(p2m);
 
     return rc;
 }
 
-#ifdef __x86_64__
 int
-set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+set_shared_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn)
 {
     int rc = 0;
     p2m_type_t ot;
     mfn_t omfn;
 
-    if ( !paging_mode_translate(d) )
+    if ( !paging_mode_translate(p2m->domain) )
         return 0;
 
-    omfn = gfn_to_mfn_query(d, gfn, &ot);
+    omfn = gfn_to_mfn_query(p2m, gfn, &ot);
     /* At the moment we only allow p2m change if gfn has already been made
      * sharable first */
     ASSERT(p2m_is_shared(ot));
@@ -2646,22 +2652,23 @@ set_shared_p2m_entry(struct domain *d, u
     set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
 
     P2M_DEBUG("set shared %lx %lx\n", gfn, mfn_x(mfn));
-    rc = set_p2m_entry(d, gfn, mfn, 0, p2m_ram_shared);
+    rc = set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_shared);
     if ( 0 == rc )
         gdprintk(XENLOG_ERR,
             "set_mmio_p2m_entry: set_p2m_entry failed! mfn=%08lx\n",
-            gmfn_to_mfn(d, gfn));
+            gmfn_to_mfn(p2m->domain, gfn));
     return rc;
 }
 
-int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn)
+#ifdef __x86_64__
+int p2m_mem_paging_nominate(struct p2m_domain *p2m, unsigned long gfn)
 {
     struct page_info *page;
     p2m_type_t p2mt;
     mfn_t mfn;
     int ret;
 
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    mfn = gfn_to_mfn(p2m, gfn, &p2mt);
 
     /* Check if mfn is valid */
     ret = -EINVAL;
@@ -2687,9 +2694,9 @@ int p2m_mem_paging_nominate(struct domai
         goto out;
 
     /* Fix p2m entry */
-    p2m_lock(d->arch.p2m);
-    set_p2m_entry(d, gfn, mfn, 0, p2m_ram_paging_out);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    set_p2m_entry(p2m, gfn, mfn, 0, p2m_ram_paging_out);
+    p2m_unlock(p2m);
 
     ret = 0;
 
@@ -2697,14 +2704,15 @@ int p2m_mem_paging_nominate(struct domai
     return ret;
 }
 
-int p2m_mem_paging_evict(struct domain *d, unsigned long gfn)
+int p2m_mem_paging_evict(struct p2m_domain *p2m, unsigned long gfn)
 {
     struct page_info *page;
     p2m_type_t p2mt;
     mfn_t mfn;
+    struct domain *d = p2m->domain;
 
     /* Get mfn */
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    mfn = gfn_to_mfn(p2m, gfn, &p2mt);
     if ( unlikely(!mfn_valid(mfn)) )
         return -EINVAL;
 
@@ -2722,9 +2730,9 @@ int p2m_mem_paging_evict(struct domain *
         put_page(page);
 
     /* Remove mapping from p2m table */
-    p2m_lock(d->arch.p2m);
-    set_p2m_entry(d, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paged);
+    p2m_unlock(p2m);
 
     /* Put the page back so it gets freed */
     put_page(page);
@@ -2732,11 +2740,12 @@ int p2m_mem_paging_evict(struct domain *
     return 0;
 }
 
-void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
+void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn)
 {
     struct vcpu *v = current;
     mem_event_request_t req;
     p2m_type_t p2mt;
+    struct domain *d = p2m->domain;
 
     memset(&req, 0, sizeof(req));
 
@@ -2747,12 +2756,12 @@ void p2m_mem_paging_populate(struct doma
     /* Fix p2m mapping */
     /* XXX: It seems inefficient to have this here, as it's only needed
      *      in one case (ept guest accessing paging out page) */
-    gfn_to_mfn(d, gfn, &p2mt);
+    gfn_to_mfn(p2m, gfn, &p2mt);
     if ( p2mt != p2m_ram_paging_out )
     {
-        p2m_lock(d->arch.p2m);
-        set_p2m_entry(d, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start);
-        p2m_unlock(d->arch.p2m);
+        p2m_lock(p2m);
+        set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start);
+        p2m_unlock(p2m);
     }
 
     /* Pause domain */
@@ -2770,25 +2779,26 @@ void p2m_mem_paging_populate(struct doma
     mem_event_put_request(d, &req);
 }
 
-int p2m_mem_paging_prep(struct domain *d, unsigned long gfn)
+int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn)
 {
     struct page_info *page;
 
     /* Get a free page */
-    page = alloc_domheap_page(d, 0);
+    page = alloc_domheap_page(p2m->domain, 0);
     if ( unlikely(page == NULL) )
         return -EINVAL;
 
     /* Fix p2m mapping */
-    p2m_lock(d->arch.p2m);
-    set_p2m_entry(d, gfn, page_to_mfn(page), 0, p2m_ram_paging_in);
-    p2m_unlock(d->arch.p2m);
+    p2m_lock(p2m);
+    set_p2m_entry(p2m, gfn, page_to_mfn(page), 0, p2m_ram_paging_in);
+    p2m_unlock(p2m);
 
     return 0;
 }
 
-void p2m_mem_paging_resume(struct domain *d)
-{
+void p2m_mem_paging_resume(struct p2m_domain *p2m)
+{
+    struct domain *d = p2m->domain;
     mem_event_response_t rsp;
     p2m_type_t p2mt;
     mfn_t mfn;
@@ -2797,10 +2807,10 @@ void p2m_mem_paging_resume(struct domain
     mem_event_get_response(d, &rsp);
 
     /* Fix p2m entry */
-    mfn = gfn_to_mfn(d, rsp.gfn, &p2mt);
-    p2m_lock(d->arch.p2m);
-    set_p2m_entry(d, rsp.gfn, mfn, 0, p2m_ram_rw);
-    p2m_unlock(d->arch.p2m);
+    mfn = gfn_to_mfn(p2m, rsp.gfn, &p2mt);
+    p2m_lock(p2m);
+    set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw);
+    p2m_unlock(p2m);
 
     /* Unpause domain */
     if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Mon Aug 09 16:46:42 2010 +0100
@@ -1714,8 +1714,9 @@ sh_alloc_p2m_pages(struct domain *d)
 
 // Returns 0 if no memory is available...
 static struct page_info *
-shadow_alloc_p2m_page(struct domain *d)
-{
+shadow_alloc_p2m_page(struct p2m_domain *p2m)
+{
+    struct domain *d = p2m->domain;
     struct page_info *pg;
     mfn_t mfn;
     void *p;
@@ -1741,8 +1742,9 @@ shadow_alloc_p2m_page(struct domain *d)
 }
 
 static void
-shadow_free_p2m_page(struct domain *d, struct page_info *pg)
-{
+shadow_free_p2m_page(struct p2m_domain *p2m, struct page_info *pg)
+{
+    struct domain *d = p2m->domain;
     ASSERT(page_get_owner(pg) == d);
     /* Should have just the one ref we gave it in alloc_p2m_page() */
     if ( (pg->count_info & PGC_count_mask) != 1 )
@@ -3100,6 +3102,7 @@ int shadow_enable(struct domain *d, u32 
     struct page_info *pg = NULL;
     uint32_t *e;
     int i, rv = 0;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     mode |= PG_SH_enable;
 
@@ -3135,7 +3138,8 @@ int shadow_enable(struct domain *d, u32 
      * to avoid possible deadlock. */
     if ( mode & PG_translate )
     {
-        rv = p2m_alloc_table(d, shadow_alloc_p2m_page, shadow_free_p2m_page);
+        rv = p2m_alloc_table(p2m,
+            shadow_alloc_p2m_page, shadow_free_p2m_page);
         if (rv != 0)
             goto out_unlocked;
     }
@@ -3146,7 +3150,7 @@ int shadow_enable(struct domain *d, u32 
     {
         /* Get a single page from the shadow pool.  Take it via the 
          * P2M interface to make freeing it simpler afterwards. */
-        pg = shadow_alloc_p2m_page(d);
+        pg = shadow_alloc_p2m_page(p2m);
         if ( pg == NULL )
         {
             rv = -ENOMEM;
@@ -3195,10 +3199,10 @@ int shadow_enable(struct domain *d, u32 
  out_locked:
     shadow_unlock(d);
  out_unlocked:
-    if ( rv != 0 && !pagetable_is_null(p2m_get_pagetable(p2m_get_hostp2m(d))) )
-        p2m_teardown(d);
+    if ( rv != 0 && !pagetable_is_null(p2m_get_pagetable(p2m)) )
+        p2m_teardown(p2m);
     if ( rv != 0 && pg != NULL )
-        shadow_free_p2m_page(d, pg);
+        shadow_free_p2m_page(p2m, pg);
     domain_unpause(d);
     return rv;
 }
@@ -3210,6 +3214,7 @@ void shadow_teardown(struct domain *d)
     struct vcpu *v;
     mfn_t mfn;
     struct page_info *pg;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     ASSERT(d->is_dying);
     ASSERT(d != current->domain);
@@ -3264,7 +3269,7 @@ void shadow_teardown(struct domain *d)
 #endif /* (SHADOW_OPTIMIZATIONS & (SHOPT_VIRTUAL_TLB|SHOPT_OUT_OF_SYNC)) */
 
     while ( (pg = page_list_remove_head(&d->arch.paging.shadow.p2m_freelist)) )
-        shadow_free_p2m_page(d, pg);
+        shadow_free_p2m_page(p2m, pg);
 
     if ( d->arch.paging.shadow.total_pages != 0 )
     {
@@ -3298,7 +3303,7 @@ void shadow_teardown(struct domain *d)
             if ( !hvm_paging_enabled(v) )
                 v->arch.guest_table = pagetable_null();
         }
-        shadow_free_p2m_page(d, 
+        shadow_free_p2m_page(p2m, 
             pagetable_get_page(d->arch.paging.shadow.unpaged_pagetable));
         d->arch.paging.shadow.unpaged_pagetable = pagetable_null();
     }
@@ -3335,7 +3340,7 @@ void shadow_final_teardown(struct domain
         shadow_teardown(d);
 
     /* It is now safe to pull down the p2m map. */
-    p2m_teardown(d);
+    p2m_teardown(p2m_get_hostp2m(d));
 
     SHADOW_PRINTK("dom %u final teardown done."
                    "  Shadow pages total = %u, free = %u, p2m=%u\n",
@@ -3657,10 +3662,11 @@ int shadow_track_dirty_vram(struct domai
     unsigned long i;
     p2m_type_t t;
     struct sh_dirty_vram *dirty_vram = d->arch.hvm_domain.dirty_vram;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     if (end_pfn < begin_pfn
-            || begin_pfn > d->arch.p2m->max_mapped_pfn
-            || end_pfn >= d->arch.p2m->max_mapped_pfn)
+            || begin_pfn > p2m->max_mapped_pfn
+            || end_pfn >= p2m->max_mapped_pfn)
         return -EINVAL;
 
     shadow_lock(d);
@@ -3729,7 +3735,7 @@ int shadow_track_dirty_vram(struct domai
 
         /* Iterate over VRAM to track dirty bits. */
         for ( i = 0; i < nr; i++ ) {
-            mfn_t mfn = gfn_to_mfn(d, begin_pfn + i, &t);
+            mfn_t mfn = gfn_to_mfn(p2m, begin_pfn + i, &t);
             struct page_info *page;
             int dirty = 0;
             paddr_t sl1ma = dirty_vram->sl1ma[i];
@@ -3814,7 +3820,7 @@ int shadow_track_dirty_vram(struct domai
                 /* was clean for more than two seconds, try to disable guest
                  * write access */
                 for ( i = begin_pfn; i < end_pfn; i++ ) {
-                    mfn_t mfn = gfn_to_mfn(d, i, &t);
+                    mfn_t mfn = gfn_to_mfn(p2m, i, &t);
                     if (mfn_x(mfn) != INVALID_MFN)
                         flush_tlb |= sh_remove_write_access(d->vcpu[0], mfn, 
1, 0);
                 }
diff -r 9e58c46ee63b -r e7afe98afd43 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Mon Aug 09 16:46:42 2010 +0100
@@ -167,7 +167,7 @@ sh_walk_guest_tables(struct vcpu *v, uns
 sh_walk_guest_tables(struct vcpu *v, unsigned long va, walk_t *gw, 
                      uint32_t pfec)
 {
-    return guest_walk_tables(v, va, gw, pfec, 
+    return guest_walk_tables(v, p2m_get_hostp2m(v->domain), va, gw, pfec, 
 #if GUEST_PAGING_LEVELS == 3 /* PAE */
                              _mfn(INVALID_MFN),
                              v->arch.paging.shadow.gl3e
@@ -2240,6 +2240,7 @@ static int validate_gl4e(struct vcpu *v,
     shadow_l4e_t *sl4p = se;
     mfn_t sl3mfn = _mfn(INVALID_MFN);
     struct domain *d = v->domain;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     p2m_type_t p2mt;
     int result = 0;
 
@@ -2248,7 +2249,7 @@ static int validate_gl4e(struct vcpu *v,
     if ( guest_l4e_get_flags(new_gl4e) & _PAGE_PRESENT )
     {
         gfn_t gl3gfn = guest_l4e_get_gfn(new_gl4e);
-        mfn_t gl3mfn = gfn_to_mfn_query(d, gl3gfn, &p2mt);
+        mfn_t gl3mfn = gfn_to_mfn_query(p2m, gl3gfn, &p2mt);
         if ( p2m_is_ram(p2mt) )
             sl3mfn = get_shadow_status(v, gl3mfn, SH_type_l3_shadow);
         else if ( p2mt != p2m_populate_on_demand )
@@ -2299,13 +2300,14 @@ static int validate_gl3e(struct vcpu *v,
     mfn_t sl2mfn = _mfn(INVALID_MFN);
     p2m_type_t p2mt;
     int result = 0;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
 
     perfc_incr(shadow_validate_gl3e_calls);
 
     if ( guest_l3e_get_flags(new_gl3e) & _PAGE_PRESENT )
     {
         gfn_t gl2gfn = guest_l3e_get_gfn(new_gl3e);
-        mfn_t gl2mfn = gfn_to_mfn_query(v->domain, gl2gfn, &p2mt);
+        mfn_t gl2mfn = gfn_to_mfn_query(p2m, gl2gfn, &p2mt);
         if ( p2m_is_ram(p2mt) )
             sl2mfn = get_shadow_status(v, gl2mfn, SH_type_l2_shadow);
         else if ( p2mt != p2m_populate_on_demand )
@@ -2329,6 +2331,7 @@ static int validate_gl2e(struct vcpu *v,
     guest_l2e_t new_gl2e = *(guest_l2e_t *)new_ge;
     shadow_l2e_t *sl2p = se;
     mfn_t sl1mfn = _mfn(INVALID_MFN);
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
     p2m_type_t p2mt;
     int result = 0;
 
@@ -2354,7 +2357,7 @@ static int validate_gl2e(struct vcpu *v,
         }
         else
         {
-            mfn_t gl1mfn = gfn_to_mfn_query(v->domain, gl1gfn, &p2mt);
+            mfn_t gl1mfn = gfn_to_mfn_query(p2m, gl1gfn, &p2mt);
             if ( p2m_is_ram(p2mt) )
                 sl1mfn = get_shadow_status(v, gl1mfn, SH_type_l1_shadow); 
             else if ( p2mt != p2m_populate_on_demand )
@@ -2415,6 +2418,7 @@ static int validate_gl1e(struct vcpu *v,
     shadow_l1e_t *sl1p = se;
     gfn_t gfn;
     mfn_t gmfn;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
     p2m_type_t p2mt;
     int result = 0;
 #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
@@ -2424,7 +2428,7 @@ static int validate_gl1e(struct vcpu *v,
     perfc_incr(shadow_validate_gl1e_calls);
 
     gfn = guest_l1e_get_gfn(new_gl1e);
-    gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt);
+    gmfn = gfn_to_mfn_query(p2m, gfn, &p2mt);
 
     l1e_propagate_from_guest(v, new_gl1e, gmfn, &new_sl1e, ft_prefetch, p2mt);
     result |= shadow_set_l1e(v, sl1p, new_sl1e, p2mt, sl1mfn);
@@ -2484,7 +2488,7 @@ void sh_resync_l1(struct vcpu *v, mfn_t 
             shadow_l1e_t nsl1e;
 
             gfn = guest_l1e_get_gfn(gl1e);
-            gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt);
+            gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), gfn, &p2mt);
             l1e_propagate_from_guest(v, gl1e, gmfn, &nsl1e, ft_prefetch, p2mt);
             rc |= shadow_set_l1e(v, sl1p, nsl1e, p2mt, sl1mfn);
 
@@ -2810,7 +2814,7 @@ static void sh_prefetch(struct vcpu *v, 
 
         /* Look at the gfn that the l1e is pointing at */
         gfn = guest_l1e_get_gfn(gl1e);
-        gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt);
+        gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), gfn, &p2mt);
 
         /* Propagate the entry.  */
         l1e_propagate_from_guest(v, gl1e, gmfn, &sl1e, ft_prefetch, p2mt);
@@ -3166,7 +3170,7 @@ static int sh_page_fault(struct vcpu *v,
 
     /* What mfn is the guest trying to access? */
     gfn = guest_l1e_get_gfn(gw.l1e);
-    gmfn = gfn_to_mfn_guest(d, gfn, &p2mt);
+    gmfn = gfn_to_mfn_guest(p2m_get_hostp2m(d), gfn, &p2mt);
 
     if ( shadow_mode_refcounts(d) && 
          ((!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt)) ||
@@ -4272,7 +4276,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
             if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT )
             {
                 gl2gfn = guest_l3e_get_gfn(gl3e[i]);
-                gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt);
+                gl2mfn = gfn_to_mfn_query(p2m_get_hostp2m(d), gl2gfn, &p2mt);
                 if ( p2m_is_ram(p2mt) )
                     flush |= sh_remove_write_access(v, gl2mfn, 2, 0);
             }
@@ -4285,7 +4289,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
             if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT )
             {
                 gl2gfn = guest_l3e_get_gfn(gl3e[i]);
-                gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt);
+                gl2mfn = gfn_to_mfn_query(p2m_get_hostp2m(d), gl2gfn, &p2mt);
                 if ( p2m_is_ram(p2mt) )
                     sh_set_toplevel_shadow(v, i, gl2mfn, (i == 3) 
                                            ? SH_type_l2h_shadow 
@@ -4682,7 +4686,7 @@ static void sh_pagetable_dying(struct vc
     if ( gcr3 == gpa )
         fast_path = 1;
 
-    gmfn = gfn_to_mfn_query(v->domain, _gfn(gpa >> PAGE_SHIFT), &p2mt);
+    gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), _gfn(gpa >> 
PAGE_SHIFT), &p2mt);
     if ( !mfn_valid(gmfn) || !p2m_is_ram(p2mt) )
     {
         printk(XENLOG_DEBUG "sh_pagetable_dying: gpa not valid %"PRIpaddr"\n",
@@ -4702,7 +4706,7 @@ static void sh_pagetable_dying(struct vc
         {
             /* retrieving the l2s */
             gl2a = guest_l3e_get_paddr(gl3e[i]);
-            gmfn = gfn_to_mfn_query(v->domain, _gfn(gl2a >> PAGE_SHIFT), 
&p2mt);
+            gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), _gfn(gl2a >> 
PAGE_SHIFT), &p2mt);
             smfn = shadow_hash_lookup(v, mfn_x(gmfn), SH_type_l2_pae_shadow);
         }
 
@@ -4737,7 +4741,7 @@ static void sh_pagetable_dying(struct vc
 
     shadow_lock(v->domain);
 
-    gmfn = gfn_to_mfn_query(v->domain, _gfn(gpa >> PAGE_SHIFT), &p2mt);
+    gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), _gfn(gpa >> 
PAGE_SHIFT), &p2mt);
 #if GUEST_PAGING_LEVELS == 2
     smfn = shadow_hash_lookup(v, mfn_x(gmfn), SH_type_l2_32_shadow);
 #else
@@ -4777,6 +4781,7 @@ static mfn_t emulate_gva_to_mfn(struct v
     mfn_t mfn;
     p2m_type_t p2mt;
     uint32_t pfec = PFEC_page_present | PFEC_write_access;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
 
     /* Translate the VA to a GFN */
     gfn = sh_gva_to_gfn(v, vaddr, &pfec);
@@ -4792,9 +4797,9 @@ static mfn_t emulate_gva_to_mfn(struct v
     /* Translate the GFN to an MFN */
     /* PoD: query only if shadow lock is held (to avoid deadlock) */
     if ( shadow_locked_by_me(v->domain) )
-        mfn = gfn_to_mfn_query(v->domain, _gfn(gfn), &p2mt);
+        mfn = gfn_to_mfn_query(p2m, _gfn(gfn), &p2mt);
     else
-        mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt);
+        mfn = gfn_to_mfn(p2m, _gfn(gfn), &p2mt);
         
     if ( p2m_is_readonly(p2mt) )
         return _mfn(READONLY_GFN);
@@ -5199,7 +5204,7 @@ int sh_audit_l1_table(struct vcpu *v, mf
             {
                 gfn = guest_l1e_get_gfn(*gl1e);
                 mfn = shadow_l1e_get_mfn(*sl1e);
-                gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt);
+                gmfn = gfn_to_mfn_query(p2m_get_hostp2m(v->domain), gfn, 
&p2mt);
                 if ( !p2m_is_grant(p2mt) && mfn_x(gmfn) != mfn_x(mfn) )
                     AUDIT_FAIL(1, "bad translation: gfn %" SH_PRI_gfn
                                " --> %" PRI_mfn " != mfn %" PRI_mfn,
@@ -5243,6 +5248,7 @@ int sh_audit_l2_table(struct vcpu *v, mf
     shadow_l2e_t *sl2e;
     mfn_t mfn, gmfn, gl2mfn;
     gfn_t gfn;
+    struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
     p2m_type_t p2mt;
     char *s;
     int done = 0;
@@ -5269,7 +5275,7 @@ int sh_audit_l2_table(struct vcpu *v, mf
             mfn = shadow_l2e_get_mfn(*sl2e);
             gmfn = (guest_l2e_get_flags(*gl2e) & _PAGE_PSE)  
                 ? get_fl1_shadow_status(v, gfn)
-                : get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, 
&p2mt), 
+                : get_shadow_status(v, gfn_to_mfn_query(p2m, gfn, &p2mt), 
                                     SH_type_l1_shadow);
             if ( mfn_x(gmfn) != mfn_x(mfn) )
                 AUDIT_FAIL(2, "bad translation: gfn %" SH_PRI_gfn
@@ -5277,8 +5283,8 @@ int sh_audit_l2_table(struct vcpu *v, mf
                            " --> %" PRI_mfn " != mfn %" PRI_mfn,
                            gfn_x(gfn), 
                            (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? 0
-                           : mfn_x(gfn_to_mfn_query(v->domain, gfn, &p2mt)),
-                           mfn_x(gmfn), mfn_x(mfn));
+                           : mfn_x(gfn_to_mfn_query(p2m,
+                                   gfn, &p2mt)), mfn_x(gmfn), mfn_x(mfn));
         }
     });
     sh_unmap_domain_page(gp);
@@ -5316,7 +5322,7 @@ int sh_audit_l3_table(struct vcpu *v, mf
         {
             gfn = guest_l3e_get_gfn(*gl3e);
             mfn = shadow_l3e_get_mfn(*sl3e);
-            gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, 
&p2mt), 
+            gmfn = get_shadow_status(v, 
gfn_to_mfn_query(p2m_get_hostp2m(v->domain), gfn, &p2mt), 
                                      ((GUEST_PAGING_LEVELS == 3 ||
                                        is_pv_32on64_vcpu(v))
                                       && !shadow_mode_external(v->domain)
@@ -5363,7 +5369,8 @@ int sh_audit_l4_table(struct vcpu *v, mf
         {
             gfn = guest_l4e_get_gfn(*gl4e);
             mfn = shadow_l4e_get_mfn(*sl4e);
-            gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, 
&p2mt), 
+            gmfn = get_shadow_status(v, 
gfn_to_mfn_query(p2m_get_hostp2m(v->domain),
+                                     gfn, &p2mt), 
                                      SH_type_l3_shadow);
             if ( mfn_x(gmfn) != mfn_x(mfn) )
                 AUDIT_FAIL(4, "bad translation: gfn %" SH_PRI_gfn
diff -r 9e58c46ee63b -r e7afe98afd43 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/common/grant_table.c  Mon Aug 09 16:46:42 2010 +0100
@@ -109,7 +109,7 @@ static unsigned inline int max_nr_maptra
 #define gfn_to_mfn_private(_d, _gfn) ({                     \
     p2m_type_t __p2mt;                                      \
     unsigned long __x;                                      \
-    __x = mfn_x(gfn_to_mfn_unshare(_d, _gfn, &__p2mt, 1));  \
+    __x = mfn_x(gfn_to_mfn_unshare(p2m_get_hostp2m(_d), _gfn, &__p2mt, 1));  \
     if ( !p2m_is_valid(__p2mt) )                            \
         __x = INVALID_MFN;                                  \
     __x; })
@@ -1933,12 +1933,13 @@ __gnttab_copy(
     {
 #ifdef CONFIG_X86
         p2m_type_t p2mt;
-        s_frame = mfn_x(gfn_to_mfn(sd, op->source.u.gmfn, &p2mt));
+        struct p2m_domain *p2m = p2m_get_hostp2m(sd);
+        s_frame = mfn_x(gfn_to_mfn(p2m, op->source.u.gmfn, &p2mt));
         if ( !p2m_is_valid(p2mt) )
           s_frame = INVALID_MFN;
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(sd, op->source.u.gmfn);
+            p2m_mem_paging_populate(p2m, op->source.u.gmfn);
             rc = -ENOENT;
             goto error_out;
         }
@@ -1979,12 +1980,13 @@ __gnttab_copy(
     {
 #ifdef CONFIG_X86
         p2m_type_t p2mt;
-        d_frame = mfn_x(gfn_to_mfn_unshare(dd, op->dest.u.gmfn, &p2mt, 1));
+        struct p2m_domain *p2m = p2m_get_hostp2m(dd);
+        d_frame = mfn_x(gfn_to_mfn_unshare(p2m, op->dest.u.gmfn, &p2mt, 1));
         if ( !p2m_is_valid(p2mt) )
           d_frame = INVALID_MFN;
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(dd, op->dest.u.gmfn);
+            p2m_mem_paging_populate(p2m, op->dest.u.gmfn);
             rc = -ENOENT;
             goto error_out;
         }
diff -r 9e58c46ee63b -r e7afe98afd43 xen/common/memory.c
--- a/xen/common/memory.c       Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/common/memory.c       Mon Aug 09 16:46:42 2010 +0100
@@ -161,7 +161,7 @@ int guest_remove_page(struct domain *d, 
     unsigned long mfn;
 
 #ifdef CONFIG_X86
-    mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt)); 
+    mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(d), gmfn, &p2mt)); 
 #else
     mfn = gmfn_to_mfn(d, gmfn);
 #endif
@@ -356,7 +356,7 @@ static long memory_exchange(XEN_GUEST_HA
                 p2m_type_t p2mt;
 
                 /* Shared pages cannot be exchanged */
-                mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
+                mfn = mfn_x(gfn_to_mfn_unshare(p2m_get_hostp2m(d), gmfn + k, 
&p2mt, 0));
                 if ( p2m_is_shared(p2mt) )
                 {
                     rc = -ENOMEM;
diff -r 9e58c46ee63b -r e7afe98afd43 xen/common/tmem_xen.c
--- a/xen/common/tmem_xen.c     Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/common/tmem_xen.c     Mon Aug 09 16:46:42 2010 +0100
@@ -100,7 +100,7 @@ static inline void *cli_mfn_to_va(tmem_c
     unsigned long cli_mfn;
     p2m_type_t t;
 
-    cli_mfn = mfn_x(gfn_to_mfn(current->domain, cmfn, &t));
+    cli_mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(current->domain), cmfn, &t));
     if (t != p2m_ram_rw || cli_mfn == INVALID_MFN)
         return NULL;
     if (pcli_mfn != NULL)
diff -r 9e58c46ee63b -r e7afe98afd43 xen/include/asm-x86/guest_pt.h
--- a/xen/include/asm-x86/guest_pt.h    Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/include/asm-x86/guest_pt.h    Mon Aug 09 16:46:42 2010 +0100
@@ -272,8 +272,8 @@ guest_walk_to_gpa(walk_t *gw)
 #define guest_walk_tables GPT_RENAME(guest_walk_tables, GUEST_PAGING_LEVELS)
 
 extern uint32_t 
-guest_walk_tables(struct vcpu *v, unsigned long va, walk_t *gw, 
-                  uint32_t pfec, mfn_t top_mfn, void *top_map);
+guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m, unsigned long va,
+                  walk_t *gw, uint32_t pfec, mfn_t top_mfn, void *top_map);
 
 /* Pretty-print the contents of a guest-walk */
 static inline void print_gw(walk_t *gw)
diff -r 9e58c46ee63b -r e7afe98afd43 xen/include/asm-x86/mem_sharing.h
--- a/xen/include/asm-x86/mem_sharing.h Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/include/asm-x86/mem_sharing.h Mon Aug 09 16:46:42 2010 +0100
@@ -30,17 +30,17 @@ typedef uint64_t shr_handle_t;
 typedef uint64_t shr_handle_t; 
 
 unsigned int mem_sharing_get_nr_saved_mfns(void);
-int mem_sharing_nominate_page(struct domain *d, 
+int mem_sharing_nominate_page(struct p2m_domain *p2m, 
                               unsigned long gfn,
                               int expected_refcnt,
                               shr_handle_t *phandle);
 #define MEM_SHARING_MUST_SUCCEED      (1<<0)
 #define MEM_SHARING_DESTROY_GFN       (1<<1)
-int mem_sharing_unshare_page(struct domain *d, 
+int mem_sharing_unshare_page(struct p2m_domain *p2m, 
                              unsigned long gfn, 
                              uint16_t flags);
 int mem_sharing_sharing_resume(struct domain *d);
-int mem_sharing_cache_resize(struct domain *d, int new_size);
+int mem_sharing_cache_resize(struct p2m_domain *p2m, int new_size);
 int mem_sharing_domctl(struct domain *d, 
                        xen_domctl_mem_sharing_op_t *mec);
 void mem_sharing_init(void);
diff -r 9e58c46ee63b -r e7afe98afd43 xen/include/asm-x86/p2m.h
--- a/xen/include/asm-x86/p2m.h Mon Aug 09 16:40:18 2010 +0100
+++ b/xen/include/asm-x86/p2m.h Mon Aug 09 16:46:42 2010 +0100
@@ -172,23 +172,28 @@ struct p2m_domain {
     /* Shadow translated domain: p2m mapping */
     pagetable_t        phys_table;
 
+    struct domain     *domain;   /* back pointer to domain */
+
     /* Pages used to construct the p2m */
     struct page_list_head pages;
 
     /* Functions to call to get or free pages for the p2m */
-    struct page_info * (*alloc_page  )(struct domain *d);
-    void               (*free_page   )(struct domain *d,
+    struct page_info * (*alloc_page  )(struct p2m_domain *p2m);
+    void               (*free_page   )(struct p2m_domain *p2m,
                                        struct page_info *pg);
-    int                (*set_entry   )(struct domain *d, unsigned long gfn,
+    int                (*set_entry   )(struct p2m_domain *p2m,
+                                       unsigned long gfn,
                                        mfn_t mfn, unsigned int page_order,
                                        p2m_type_t p2mt);
-    mfn_t              (*get_entry   )(struct domain *d, unsigned long gfn,
+    mfn_t              (*get_entry   )(struct p2m_domain *p2m,
+                                       unsigned long gfn,
                                        p2m_type_t *p2mt,
                                        p2m_query_t q);
-    mfn_t              (*get_entry_current)(unsigned long gfn,
+    mfn_t              (*get_entry_current)(struct p2m_domain *p2m,
+                                            unsigned long gfn,
                                             p2m_type_t *p2mt,
                                             p2m_query_t q);
-    void               (*change_entry_type_global)(struct domain *d,
+    void               (*change_entry_type_global)(struct p2m_domain *p2m,
                                                    p2m_type_t ot,
                                                    p2m_type_t nt);
 
@@ -279,65 +284,64 @@ static inline p2m_type_t p2m_flags_to_ty
 }
 
 /* Read the current domain's p2m table.  Do not populate PoD pages. */
-static inline mfn_t gfn_to_mfn_type_current(unsigned long gfn, p2m_type_t *t,
+static inline mfn_t gfn_to_mfn_type_current(struct p2m_domain *p2m,
+                                            unsigned long gfn, p2m_type_t *t,
                                             p2m_query_t q)
 {
-    return current->domain->arch.p2m->get_entry_current(gfn, t, q);
-}
-
-/* Read another domain's P2M table, mapping pages as we go.
+    return p2m->get_entry_current(p2m, gfn, t, q);
+}
+
+/* Read P2M table, mapping pages as we go.
  * Do not populate PoD pages. */
-static inline
-mfn_t gfn_to_mfn_type_foreign(struct domain *d, unsigned long gfn, p2m_type_t 
*t,
-                              p2m_query_t q)
-{
-    return d->arch.p2m->get_entry(d, gfn, t, q);
-}
+static inline mfn_t
+gfn_to_mfn_type_p2m(struct p2m_domain *p2m, unsigned long gfn,
+                              p2m_type_t *t, p2m_query_t q)
+{
+    return p2m->get_entry(p2m, gfn, t, q);
+}
+
 
 /* General conversion function from gfn to mfn */
-static inline mfn_t _gfn_to_mfn_type(struct domain *d,
+static inline mfn_t _gfn_to_mfn_type(struct p2m_domain *p2m,
                                      unsigned long gfn, p2m_type_t *t,
                                      p2m_query_t q)
 {
-    if ( !paging_mode_translate(d) )
+    if ( !p2m || !paging_mode_translate(p2m->domain) )
     {
         /* Not necessarily true, but for non-translated guests, we claim
          * it's the most generic kind of memory */
         *t = p2m_ram_rw;
         return _mfn(gfn);
     }
-    if ( likely(current->domain == d) )
-        return gfn_to_mfn_type_current(gfn, t, q);
+    if ( likely(current->domain == p2m->domain) )
+        return gfn_to_mfn_type_current(p2m, gfn, t, q);
     else
-        return gfn_to_mfn_type_foreign(d, gfn, t, q);
-}
-
-#define gfn_to_mfn(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_alloc)
-#define gfn_to_mfn_query(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_query)
-#define gfn_to_mfn_guest(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_guest)
-
-#define gfn_to_mfn_current(g, t) gfn_to_mfn_type_current((g), (t), p2m_alloc)
-#define gfn_to_mfn_foreign(d, g, t) gfn_to_mfn_type_foreign((d), (g), (t), 
p2m_alloc)
-
-static inline mfn_t gfn_to_mfn_unshare(struct domain *d,
+        return gfn_to_mfn_type_p2m(p2m, gfn, t, q);
+}
+
+#define gfn_to_mfn(p2m, g, t) _gfn_to_mfn_type((p2m), (g), (t), p2m_alloc)
+#define gfn_to_mfn_query(p2m, g, t) _gfn_to_mfn_type((p2m), (g), (t), 
p2m_query)
+#define gfn_to_mfn_guest(p2m, g, t) _gfn_to_mfn_type((p2m), (g), (t), 
p2m_guest)
+
+static inline mfn_t gfn_to_mfn_unshare(struct p2m_domain *p2m,
                                        unsigned long gfn,
                                        p2m_type_t *p2mt,
                                        int must_succeed)
 {
     mfn_t mfn;
 
-    mfn = gfn_to_mfn(d, gfn, p2mt);
+    mfn = gfn_to_mfn(p2m, gfn, p2mt);
 #ifdef __x86_64__
     if ( p2m_is_shared(*p2mt) )
     {
-        if ( mem_sharing_unshare_page(d, gfn,
+        if ( mem_sharing_unshare_page(p2m, gfn,
                                       must_succeed 
                                       ? MEM_SHARING_MUST_SUCCEED : 0) )
         {
             BUG_ON(must_succeed);
             return mfn;
         }
-        mfn = gfn_to_mfn(d, gfn, p2mt);
+        mfn = gfn_to_mfn(p2m, gfn, p2mt);
     }
 #endif
 
@@ -350,7 +354,7 @@ static inline unsigned long gmfn_to_mfn(
 {
     mfn_t mfn;
     p2m_type_t t;
-    mfn = gfn_to_mfn(d, gpfn, &t);
+    mfn = gfn_to_mfn(d->arch.p2m, gpfn, &t);
     if ( p2m_is_valid(t) )
         return mfn_x(mfn);
     return INVALID_MFN;
@@ -374,16 +378,16 @@ int p2m_init(struct domain *d);
  * build the p2m, and to release it again at the end of day. 
  *
  * Returns 0 for success or -errno. */
-int p2m_alloc_table(struct domain *d,
-                    struct page_info * (*alloc_page)(struct domain *d),
-                    void (*free_page)(struct domain *d, struct page_info *pg));
+int p2m_alloc_table(struct p2m_domain *p2m,
+               struct page_info * (*alloc_page)(struct p2m_domain *p2m),
+               void (*free_page)(struct p2m_domain *p2m, struct page_info 
*pg));
 
 /* Return all the p2m resources to Xen. */
-void p2m_teardown(struct domain *d);
+void p2m_teardown(struct p2m_domain *p2m);
 void p2m_final_teardown(struct domain *d);
 
 /* Dump PoD information about the domain */
-void p2m_pod_dump_data(struct domain *d);
+void p2m_pod_dump_data(struct p2m_domain *p2m);
 
 /* Move all pages from the populate-on-demand cache to the domain page_list
  * (usually in preparation for domain destruction) */
@@ -402,14 +406,18 @@ p2m_pod_decrease_reservation(struct doma
 
 /* Called by p2m code when demand-populating a PoD page */
 int
-p2m_pod_demand_populate(struct domain *d, unsigned long gfn,
+p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn,
                         unsigned int order,
                         p2m_query_t q);
 
 /* Add a page to a domain's p2m table */
-int guest_physmap_add_entry(struct domain *d, unsigned long gfn,
+int guest_physmap_add_entry(struct p2m_domain *p2m, unsigned long gfn,
                             unsigned long mfn, unsigned int page_order, 
                             p2m_type_t t);
+
+/* Remove a page from a domain's p2m table */
+void guest_physmap_remove_entry(struct p2m_domain *p2m, unsigned long gfn,
+                            unsigned long mfn, unsigned int page_order);
 
 /* Set a p2m range as populate-on-demand */
 int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
@@ -419,49 +427,55 @@ int guest_physmap_mark_populate_on_deman
  *
  * Return 0 for success
  */
-static inline int guest_physmap_add_page(struct domain *d, unsigned long gfn,
+static inline int guest_physmap_add_page(struct domain *d,
+                                         unsigned long gfn,
                                          unsigned long mfn,
                                          unsigned int page_order)
 {
-    return guest_physmap_add_entry(d, gfn, mfn, page_order, p2m_ram_rw);
+    return guest_physmap_add_entry(d->arch.p2m, gfn, mfn, page_order, 
p2m_ram_rw);
 }
 
 /* Remove a page from a domain's p2m table */
-void guest_physmap_remove_page(struct domain *d, unsigned long gfn,
-                               unsigned long mfn, unsigned int page_order);
+static inline void guest_physmap_remove_page(struct domain *d,
+                               unsigned long gfn,
+                               unsigned long mfn, unsigned int page_order)
+{
+    guest_physmap_remove_entry(d->arch.p2m, gfn, mfn, page_order);
+}
 
 /* Change types across all p2m entries in a domain */
-void p2m_change_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt);
-void p2m_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t 
nt);
+void p2m_change_type_global(struct p2m_domain *p2m, p2m_type_t ot, p2m_type_t 
nt);
+void p2m_change_entry_type_global(struct p2m_domain *p2m, p2m_type_t ot, 
p2m_type_t nt);
 
 /* Compare-exchange the type of a single p2m entry */
-p2m_type_t p2m_change_type(struct domain *d, unsigned long gfn,
+p2m_type_t p2m_change_type(struct p2m_domain *p2m, unsigned long gfn,
                            p2m_type_t ot, p2m_type_t nt);
 
 /* Set mmio addresses in the p2m table (for pass-through) */
-int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn);
+int set_mmio_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn);
+int clear_mmio_p2m_entry(struct p2m_domain *p2m, unsigned long gfn);
 
 
 #ifdef __x86_64__
 /* Modify p2m table for shared gfn */
-int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
+int set_shared_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn);
+
 /* Check if a nominated gfn is valid to be paged out */
-int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn);
+int p2m_mem_paging_nominate(struct p2m_domain *p2m, unsigned long gfn);
 /* Evict a frame */
-int p2m_mem_paging_evict(struct domain *d, unsigned long gfn);
+int p2m_mem_paging_evict(struct p2m_domain *p2m, unsigned long gfn);
 /* Start populating a paged out frame */
-void p2m_mem_paging_populate(struct domain *d, unsigned long gfn);
+void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn);
 /* Prepare the p2m for paging a frame in */
-int p2m_mem_paging_prep(struct domain *d, unsigned long gfn);
+int p2m_mem_paging_prep(struct p2m_domain *p2m, unsigned long gfn);
 /* Resume normal operation (in case a domain was paused) */
-void p2m_mem_paging_resume(struct domain *d);
+void p2m_mem_paging_resume(struct p2m_domain *p2m);
 #else
-static inline void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
+static inline void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned 
long gfn)
 { }
 #endif
 
-struct page_info *p2m_alloc_ptp(struct domain *d, unsigned long type);
+struct page_info *p2m_alloc_ptp(struct p2m_domain *p2m, unsigned long type);
 
 #endif /* _XEN_P2M_H */
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Nested Virtualization: p2m infrastructure, Xen patchbot-unstable <=