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-devel

[Xen-devel] [PATCH 2/3] x86_64: don't allocate L1 per-domain page table

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2/3] x86_64: don't allocate L1 per-domain page table pages in a single chunk
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Wed, 10 Jun 2009 15:39:03 +0100
Delivery-date: Wed, 10 Jun 2009 07:38:14 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Instead, allocate them on demand, and adjust the consumer to no longer
assume the allocated space is contiguous.

This another prerequisite to extend to number of vCPU-s the hypervisor
can support per guest.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- 2009-06-10.orig/xen/arch/x86/domain.c       2009-05-27 13:54:05.000000000 
+0200
+++ 2009-06-10/xen/arch/x86/domain.c    2009-06-10 10:48:19.000000000 +0200
@@ -322,6 +322,22 @@ int vcpu_initialise(struct vcpu *v)
 
 #if defined(__i386__)
     mapcache_vcpu_init(v);
+#else
+    {
+        unsigned int idx = perdomain_pt_pgidx(v);
+        struct page_info *pg;
+
+        if ( !perdomain_pt_page(d, idx) )
+        {
+            pg = alloc_domheap_page(NULL, MEMF_node(vcpu_to_node(v)));
+            if ( !pg )
+                return -ENOMEM;
+            clear_page(page_to_virt(pg));
+            perdomain_pt_page(d, idx) = pg;
+            d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+idx]
+                = l2e_from_page(pg, __PAGE_HYPERVISOR);
+        }
+    }
 #endif
 
     pae_l3_cache_init(&v->arch.pae_l3_cache);
@@ -357,8 +373,7 @@ int vcpu_initialise(struct vcpu *v)
             real_cr4_to_pv_guest_cr4(mmu_cr4_features);
     }
 
-    v->arch.perdomain_ptes =
-        d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT);
+    v->arch.perdomain_ptes = perdomain_ptes(d, v);
 
     spin_lock_init(&v->arch.shadow_ldt_lock);
 
@@ -378,8 +393,10 @@ int arch_domain_create(struct domain *d,
 {
 #ifdef __x86_64__
     struct page_info *pg;
+#else
+    int pdpt_order;
 #endif
-    int i, pdpt_order, paging_initialised = 0;
+    int i, paging_initialised = 0;
     int rc = -ENOMEM;
 
     d->arch.hvm_domain.hap_enabled =
@@ -394,27 +411,30 @@ int arch_domain_create(struct domain *d,
     d->arch.relmem = RELMEM_not_started;
     INIT_PAGE_LIST_HEAD(&d->arch.relmem_list);
 
+#if defined(__i386__)
+
     pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
     d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order, 0);
     if ( d->arch.mm_perdomain_pt == NULL )
         goto fail;
     memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
 
-#if defined(__i386__)
-
     mapcache_domain_init(d);
 
 #else /* __x86_64__ */
 
+    d->arch.mm_perdomain_pt_pages = xmalloc_array(struct page_info *,
+                                                  PDPT_L2_ENTRIES);
+    if ( !d->arch.mm_perdomain_pt_pages )
+        goto fail;
+    memset(d->arch.mm_perdomain_pt_pages, 0,
+           PDPT_L2_ENTRIES * sizeof(*d->arch.mm_perdomain_pt_pages));
+
     pg = alloc_domheap_page(NULL, MEMF_node(domain_to_node(d)));
     if ( pg == NULL )
         goto fail;
     d->arch.mm_perdomain_l2 = page_to_virt(pg);
     clear_page(d->arch.mm_perdomain_l2);
-    for ( i = 0; i < (1 << pdpt_order); i++ )
-        d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+i] =
-            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt)+i,
-                          __PAGE_HYPERVISOR);
 
     pg = alloc_domheap_page(NULL, MEMF_node(domain_to_node(d)));
     if ( pg == NULL )
@@ -503,13 +523,19 @@ int arch_domain_create(struct domain *d,
         free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
     if ( d->arch.mm_perdomain_l3 )
         free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
-#endif
+    xfree(d->arch.mm_perdomain_pt_pages);
+#else
     free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order);
+#endif
     return rc;
 }
 
 void arch_domain_destroy(struct domain *d)
 {
+#ifdef __x86_64__
+    unsigned int i;
+#endif
+
     if ( is_hvm_domain(d) )
         hvm_domain_destroy(d);
 
@@ -520,11 +546,17 @@ void arch_domain_destroy(struct domain *
 
     paging_final_teardown(d);
 
+#ifdef __i386__
     free_xenheap_pages(
         d->arch.mm_perdomain_pt,
         get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
-
-#ifdef __x86_64__
+#else
+    for ( i = 0; i < PDPT_L2_ENTRIES; ++i )
+    {
+        if ( perdomain_pt_page(d, i) )
+            free_domheap_page(perdomain_pt_page(d, i));
+    }
+    xfree(d->arch.mm_perdomain_pt_pages);
     free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
     free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
 #endif
@@ -1272,8 +1304,7 @@ static void __context_switch(void)
         struct page_info *page = virt_to_page(gdt);
         unsigned int i;
         for ( i = 0; i < NR_RESERVED_GDT_PAGES; i++ )
-            l1e_write(n->domain->arch.mm_perdomain_pt +
-                      (n->vcpu_id << GDT_LDT_VCPU_SHIFT) +
+            l1e_write(n->arch.perdomain_ptes +
                       FIRST_RESERVED_GDT_PAGE + i,
                       l1e_from_page(page + i, __PAGE_HYPERVISOR));
     }
--- 2009-06-10.orig/xen/arch/x86/domain_build.c 2009-05-27 13:54:05.000000000 
+0200
+++ 2009-06-10/xen/arch/x86/domain_build.c      2009-06-10 10:46:31.000000000 
+0200
@@ -480,8 +480,7 @@ int __init construct_dom0(
 
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
         l2tab[l2_linear_offset(PERDOMAIN_VIRT_START) + i] =
-            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
-                          __PAGE_HYPERVISOR);
+            l2e_from_page(perdomain_pt_page(d, i), __PAGE_HYPERVISOR);
 
     l2tab += l2_linear_offset(v_start);
     mfn = alloc_spfn;
--- 2009-06-10.orig/xen/arch/x86/mm.c   2009-06-10 10:46:17.000000000 +0200
+++ 2009-06-10/xen/arch/x86/mm.c        2009-06-10 10:46:31.000000000 +0200
@@ -1207,9 +1207,7 @@ static int create_pae_xen_mappings(struc
            L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t));
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
     {
-        l2e = l2e_from_page(
-            virt_to_page(d->arch.mm_perdomain_pt) + i,
-            __PAGE_HYPERVISOR);
+        l2e = l2e_from_page(perdomain_pt_page(d, i), __PAGE_HYPERVISOR);
         l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i], l2e);
     }
     for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
--- 2009-06-10.orig/xen/arch/x86/mm/hap/hap.c   2009-06-08 08:44:53.000000000 
+0200
+++ 2009-06-10/xen/arch/x86/mm/hap/hap.c        2009-06-10 10:46:31.000000000 
+0200
@@ -437,7 +437,7 @@ static void hap_install_xen_entries_in_l
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
         l2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
             l2e_from_pfn(
-                mfn_x(page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i)),
+                mfn_x(page_to_mfn(perdomain_pt_page(d, i))),
                 __PAGE_HYPERVISOR);
 
     /* No linear mapping; will be set up by monitor-table contructor. */
--- 2009-06-10.orig/xen/arch/x86/mm/shadow/multi.c      2009-06-08 
08:44:53.000000000 +0200
+++ 2009-06-10/xen/arch/x86/mm/shadow/multi.c   2009-06-10 10:46:31.000000000 
+0200
@@ -1470,7 +1470,7 @@ static void sh_install_xen_entries_in_l2
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
         sl2e[shadow_l2_table_offset(PERDOMAIN_VIRT_START) + i] =
             shadow_l2e_from_mfn(
-                page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i),
+                page_to_mfn(perdomain_pt_page(d, i)),
                 __PAGE_HYPERVISOR);
     
     /* We don't set up a linear mapping here because we can't until this
--- 2009-06-10.orig/xen/include/asm-x86/domain.h        2009-05-27 
13:54:07.000000000 +0200
+++ 2009-06-10/xen/include/asm-x86/domain.h     2009-06-10 10:46:31.000000000 
+0200
@@ -231,10 +231,12 @@ struct domain_mca_msrs
 
 struct arch_domain
 {
-    l1_pgentry_t *mm_perdomain_pt;
 #ifdef CONFIG_X86_64
+    struct page_info **mm_perdomain_pt_pages;
     l2_pgentry_t *mm_perdomain_l2;
     l3_pgentry_t *mm_perdomain_l3;
+#else
+    l1_pgentry_t *mm_perdomain_pt;
 #endif
 
 #ifdef CONFIG_X86_32
@@ -302,6 +304,21 @@ struct arch_domain
 
 #define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
 
+#ifdef CONFIG_X86_64
+#define perdomain_pt_pgidx(v) \
+      ((v)->vcpu_id >> (PAGETABLE_ORDER - GDT_LDT_VCPU_SHIFT))
+#define perdomain_ptes(d, v) \
+    ((l1_pgentry_t *)page_to_virt((d)->arch.mm_perdomain_pt_pages \
+      [perdomain_pt_pgidx(v)]) + (((v)->vcpu_id << GDT_LDT_VCPU_SHIFT) & \
+                                  (L1_PAGETABLE_ENTRIES - 1)))
+#define perdomain_pt_page(d, n) ((d)->arch.mm_perdomain_pt_pages[n])
+#else
+#define perdomain_ptes(d, v) \
+    ((d)->arch.mm_perdomain_pt + ((v)->vcpu_id << GDT_LDT_VCPU_SHIFT))
+#define perdomain_pt_page(d, n) \
+    (virt_to_page((d)->arch.mm_perdomain_pt) + (n))
+#endif
+
 
 #ifdef __i386__
 struct pae_l3_cache {



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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 2/3] x86_64: don't allocate L1 per-domain page table pages in a single chunk, Jan Beulich <=