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] x86_64: don't allocate L1 per-domain page

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86_64: don't allocate L1 per-domain page table pages in a single chunk
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 19 Jun 2009 00:56:27 -0700
Delivery-date: Fri, 19 Jun 2009 01:07:49 -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 1245315923 -3600
# Node ID cecc76506afc76e6f34b994d06abd35c753baf64
# Parent  d835ad2f6980240c4437273e4e2d46bc820c4009
x86_64: don't allocate L1 per-domain page table pages in a single chunk

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>
---
 xen/arch/x86/domain.c          |   61 ++++++++++++++++++++++++++++++-----------
 xen/arch/x86/domain_build.c    |    3 --
 xen/arch/x86/mm.c              |    4 --
 xen/arch/x86/mm/hap/hap.c      |    2 -
 xen/arch/x86/mm/shadow/multi.c |    2 -
 xen/include/asm-x86/domain.h   |   19 ++++++++++++
 6 files changed, 68 insertions(+), 23 deletions(-)

diff -r d835ad2f6980 -r cecc76506afc xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/arch/x86/domain.c     Thu Jun 18 10:05:23 2009 +0100
@@ -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;
-#endif
-    int i, pdpt_order, paging_initialised = 0;
+#else
+    int pdpt_order;
+#endif
+    int i, paging_initialised = 0;
     int rc = -ENOMEM;
 
     d->arch.hvm_domain.hap_enabled =
@@ -393,6 +410,8 @@ 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);
@@ -400,21 +419,22 @@ int arch_domain_create(struct domain *d,
         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));
     }
diff -r d835ad2f6980 -r cecc76506afc xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/arch/x86/domain_build.c       Thu Jun 18 10:05:23 2009 +0100
@@ -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;
diff -r d835ad2f6980 -r cecc76506afc xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/arch/x86/mm.c Thu Jun 18 10:05:23 2009 +0100
@@ -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++ )
diff -r d835ad2f6980 -r cecc76506afc xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/arch/x86/mm/hap/hap.c Thu Jun 18 10:05:23 2009 +0100
@@ -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. */
diff -r d835ad2f6980 -r cecc76506afc xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Thu Jun 18 10:05:23 2009 +0100
@@ -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
diff -r d835ad2f6980 -r cecc76506afc xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Thu Jun 18 10:04:57 2009 +0100
+++ b/xen/include/asm-x86/domain.h      Thu Jun 18 10:05:23 2009 +0100
@@ -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
@@ -301,6 +303,21 @@ struct arch_domain
 } __cacheline_aligned;
 
 #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__

_______________________________________________
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] x86_64: don't allocate L1 per-domain page table pages in a single chunk, Xen patchbot-unstable <=