Skip to contentSkip to conversation

Nested Virtualization: p2m infrastructure

PATCH In review Christoph Egger 2 participants 2 messages Apr 15, 2010 – Apr 16, 2010

lore
Share & tools
lore
#0 lore raw

PATCH 17/18 Nested Virtualization: p2m infrastructure

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Karl-Hammerschmidt-Str. 34, 85609 Dornach b. Muenchen
Geschaeftsfuehrer: Andrew Bowd, Thomas M. McCoy, Giuliano Meroni
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

# HG changeset patch
# User cegger
# Date 1271330314 -7200
Change p2m infrastructure to operate on per-p2m instead of per-domain. This allows us to use multiple p2m tables per-domain.

xen/arch/x86/domain.c +1 -1
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/domain.c
@@ -160,7 +160,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));
     }
 
     page_list_for_each ( page, &d->xenpage_list )
xen/arch/x86/domctl.c +2 -2
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/domctl.c
@@ -992,7 +992,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
         {
@@ -1001,7 +1001,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);
         }
 
xen/arch/x86/hvm/emulate.c +6 -5
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/hvm/emulate.c
@@ -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(curr->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,7 +639,7 @@ static int hvmemul_rep_movs(
     unsigned long saddr, daddr, bytes;
     paddr_t sgpa, dgpa;
     uint32_t pfec = PFEC_page_present;
-    struct domain *d = current->domain;
+    struct p2m_domain *p2m = p2m_get_hostp2m(current->domain);
     p2m_type_t p2mt;
     int rc, df = !!(ctxt->regs->eflags & X86_EFLAGS_DF);
     char *buf;
@@ -669,12 +670,12 @@ static int hvmemul_rep_movs(
     if ( rc != X86EMUL_OKAY )
         return rc;
 
-    (void)gfn_to_mfn(d, 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(d, 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);
xen/arch/x86/hvm/hvm.c +30 -20

175 lines not on this page · raw message

xen/arch/x86/hvm/mtrr.c +1 -1
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/hvm/mtrr.c
@@ -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 "
xen/arch/x86/hvm/stdvga.c +3 -4
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/hvm/stdvga.c
@@ -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,8 +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->domain,
-                        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.
@@ -504,8 +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->domain,
-                        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;
xen/arch/x86/hvm/svm/svm.c +7 -5
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/hvm/svm/svm.c
@@ -228,7 +228,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",
@@ -1536,7 +1536,9 @@ static void svm_do_nested_pgfault(paddr_
     unsigned long gfn = gpa >> PAGE_SHIFT;
     mfn_t mfn;
     p2m_type_t p2mt;
-    struct domain *d = current->domain;
+    struct p2m_domain *p2m;
+
+    p2m = p2m_get_hostp2m(current->domain);
 
     if ( tb_init_done )
     {
@@ -1549,7 +1551,7 @@ static void svm_do_nested_pgfault(paddr_
 
         _d.gpa = gpa;
         _d.qualification = 0;
-        _d.mfn = mfn_x(gfn_to_mfn_query(d, 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);
     }
@@ -1558,10 +1560,10 @@ static void svm_do_nested_pgfault(paddr_
         return;
 
     /* Everything else is an error. */
-    mfn = gfn_to_mfn_guest(d, gfn, &p2mt);
+    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(d);
+    domain_crash(current->domain);
 }
 
 static void svm_fpu_dirty_intercept(void)
xen/arch/x86/hvm/vmx/vmx.c +11 -7
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/hvm/vmx/vmx.c
@@ -491,7 +491,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);
@@ -1007,7 +1008,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;
 
@@ -1226,7 +1228,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
@@ -1345,7 +1347,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);
 }
 
@@ -1915,7 +1917,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;
@@ -2123,6 +2126,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 )
     {
@@ -2135,7 +2139,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);
     }
@@ -2145,7 +2149,7 @@ static void ept_handle_violation(unsigne
         return;
 
     /* Everything else is an error. */
-    mfn = gfn_to_mfn_guest(current->domain, gfn, &p2mt);
+    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, 
xen/arch/x86/mm.c +32 -25

170 lines not on this page · raw message

xen/arch/x86/mm/guest_walk.c +7 -6
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/guest_walk.c
@@ -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;
@@ -123,6 +123,7 @@ guest_walk_tables(struct vcpu *v, unsign
                   uint32_t pfec, mfn_t top_mfn, void *top_map)
 {
     struct domain *d = v->domain;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
     p2m_type_t p2mt;
     guest_l1e_t *l1p = NULL;
     guest_l2e_t *l2p = NULL;
@@ -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,
xen/arch/x86/mm/hap/guest_walk.c +5 -5
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/hap/guest_walk.c
@@ -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;
@@ -78,10 +79,10 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
     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:
  */
-
xen/arch/x86/mm/hap/hap.c +22 -15
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/hap/hap.c
@@ -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() */
@@ -580,10 +585,11 @@ int hap_enable(struct domain *d, u32 mod
         }
     }
 
-    /* allocate P2m table */
+    /* 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;
     }
@@ -600,7 +606,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);
 }
 
@@ -700,9 +706,11 @@ void hap_vcpu_init(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;
 }
 
@@ -822,6 +830,7 @@ static unsigned long hap_gva_to_gfn_real
     return ((paddr_t)gva >> PAGE_SHIFT);
 }
 
+
 /* Entry points into this mode of the hap code. */
 static const struct paging_mode hap_paging_real_mode = {
     .page_fault             = hap_page_fault,
@@ -871,5 +880,3 @@ static const struct paging_mode hap_pagi
  * indent-tabs-mode: nil
  * End:
  */
-
-
xen/arch/x86/mm/hap/p2m-ept.c +60 -55

369 lines not on this page · raw message

xen/arch/x86/mm/mem_event.c +2 -2
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/mem_event.c
@@ -240,7 +240,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))) )
@@ -249,7 +249,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))) )
xen/arch/x86/mm/mem_paging.c +5 -4
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/mem_paging.c
@@ -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;
xen/arch/x86/mm/mem_sharing.c +17 -12
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/mem_sharing.c
@@ -254,6 +254,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;
 
@@ -265,7 +266,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",
@@ -380,7 +382,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, ", 
@@ -490,7 +492,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)
@@ -502,10 +504,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;
@@ -539,7 +542,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.
@@ -602,7 +605,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);
@@ -621,7 +624,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)
 {
@@ -634,8 +637,9 @@ int mem_sharing_unshare_page(struct doma
     struct gfn_info *gfn_info = NULL;
     shr_handle_t handle;
     struct list_head *le;
+    struct domain *d = p2m->domain;
 
-    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    mfn = gfn_to_mfn(p2m, gfn, &p2mt);
 
     page = mfn_to_page(mfn);
     handle = page->shr_handle;
@@ -699,7 +703,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:    
@@ -711,7 +715,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");
@@ -743,7 +747,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();
         }
@@ -759,7 +763,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();
         }
xen/arch/x86/mm/p2m.c +419 -389

1,719 lines not on this page · raw message

xen/arch/x86/mm/shadow/common.c +20 -14
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/arch/x86/mm/shadow/common.c

Lines of this file are not shown. View the raw message.

xen/arch/x86/mm/shadow/multi.c +24 -17

41 lines not on this page · raw message

xen/common/grant_table.c +9 -7
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/common/grant_table.c

Lines of this file are not shown. View the raw message.

xen/common/memory.c +2 -2
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/common/memory.c

Lines of this file are not shown. View the raw message.

xen/common/tmem_xen.c +1 -1
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/common/tmem_xen.c

Lines of this file are not shown. View the raw message.

xen/include/asm-x86/mem_sharing.h +4 -4
diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/include/asm-x86/mem_sharing.h

Lines of this file are not shown. View the raw message.

xen/include/asm-x86/p2m.h +61 -49

110 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

Part of the diff is not shown here. View the raw message.

#1 lore raw

This was mostly OK, with a few oddities (below), and assuming that we can agree that later patches make it necessary.

If you resubmit, please send it as two patches, one of which does _only_ the change from passing struct domains to passing p2m structs and nothing else - no comment changes, no format tidying, nothing. I don't want to have to comb through another 4000 line patch looking for hidden surprises.

xen/arch/x86/mm/p2m.c out: · line 1393

Quoted 5 lines
xen/arch/x86/mm/p2m.c +1 -0
@@ -1391,8 +1390,9 @@ out:
     return rv;
 }
 
+/* Read p2m table (through the linear mapping). */

That's exactly wrong. The gfn_to_mfn_current() function that you removed was the one that used the linear mapping. This one maps and unmaps pages as it goes.

xen/arch/x86/mm/p2m.c out: · line 1397

Quoted 5 lines
xen/arch/x86/mm/p2m.c +1 -1
 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;

...

xen/arch/x86/mm/p2m.c pod_retry_l1: · line 1534

Quoted 7 lines
xen/arch/x86/mm/p2m.c +1 -2
@@ -1531,8 +1531,7 @@ pod_retry_l1:
     return (p2m_is_valid(*t) || p2m_is_grant(*t)) ? mfn : _mfn(INVALID_MFN);
 }
 
-/* Init the datastructures for later use by the p2m code */
-int p2m_init(struct domain *d)
+static int p2m_allocp2m(struct p2m_domain **_p2m)

Since the only error this routine can return is -ENOMEM, why not just return the p2m pointer or NULL?

Quoted 8 lines
xen/arch/x86/mm/p2m.c +0 -1
 {
     struct p2m_domain *p2m;
 
@@ -1540,39 +1539,68 @@ int p2m_init(struct domain *d)
     if ( p2m == NULL )
         return -ENOMEM;
 
-    d->arch.p2m = p2m;

xen/arch/x86/mm/p2m.c int p2m_init(struct domain *d) · line 1550

Quoted 10 lines
xen/arch/x86/mm/p2m.c +9 -1
-
+    *_p2m = p2m;
+    return 0;
+}
+
+/* Init the datastructures for later use by the p2m code */
+static void p2m_initialise(struct domain *d, struct p2m_domain *p2m,
+                          bool_t preserve_allocfree)
+{
+    void *alloc, *free;

These are function pointers; there's no need to hack them into void pointers.

Quoted 26 lines
xen/arch/x86/mm/p2m.c +12 -0
+    alloc = free = NULL;
+    if (preserve_allocfree) {
+        alloc = p2m->alloc_page;
+        free = p2m->free_page;
+    }
     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->change_entry_type_global = p2m_change_type_global;
+    if (preserve_allocfree) {
+        p2m->alloc_page = alloc;
+        p2m->free_page = free;
+    }
 
     if ( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled &&
          (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) )
         ept_p2m_init(d);
 
+    return;
+}

...

Quoted 3 lines

void p2m_final_teardown(struct domain *d)
{
+ /* Iterate over all p2m tables per domain */

Even when the matching code arrives this comment's not really helpful.

Quoted 41 lines
     xfree(d->arch.p2m);
     d->arch.p2m = NULL;

}

#if P2M_AUDIT

xen/arch/x86/mm/p2m.c +5 -4
-static void audit_p2m(struct domain *d)
+static void audit_p2m(struct p2m_domain *p2m)
 {
     struct page_info *page;
     struct domain *od;
@@ -1735,6 +1761,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;
@@ -1789,7 +1816,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++;
@@ -1805,9 +1832,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) )
+        if ( test_linear && (gfn <= p2m->max_mapped_pfn) )
         {
-            lp2mfn = mfn_x(gfn_to_mfn_query(d, gfn, &type));
+            lp2mfn = mfn_x(gfn_to_mfn_query(p2m, gfn, &type));
             if ( lp2mfn != mfn_x(p2mfn) )
             {
                 P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
@@ -1822,21 +1849,19 @@ static void audit_p2m(struct domain *d)
     spin_unlock(&d->page_alloc_lock);

xen/arch/x86/mm/p2m.c static void audit_p2m(struct domain *d) · line 1857

Quoted 10 lines
xen/arch/x86/mm/p2m.c +3 -2
 
     /* 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 )
     {
+        l3_pgentry_t *l3e;
         l2_pgentry_t *l2e;
         l1_pgentry_t *l1e;
-        int i1, i2;
+        int i1, i2, i3;

Why are you moving these definitions around? You don't change the use of the variables anywhere.

xen/arch/x86/mm/p2m.c static void audit_p2m(struct domain *d) · line 1838

Quoted 10 lines
xen/arch/x86/mm/p2m.c +2 -5
 #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;
+        l4e = map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m))));
 #else /* CONFIG_PAGING_LEVELS == 3 */
-        l3_pgentry_t *l3e;
-        int i3;

Ditto.

Quoted 5 lines
xen/arch/x86/mm/p2m.c +1 -1
-        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;

...

Quoted 13 lines

diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/common/grant_table.c

xen/common/grant_table.c +1 -1
@@ -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; })

xen/common/grant_table.c gnttab_unpopulate_status_frames(struct d · line 1062

Quoted 5 lines
xen/common/grant_table.c +1 -1
@@ -1059,7 +1059,7 @@ gnttab_unpopulate_status_frames(struct d
 
     for ( i = 0; i < nr_status_frames(gt); i++ )
     {
-        page_set_owner(virt_to_page(gt->status[i]), dom_xen);
+        page_set_owner(virt_to_page(gt->status[i]), p2m_get_hostp2m(dom_xen));

That seems very unlikely to be correct. Did you get carried away?

xen/common/grant_table.c gnttab_transfer( · line 1501

Quoted 9 lines
xen/common/grant_table.c +1 -1
         free_xenheap_page(gt->status[i]);
         gt->status[i] = NULL;
     }
@@ -1498,7 +1498,7 @@ gnttab_transfer(
         if ( unlikely(e->tot_pages++ == 0) )
             get_knownalive_domain(e);
         page_list_add_tail(page, &e->page_list);
-        page_set_owner(page, e);
+        page_set_owner(page, p2m_get_hostp2m(e));

Likewise.

Quoted 3 lines
xen/common/grant_table.c +0 -0
         spin_unlock(&e->page_alloc_lock);
 

...

xen/include/asm-x86/mem_sharing.h line 27

Quoted 10 lines

diff -r f96f6f2cd19a -r 3f48b73b0a30 xen/include/asm-x86/mem_sharing.h

xen/include/asm-x86/mem_sharing.h +1 -1
@@ -23,22 +23,22 @@
 #define __MEM_SHARING_H__
 
 #define sharing_supported(_d) \
-    (is_hvm_domain(_d) && (_d)->arch.hvm_domain.hap_enabled) 
+    (is_hvm_domain(_d) && paging_mode_hap(_d)) 
 

Okay, but it really doesn't belong in this patch.

Cheers,

Tim.

Signature · 3 lines
Tim Deegan <[email protected]>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd.  (Company #02937203, SL9 0BG)